diff --git a/.github/scripts/extract_matrix.py b/.github/scripts/extract_matrix.py
index 7347eaae72..00c9683c12 100644
--- a/.github/scripts/extract_matrix.py
+++ b/.github/scripts/extract_matrix.py
@@ -68,6 +68,12 @@
"cpython-gate",
"darwin",
+
+ # python-graalos-resources downloads the GraalOS runtime from an Oracle-internal
+ # location (GRAALPY_GRAALOS_ARTIFACT_BASE_URL, an overlay import that is empty in the
+ # public ci.jsonnet) and python-resource-variants consumes that artifact. Both fail
+ # the same way in upstream's own GitHub Actions runs.
+ "graalos",
)
DOWNLOADS_LINKS = {
@@ -75,19 +81,27 @@
"ECLIPSE": "https://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops4/R-4.26-202211231800/eclipse-SDK-4.26-linux-gtk-x86_64.tar.gz"
}
-# Github Runners OSS
+# Runner labels by required capabilities. Elide's fork builds and tests on its
+# self-hosted runner pool, not on GitHub-hosted runners.
+LINUX_AMD64_RUNNER = "linux-amd64-cipool"
+LINUX_AARCH64_RUNNER = "linux-arm64-cipool"
+WINDOWS_AMD64_RUNNER = "windows-amd64-cipool"
OSS = {
- "ubuntu-latest": ["linux", "amd64"],
- "ubuntu-24.04-arm": ["linux", "aarch64"],
- "windows-latest": ["windows", "amd64"]
+ LINUX_AMD64_RUNNER: ["linux", "amd64"],
+ LINUX_AARCH64_RUNNER: ["linux", "aarch64"],
+ WINDOWS_AMD64_RUNNER: ["windows", "amd64"]
}
# Override unavailable Python versions for some OS/Arch / job name combinations
PYTHON_VERSIONS = {
- "ubuntu-24.04-arm": "3.12.8",
- "ubuntu-latest": "3.12.8",
+ LINUX_AARCH64_RUNNER: "3.12.8",
+ LINUX_AMD64_RUNNER: "3.12.8",
"style-gate": "3.8.12",
"style-ecj-gate": "3.8.12",
+ # The JUnit gates build a delvewheel venv, which needs CPython >= 3.12 (or an
+ # Oracle-internal ARTIFACT_DOWNLOAD_SCRIPT); ci.jsonnet's 3.8 fails there upstream as well.
+ "python-junit-gate-windows": "3.12.8",
+ "python-junit-maven-gate-windows": "3.12.8",
}
EXCLUDED_SYSTEM_PACKAGES = {
@@ -119,7 +133,7 @@ def runs_on(self) -> str:
for os, caps in OSS.items():
if all(required in capabilities for required in caps): return os
- return "ubuntu-latest"
+ return LINUX_AMD64_RUNNER
@cached_property
def name(self) -> str:
@@ -132,7 +146,7 @@ def targets(self) -> list[str]:
@cached_property
def env(self) -> dict[str, str]:
environment = self.job.get("environment", {}) | DEFAULT_ENV
- if self.runs_on == "windows-latest":
+ if self.runs_on == WINDOWS_AMD64_RUNNER:
def _to_windows_env_format(s: str) -> str:
# Replace ${VAR} and $VAR with %VAR%
s = re.sub(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}", r"%\1%", s)
@@ -180,7 +194,7 @@ def system_packages(self) -> list[str]:
k = k[3:]
if any(excluded in k for excluded in EXCLUDED_SYSTEM_PACKAGES):
continue
- system_packages.append(f"'{k}'" if self.runs_on != "windows-latest" else f"{k}")
+ system_packages.append(f"'{k}'" if self.runs_on != WINDOWS_AMD64_RUNNER else f"{k}")
return system_packages
@cached_property
@@ -191,13 +205,13 @@ def python_packages(self) -> list[str]:
key = k[4:]
if key in PYTHON_PACKAGES_VERSIONS: continue
python_packages.append(f"{key}{v}")
- return [f"'{pkg}'" if self.runs_on != "windows-latest" else f"{pkg}" for pkg in python_packages]
+ return [f"'{pkg}'" if self.runs_on != WINDOWS_AMD64_RUNNER else f"{pkg}" for pkg in python_packages]
def get_download_steps(self, key: str, version: str) -> str:
download_link = self.get_download_link(key, version)
filename = download_link.split('/')[-1]
- if self.runs_on == "windows-latest":
+ if self.runs_on == WINDOWS_AMD64_RUNNER:
return (f"""
Invoke-WebRequest -Uri {download_link} -OutFile {filename}
Expand-Archive -Path {filename} -DestinationPath .
diff --git a/.github/workflows/_downstream-test-common.yml b/.github/workflows/_downstream-test-common.yml
index 9d97ce7c52..4f7bbd85ee 100644
--- a/.github/workflows/_downstream-test-common.yml
+++ b/.github/workflows/_downstream-test-common.yml
@@ -29,10 +29,10 @@ jobs:
fail-fast: false
matrix:
os:
- - id: ubuntu-latest
+ - id: linux-amd64-cipool
platform: linux
arch: amd64
- - id: macos-latest
+ - id: macos-arm64-cipool
platform: macos
arch: aarch64
diff --git a/.github/workflows/_downstream-test-oracledb.yml b/.github/workflows/_downstream-test-oracledb.yml
index 5e0717866b..b2104ca753 100644
--- a/.github/workflows/_downstream-test-oracledb.yml
+++ b/.github/workflows/_downstream-test-oracledb.yml
@@ -25,7 +25,7 @@ permissions:
jobs:
build-numpy-wheels:
- runs-on: ubuntu-latest
+ runs-on: linux-amd64-cipool
env:
PACKAGES_TO_BUILD: numpy==2.2.6
steps:
@@ -58,7 +58,7 @@ jobs:
build-pandas-wheels:
needs: build-numpy-wheels
- runs-on: ubuntu-latest
+ runs-on: linux-amd64-cipool
env:
PACKAGES_TO_BUILD: pandas==2.2.3
PIP_FIND_LINKS: ${{ github.workspace }}/dependency-wheels
@@ -99,7 +99,7 @@ jobs:
build-pyarrow-wheels:
needs: build-numpy-wheels
- runs-on: ubuntu-latest
+ runs-on: linux-amd64-cipool
env:
PACKAGES_TO_BUILD: pyarrow==20.0.0
PIP_FIND_LINKS: ${{ github.workspace }}/dependency-wheels
@@ -163,7 +163,7 @@ jobs:
fail-fast: false
matrix:
os:
- - id: ubuntu-latest
+ - id: linux-amd64-cipool
platform: linux
arch: amd64
diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml
index 082afd840c..d535bf735a 100644
--- a/.github/workflows/build-wheels.yml
+++ b/.github/workflows/build-wheels.yml
@@ -28,15 +28,12 @@ permissions:
jobs:
build_wheels:
+ # Elide's fork builds on its self-hosted runner pool, not on GitHub-hosted runners.
runs-on: >-
- ${{ contains(inputs.platform, 'self-hosted-linux-amd64') && fromJson('["self-hosted", "Linux", "X86"]') ||
- contains(inputs.platform, 'self-hosted-linux-aarch64') && fromJson('["self-hosted", "Linux", "ARM64"]') ||
- contains(inputs.platform, 'self-hosted-macos') && fromJson('["self-hosted", "macOS"]') ||
- contains(inputs.platform, 'self-hosted-windows') && fromJson('["self-hosted", "Windows"]') ||
- contains(inputs.platform, 'linux-amd64') && fromJson('["ubuntu-latest"]') ||
- contains(inputs.platform, 'linux-aarch64') && fromJson('["ubuntu-24.04-arm"]') ||
- contains(inputs.platform, 'windows') && fromJson('["windows-latest"]') ||
- contains(inputs.platform, 'macos') && fromJson('["macos-latest"]') }}
+ ${{ contains(inputs.platform, 'aarch64') && contains(inputs.platform, 'linux') && 'linux-arm64-cipool' ||
+ contains(inputs.platform, 'linux') && 'linux-amd64-cipool' ||
+ contains(inputs.platform, 'windows') && 'windows-amd64-cipool' ||
+ contains(inputs.platform, 'macos') && 'macos-arm64-cipool' }}
container: >-
${{ contains(inputs.platform, 'linux-amd64') && 'quay.io/pypa/manylinux_2_28_x86_64' ||
contains(inputs.platform, 'linux-aarch64') && 'quay.io/pypa/manylinux_2_28_aarch64' ||
diff --git a/.github/workflows/ci-matrix-gen.yml b/.github/workflows/ci-matrix-gen.yml
index 8920a5c6b5..6b759207b7 100644
--- a/.github/workflows/ci-matrix-gen.yml
+++ b/.github/workflows/ci-matrix-gen.yml
@@ -82,6 +82,17 @@ jobs:
matrix:
include: ${{ fromJson(needs.generate-tier1.outputs.artifact_matrix) }}
steps: &buildsteps
+ # The self-hosted runners keep their workspace between jobs, and these steps clone
+ # mx and other repositories next to the checkout, so start from an empty workspace.
+ - name: Clean workspace
+ if: runner.os != 'Windows'
+ shell: bash
+ run: find "${GITHUB_WORKSPACE:?}" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
+ - name: Clean workspace (Windows)
+ if: runner.os == 'Windows'
+ shell: pwsh
+ run: Get-ChildItem -Force -LiteralPath $env:GITHUB_WORKSPACE | Remove-Item -Recurse -Force
+
- name: Process matrix downloads
if: ${{ matrix.downloads_steps }}
run: |
@@ -91,8 +102,13 @@ jobs:
shell: bash
if: runner.os != 'Windows'
run: |
+ # A UTF-8 locale, as on GitHub's runners: the JDK uses it for file names (some CA
+ # certificates in /etc/ssl/certs have non-ASCII names).
+ if [ "$RUNNER_OS" = macOS ]; then echo "LANG=en_US.UTF-8" >> $GITHUB_ENV; echo "LC_ALL=en_US.UTF-8" >> $GITHUB_ENV;
+ else echo "LANG=C.UTF-8" >> $GITHUB_ENV; echo "LC_ALL=C.UTF-8" >> $GITHUB_ENV; fi
matrix_env='${{ toJson(matrix.env) }}'
- echo $matrix_env | jq -r 'to_entries[] | "\(.key)=\(.value)"' >> tmp.env
+ # python3 rather than jq, which the self-hosted runners don't all have.
+ echo $matrix_env | python3 -c 'import json, sys; [print(f"{k}={v}") for k, v in json.load(sys.stdin).items()]' >> tmp.env
while IFS= read -r line; do
eval "echo \"$line\"" >> $GITHUB_ENV
done < tmp.env
@@ -126,9 +142,31 @@ jobs:
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- if: ${{ matrix.python_version }}
+ if: ${{ runner.os == 'Windows' && matrix.python_version }}
with:
python-version: ${{ matrix.python_version }}
+ # actions/setup-python only has interpreters for GitHub's own runner images, so on
+ # the self-hosted Linux and macOS runners the version comes from uv (python-build-standalone),
+ # in a virtualenv with pip that is put first on the PATH.
+ - name: Set up Python with uv
+ if: ${{ runner.os != 'Windows' && matrix.python_version }}
+ shell: bash
+ env:
+ UV_VERSION: 0.12.20
+ PYTHON_VERSION: ${{ matrix.python_version }}
+ run: |
+ # Everything in the job's temp directory, and only uv-managed interpreters: the runners
+ # can have partial interpreters (and a shared uv cache) left by earlier jobs.
+ export UV_INSTALL_DIR="$RUNNER_TEMP/uv/bin" UV_PYTHON_INSTALL_DIR="$RUNNER_TEMP/uv/python" UV_NO_MODIFY_PATH=1
+ export UV_CACHE_DIR="$RUNNER_TEMP/uv/cache" UV_LINK_MODE=copy UV_PYTHON_PREFERENCE=only-managed
+ # The temp directory survives between jobs on these runners: a partial interpreter from an
+ # earlier job would be reused ("Python installation is missing a _sysconfigdata_ file").
+ rm -rf "$RUNNER_TEMP/uv"
+ curl -LsSf "https://astral.sh/uv/${UV_VERSION}/install.sh" | sh
+ rm -rf "$RUNNER_TEMP/python-venv"
+ "$UV_INSTALL_DIR/uv" venv --seed --python "$PYTHON_VERSION" "$RUNNER_TEMP/python-venv"
+ echo "$RUNNER_TEMP/python-venv/bin" >> "$GITHUB_PATH"
+ "$RUNNER_TEMP/python-venv/bin/python" --version
- name: Install python packages on Unix
if: ${{ runner.os != 'Windows' && matrix.python_packages }}
run: |
@@ -150,6 +188,19 @@ jobs:
for pkg in ${{ matrix.system_packages }}; do
sudo apt-get -qq install "$pkg" || true
done
+ # apt failures are tolerated above, and on a self-hosted runner whose dpkg state is
+ # broken the maven package can be unpacked but unconfigured (no /usr/bin/mvn), so
+ # fall back to a direct Maven download when the job needs it and mvn is missing.
+ case " ${{ matrix.system_packages }} " in *"'maven'"*)
+ if ! command -v mvn >/dev/null; then
+ maven_version=3.9.9
+ maven_dir="$RUNNER_TEMP/maven"
+ rm -rf "$maven_dir" && mkdir -p "$maven_dir"
+ curl -fsSL "https://archive.apache.org/dist/maven/maven-3/$maven_version/binaries/apache-maven-$maven_version-bin.tar.gz" | tar -xz -C "$maven_dir"
+ echo "$maven_dir/apache-maven-$maven_version/bin" >> "$GITHUB_PATH"
+ echo "Installed Maven $maven_version to $maven_dir (mvn was not on the PATH after apt-get)"
+ fi
+ ;; esac
- name: Install system packages on macOS
if: ${{ runner.os == 'macOS' && matrix.system_packages }}
run: |
@@ -162,12 +213,34 @@ jobs:
if: ${{ runner.os == 'Windows' && matrix.system_packages }}
run: |
$packages = '${{ matrix.system_packages }}' -split ' '
+ # The self-hosted Windows runners have no Chocolatey (and no preinstalled Maven, unlike
+ # GitHub's images), so Maven is downloaded directly when choco is missing; cmake is
+ # already on their PATH.
+ $haveChoco = [bool](Get-Command choco -ErrorAction SilentlyContinue)
foreach ($pkg in $packages) {
- try {
- choco install $pkg -y
- } catch {
- Write-Host "Failed to install $pkg, skipping."
- Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Yellow
+ if ($haveChoco) {
+ try {
+ choco install $pkg -y
+ } catch {
+ Write-Host "Failed to install $pkg, skipping."
+ Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Yellow
+ }
+ } elseif ($pkg -eq 'maven' -and -not (Get-Command mvn -ErrorAction SilentlyContinue)) {
+ $mavenVersion = '3.9.9'
+ $mavenDir = Join-Path $env:RUNNER_TEMP 'maven'
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $mavenDir
+ New-Item -ItemType Directory -Force $mavenDir | Out-Null
+ $zip = Join-Path $mavenDir "apache-maven-$mavenVersion-bin.zip"
+ Invoke-WebRequest -Uri "https://archive.apache.org/dist/maven/maven-3/$mavenVersion/binaries/apache-maven-$mavenVersion-bin.zip" -OutFile $zip
+ Expand-Archive -Path $zip -DestinationPath $mavenDir
+ $mavenBin = Join-Path $mavenDir "apache-maven-$mavenVersion\bin"
+ $mavenBin | Out-File -FilePath $env:GITHUB_PATH -Append
+ # Not verified with `mvn --version` here: the JDK is only fetched in a later step.
+ Write-Host "Installed Maven $mavenVersion to $mavenBin"
+ } elseif (Get-Command $pkg -ErrorAction SilentlyContinue) {
+ Write-Host "$pkg is already available: $((Get-Command $pkg).Source)"
+ } else {
+ Write-Host "No choco on this runner and no fallback for $pkg, skipping." -ForegroundColor Yellow
}
}
diff --git a/.github/workflows/ci-unittests.yml b/.github/workflows/ci-unittests.yml
index 91035de4d8..11fcfc3e2a 100644
--- a/.github/workflows/ci-unittests.yml
+++ b/.github/workflows/ci-unittests.yml
@@ -11,15 +11,20 @@ permissions:
jobs:
abi-check:
if: github.event.pull_request.draft == false
- runs-on: ubuntu-latest
+ runs-on: linux-amd64-cipool
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install libabigail
shell: bash
run: |
- sudo apt-get update
- sudo apt-get install -y abigail-tools
+ # The self-hosted runners keep abigail-tools installed; only touch apt when it is
+ # missing, so a broken dpkg state left by another job's package install does not fail
+ # the check.
+ if ! command -v abidiff >/dev/null; then
+ sudo apt-get update
+ sudo apt-get install -y abigail-tools
+ fi
- name: Get mx and labsjdk
shell: bash
diff --git a/.github/workflows/platforms-tests.yml b/.github/workflows/platforms-tests.yml
index f0fea75886..2c2982b3ec 100644
--- a/.github/workflows/platforms-tests.yml
+++ b/.github/workflows/platforms-tests.yml
@@ -9,7 +9,7 @@ permissions:
jobs:
centos-ppc64le-test:
- runs-on: ubuntu-latest
+ runs-on: linux-amd64-cipool
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/docs/site/_includes/compatibility.html b/docs/site/_includes/compatibility.html
index 6c22511b7c..c2f273b10f 100644
--- a/docs/site/_includes/compatibility.html
+++ b/docs/site/_includes/compatibility.html
@@ -87,7 +87,7 @@
const parts = item.name.split('.');
const package_name = parts[0];
const version = parts.slice(1, -1).join('.') || DB.ANY_VERSION;
- packages.push(`${package_name},${version},0,${BUILD_SCRIPT_AVAILABLE(item.html_url)}`);
+ packages.push(`${package_name},${version},,${BUILD_SCRIPT_AVAILABLE(item.html_url)}`);
}
resolve(packages.join("\n"));
} else {
@@ -116,7 +116,7 @@
patches.push(
[currentPatch.name,
currentPatch.version,
- 0,
+ '',
currentPatch.comment || PATCH_AVAILABLE].join(",")
)
}
@@ -143,7 +143,7 @@
patches.push(
[currentPatch.name,
currentPatch.version,
- 0,
+ '',
currentPatch.comment || PATCH_AVAILABLE].join(",")
)
}
@@ -285,11 +285,11 @@
load_db(graalpyModuleValue).then(function (db_contents) {
database = new DB("python", db_contents);
const rowsPerPage = getRowsPerPage();
- let count = 0;
let countCompatible = 0;
let countUntested = 0;
let countIncompatible = 0;
let countNotSupported = 0;
+ let tableRowCount = 0;
$('#dataTable tbody').empty();
for (let package in database.db) {
const versions = database.db[package];
@@ -300,7 +300,7 @@
if (versionA > versionB) return 1;
return 0;
});
- versions_loop: for (const version of version_keys) {
+ for (const version of version_keys) {
if (version.startsWith('~')) {
continue;
}
@@ -310,18 +310,16 @@
countCompatible++;
break;
case 1:
- countUntested++;
+ countIncompatible++;
break;
case 2:
- countIncompatible++;
+ countUntested++;
break;
case 3:
countNotSupported++;
break;
- default:
- continue versions_loop;
}
- const styling = count++ < rowsPerPage ? '' : ' style="display: none;"';
+ const styling = tableRowCount++ < rowsPerPage ? '' : ' style="display: none;"';
const highlight = ''.repeat(Math.ceil(info.highlight));
$('#dataTable tbody').append(`
@@ -332,6 +330,7 @@
}
}
$('#compatibility_page__search-field').trigger("input");
+ const count = countCompatible + countUntested + countIncompatible + countNotSupported;
updateStatistics(count, countCompatible, countUntested, countIncompatible, countNotSupported);
updatePagination(true);
});
@@ -543,15 +542,15 @@ Over 600 Python packages tested for compatibility
Compatible: loading...
+ title="More than 75% of the package's tests run successfully on GraalPy">Compatible:
loading...
Currently Untested: loading...
Currently
- Incompatible: loading...
+ title="Fewer than 75% of the package's tests run successfully on GraalPy">Currently
+ Failing Tests:
loading...
Not
Supported: loading...
diff --git a/graalpython/com.oracle.graal.python.benchmarks/python/micro/attribute-access-megamorphic.py b/graalpython/com.oracle.graal.python.benchmarks/python/micro/attribute-access-megamorphic.py
new file mode 100644
index 0000000000..ecfc0455e3
--- /dev/null
+++ b/graalpython/com.oracle.graal.python.benchmarks/python/micro/attribute-access-megamorphic.py
@@ -0,0 +1,164 @@
+# Copyright (c) 2017, 2026, 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.
+# micro benchmark: megamorphic attribute access inspired by richards
+
+iteration = 20000
+
+
+class TaskState(object):
+ pass
+
+
+class Task(TaskState):
+ def __init__(self, foo):
+ self.foo = foo
+
+
+class Task0(Task):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task1(Task0):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+
+
+class Task2(Task1):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task3(Task2):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+
+
+class Task4(Task):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task5(Task4):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+
+
+class Task6(Task5):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task7(Task6):
+ def __init__(self, foo):
+ Task.__init__(self, foo)
+
+
+class Task8(TaskState):
+ def __init__(self, foo):
+ self.foo = foo
+
+
+class Task9(Task8):
+ def __init__(self, foo):
+ Task8.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task10(Task9):
+ def __init__(self, foo):
+ Task8.__init__(self, foo)
+
+
+class Task11(Task10):
+ def __init__(self, foo):
+ Task8.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task12(TaskState):
+ def __init__(self, foo):
+ self.foo = foo
+
+
+class Task13(Task12):
+ def __init__(self, foo):
+ Task12.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+class Task14(Task13):
+ def __init__(self, foo):
+ Task12.__init__(self, foo)
+
+
+class Task15(Task14):
+ def __init__(self, foo):
+ Task12.__init__(self, foo)
+ self.bar = foo + 1
+ self.baz = foo + 2
+
+
+TASK_LIST = [Task0(0), Task1(1), Task2(2), Task3(3),
+ Task4(4), Task5(5), Task6(6), Task7(7),
+ Task8(8), Task9(9), Task10(10), Task11(11),
+ Task12(12), Task13(13), Task14(14), Task15(15)]
+
+
+def do_stuff():
+ task_list = TASK_LIST
+ total = 0
+ for i in range(iteration):
+ for t in task_list:
+ total = (total + t.foo) % 7
+
+ return total
+
+
+def measure(num):
+ result = 0
+ for i in range(num): # 50000
+ result |= do_stuff()
+
+ return result
+
+
+def __benchmark__(num=1000):
+ return measure(num)
+
+
+def run():
+ __benchmark__(num=10)
+
diff --git a/graalpython/com.oracle.graal.python.cext/src/call.c b/graalpython/com.oracle.graal.python.cext/src/call.c
index 954f70eed0..b6693f5af5 100644
--- a/graalpython/com.oracle.graal.python.cext/src/call.c
+++ b/graalpython/com.oracle.graal.python.cext/src/call.c
@@ -929,6 +929,31 @@ PyObject_VectorcallMethod(PyObject *name, PyObject *const *args,
assert(args != NULL);
assert(PyVectorcall_NARGS(nargsf) >= 1);
+ /* GraalPy change: Perform the method lookup and call in a single upcall if the receiver is
+ managed, or if a native extension type inherited GraalPy's managed object.__getattribute__
+ slot. If the lookup finds an unbound native method descriptor, the upcall returns the
+ descriptor instead of invoking it. This keeps native extension method calls in native code
+ without duplicating managed MRO and instance-dict lookup semantics here. */
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ if (points_to_py_handle_space(args[0]) ||
+ (Py_TYPE(args[0])->tp_getattro == PyBaseObject_Type.tp_getattro && PyUnicode_CheckExact(name))) {
+ PyObject *result = NULL;
+ int native_method = GraalPyPrivate_Object_VectorcallMethod(name, args[0], args + 1,
+ nargs - 1, kwnames, &result);
+ if (native_method <= 0) {
+ return result;
+ }
+
+ /* The receiver is still args[0], so the descriptor can use the original argument array.
+ Do not expose PY_VECTORCALL_ARGUMENTS_OFFSET: the native callee must not modify the
+ slot immediately preceding args. */
+ nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET;
+ PyObject *call_result = _PyObject_VectorcallTstate(_PyThreadState_GET(), result,
+ args, nargsf, kwnames);
+ Py_DECREF(result);
+ return call_result;
+ }
+
PyThreadState *tstate = _PyThreadState_GET();
PyObject *callable = NULL;
/* Use args[0] as "self" argument */
diff --git a/graalpython/com.oracle.graal.python.cext/src/object.c b/graalpython/com.oracle.graal.python.cext/src/object.c
index 4f6d29b17d..2a67cf1cf6 100644
--- a/graalpython/com.oracle.graal.python.cext/src/object.c
+++ b/graalpython/com.oracle.graal.python.cext/src/object.c
@@ -1645,6 +1645,14 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
}
}
+ /* GraalPy change: Native extension types inherit GraalPy's managed
+ object.__getattribute__ slot rather than PyObject_GenericGetAttr.
+ Do the LOAD_METHOD-style lookup on the managed side so that method
+ descriptors stay unbound. */
+ if (tp->tp_getattro == PyBaseObject_Type.tp_getattro && PyUnicode_CheckExact(name)) {
+ return GraalPyPrivate_Object_GetMethod(obj, name, method);
+ }
+
if (tp->tp_getattro != PyObject_GenericGetAttr || !PyUnicode_CheckExact(name)) {
*method = PyObject_GetAttr(obj, name);
return 0;
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 dcc72a50c3..b082c7b78b 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
@@ -157,6 +157,7 @@ private static void appendDecodedChars(StringBuilder builder, CharBuffer out) {
private boolean noUserSite = false;
private boolean noSite = false;
private boolean unbufferedIO = false;
+ private boolean legacyWindowsStdio = false;
private boolean multiContext = false;
private int repeatedRuns = 1;
private boolean snaptshotStartup = false;
@@ -794,6 +795,7 @@ protected void launch(Builder contextBuilder) {
safePath = safePath || getBoolEnv("PYTHONSAFEPATH");
verboseFlag = verboseFlag || getBoolEnv("PYTHONVERBOSE");
unbufferedIO = unbufferedIO || getBoolEnv("PYTHONUNBUFFERED");
+ legacyWindowsStdio = getBoolEnv("PYTHONLEGACYWINDOWSSTDIO");
dontWriteBytecode = dontWriteBytecode || getBoolEnv("PYTHONDONTWRITEBYTECODE");
String maxStrDigitsEnv = getEnv("PYTHONINTMAXSTRDIGITS");
if (intMaxStrDigits < 0 && maxStrDigitsEnv != null) {
@@ -877,6 +879,9 @@ protected void launch(Builder contextBuilder) {
}
contextBuilder.option("python.IgnoreEnvironmentFlag", Boolean.toString(ignoreEnv));
contextBuilder.option("python.UnbufferedIO", Boolean.toString(unbufferedIO));
+ if (IS_WINDOWS) {
+ contextBuilder.option("python.LegacyWindowsStdio", Boolean.toString(legacyWindowsStdio));
+ }
ConsoleHandler consoleHandler = createConsoleHandler(System.in, System.out);
contextBuilder.arguments(getLanguageId(), programArgs.toArray(new String[programArgs.size()]));
@@ -1288,6 +1293,7 @@ protected void printHelp(OptionCategory maxCategory) {
"PYTHON_CPU_COUNT: override the return value of os.cpu_count() (-X cpu_count).\n" +
"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" +
"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" +
+ "PYTHONLEGACYWINDOWSSTDIO: use legacy Windows console I/O.\n" +
"PYTHONHASHSEED: if this variable is set to 'random', the effect is the same\n" +
" as specifying the -R option: a random value is used to seed the hashes of\n" +
" str, bytes and datetime objects. It can also be set to an integer\n" +
diff --git a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/SocketTests.java b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/SocketTests.java
index f71fb33cf2..a795a5b3d3 100644
--- a/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/SocketTests.java
+++ b/graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/SocketTests.java
@@ -98,7 +98,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import com.oracle.graal.python.PythonLanguage;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -110,28 +109,28 @@
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+import com.oracle.graal.python.PythonLanguage;
import com.oracle.graal.python.annotations.PythonOS;
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
+import com.oracle.graal.python.nodes.util.PosixSupportNodes;
import com.oracle.graal.python.runtime.PosixConstants.MandatoryIntConstant;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.AcceptResult;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.AddrInfoCursor;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.AddrInfoCursorLibrary;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.Buffer;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.FamilySpecificSockAddr;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.GetAddrInfoException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.Inet4SockAddr;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.Inet6SockAddr;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.InvalidAddressException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.InvalidUnixSocketPathException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixErrnoException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.RecvfromResult;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.SelectResult;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.Timeval;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.UniversalSockAddr;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.UniversalSockAddrLibrary;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.UnixSockAddr;
+import com.oracle.graal.python.runtime.PosixSupport;
+import com.oracle.graal.python.runtime.PosixSupport.AcceptResult;
+import com.oracle.graal.python.runtime.PosixSupport.AddrInfoCursor;
+import com.oracle.graal.python.runtime.PosixSupport.Buffer;
+import com.oracle.graal.python.runtime.PosixSupport.FamilySpecificSockAddr;
+import com.oracle.graal.python.runtime.PosixSupport.GetAddrInfoException;
+import com.oracle.graal.python.runtime.PosixSupport.Inet4SockAddr;
+import com.oracle.graal.python.runtime.PosixSupport.Inet6SockAddr;
+import com.oracle.graal.python.runtime.PosixSupport.InvalidAddressException;
+import com.oracle.graal.python.runtime.PosixSupport.InvalidUnixSocketPathException;
+import com.oracle.graal.python.runtime.PosixSupport.PosixErrnoException;
+import com.oracle.graal.python.runtime.PosixSupport.PosixException;
+import com.oracle.graal.python.runtime.PosixSupport.RecvfromResult;
+import com.oracle.graal.python.runtime.PosixSupport.SelectResult;
+import com.oracle.graal.python.runtime.PosixSupport.Timeval;
+import com.oracle.graal.python.runtime.PosixSupport.UniversalSockAddr;
+import com.oracle.graal.python.runtime.PosixSupport.UnixSockAddr;
import com.oracle.graal.python.test.integration.CleanupRule;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.memory.ByteArraySupport;
@@ -158,17 +157,11 @@ public static String[] params() {
private static final byte[] DATA2 = new byte[]{4, 5, 6, 7};
private static final UnixSockAddr UNIX_SOCK_ADDR_UNNAMED = new UnixSockAddr(new byte[0]);
- private Object posixSupport;
- private PosixSupportLibrary lib;
- private UniversalSockAddrLibrary usaLib;
- private AddrInfoCursorLibrary aicLib;
+ private PosixSupport posixSupport;
@Before
public void setUp() {
posixSupport = withPythonContextRule.getPythonContext().getPosixSupport();
- lib = PosixSupportLibrary.getUncached();
- usaLib = UniversalSockAddrLibrary.getUncached();
- aicLib = AddrInfoCursorLibrary.getUncached();
}
@Test
@@ -195,21 +188,21 @@ public void fillUniversalSockAddrUnix() throws PosixException {
@Test
public void dgramUnboundGetsocknameInet4() throws PosixException {
int s = createSocket(AF_INET.value, SOCK_DGRAM.value, 0);
- checkUsa(new Inet4SockAddr(0, INADDR_ANY.value), lib.getsockname(posixSupport, s));
+ checkUsa(new Inet4SockAddr(0, INADDR_ANY.value), posixSupport.getsockname(s));
}
@Test
public void dgramUnboundGetsocknameInet6() throws PosixException {
assumeTrue(isInet6Supported());
int s = createSocket(AF_INET6.value, SOCK_DGRAM.value, 0);
- checkUsa(new Inet6SockAddr(0, IN6ADDR_ANY, 0, 0), lib.getsockname(posixSupport, s));
+ checkUsa(new Inet6SockAddr(0, IN6ADDR_ANY, 0, 0), posixSupport.getsockname(s));
}
@Test
public void dgramUnboundGetsocknameUnix() throws PosixException {
assumeTrue("native".equals(backendName));
int s = createSocket(AF_UNIX.value, SOCK_DGRAM.value, 0);
- checkUsa(new UnixSockAddr(new byte[0]), lib.getsockname(posixSupport, s));
+ checkUsa(new UnixSockAddr(new byte[0]), posixSupport.getsockname(s));
}
@Test
@@ -430,7 +423,7 @@ public void streamRecvfromInet() throws PosixException {
checkUsa(cli.address(), c.getpeername());
c.send(DATA, 0);
- assertEquals(AF_UNSPEC.value, usaLib.getFamily(cli.recvfrom(DATA, 0)));
+ assertEquals(AF_UNSPEC.value, cli.recvfrom(DATA, 0).getFamily());
}
@Test
@@ -479,7 +472,7 @@ public void streamWriteReadUnix() throws PosixException, IOException {
Socket cli = new Socket(AF_UNIX.value, SOCK_STREAM.value);
UniversalSockAddr addr = null;
try {
- addr = lib.createUniversalSockAddrUnix(posixSupport, unixSockAddr);
+ addr = posixSupport.createUniversalSockAddrUnix(unixSockAddr);
} catch (InvalidUnixSocketPathException e) {
assumeNoException(e);
}
@@ -506,7 +499,7 @@ public void dgramUnconnectedGetpeername() {
@Test
public void dgramListen() {
- expectErrno(() -> lib.listen(posixSupport, new UdpServer(AF_INET.value).fd, 5),
+ expectErrno(() -> posixSupport.listen(new UdpServer(AF_INET.value).fd, 5),
OSErrorEnum.EOPNOTSUPP,
OSErrorEnum.EACCES /* Some CI machines seem to block this with EACCESS */);
}
@@ -528,7 +521,7 @@ public void streamUnconnectedGetpeername() {
@Test
public void streamUnconnectedRead() {
expectErrno(() -> {
- lib.read(posixSupport, new TcpClient(AF_INET.value).fd, 10);
+ posixSupport.read(new TcpClient(AF_INET.value).fd, 10);
}, OSErrorEnum.ENOTCONN);
}
@@ -536,7 +529,7 @@ public void streamUnconnectedRead() {
public void streamUnconnectedWrite() {
// From send(2): Linux may return EPIPE instead of ENOTCONN.
expectErrno(() -> {
- lib.write(posixSupport, new TcpClient(AF_INET.value).fd, Buffer.wrap(DATA));
+ posixSupport.write(new TcpClient(AF_INET.value).fd, Buffer.wrap(DATA));
}, OSErrorEnum.ENOTCONN, OSErrorEnum.EPIPE);
}
@@ -550,7 +543,7 @@ public void streamListeningGetpeername() {
@Test
public void streamListeningRecv() {
expectErrno(() -> {
- lib.recv(posixSupport, new TcpServer(AF_INET.value).fd, new byte[10], 0, 10, 0);
+ posixSupport.recv(new TcpServer(AF_INET.value).fd, new byte[10], 0, 10, 0);
}, OSErrorEnum.ENOTCONN);
}
@@ -558,14 +551,14 @@ public void streamListeningRecv() {
public void streamListeningSend() {
// From send(2): Linux may return EPIPE instead of ENOTCONN.
expectErrno(() -> {
- lib.send(posixSupport, new TcpServer(AF_INET.value).fd, DATA, 0, DATA.length, 0);
+ posixSupport.send(new TcpServer(AF_INET.value).fd, DATA, 0, DATA.length, 0);
}, OSErrorEnum.ENOTCONN, OSErrorEnum.EPIPE);
}
@Test
public void streamListeningRead() {
expectErrno(() -> {
- lib.read(posixSupport, new TcpServer(AF_INET.value).fd, 10);
+ posixSupport.read(new TcpServer(AF_INET.value).fd, 10);
}, OSErrorEnum.ENOTCONN);
}
@@ -573,7 +566,7 @@ public void streamListeningRead() {
public void streamListeningWrite() {
// From send(2): Linux may return EPIPE instead of ENOTCONN.
expectErrno(() -> {
- lib.write(posixSupport, new TcpServer(AF_INET.value).fd, Buffer.wrap(DATA));
+ posixSupport.write(new TcpServer(AF_INET.value).fd, Buffer.wrap(DATA));
}, OSErrorEnum.ENOTCONN, OSErrorEnum.EPIPE);
}
@@ -594,9 +587,9 @@ public void getSocketOptionsAcceptConn() throws PosixException {
assumeTrue("native".equals(backendName));
assumeTrue(runsOnLinux()); // darwin defines but does not support SO_ACCEPTCONN
int socket = createSocket(AF_INET.value, SOCK_STREAM.value, 0);
- lib.bind(posixSupport, socket, createUsa(new Inet4SockAddr(0, INADDR_LOOPBACK.value)));
+ posixSupport.bind(socket, createUsa(new Inet4SockAddr(0, INADDR_LOOPBACK.value)));
assertEquals(0, getIntSockOpt(socket, SOL_SOCKET.value, SO_ACCEPTCONN.value));
- lib.listen(posixSupport, socket, 5);
+ posixSupport.listen(socket, 5);
assertEquals(1, getIntSockOpt(socket, SOL_SOCKET.value, SO_ACCEPTCONN.value));
}
@@ -627,7 +620,7 @@ public void nonBlockingDgramRecv() {
UdpClient cli = new UdpClient(AF_INET.value);
cli.setBlocking(false);
assertFalse(cli.getBlocking());
- lib.recv(posixSupport, cli.fd, new byte[10], 0, 10, 0);
+ posixSupport.recv(cli.fd, new byte[10], 0, 10, 0);
}, OSErrorEnum.EWOULDBLOCK);
}
@@ -637,7 +630,7 @@ public void nonBlockingAccept() throws PosixException {
TcpClient cli = new TcpClient(AF_INET.value);
srv.setBlocking(false);
try {
- lib.accept(posixSupport, srv.fd);
+ posixSupport.accept(srv.fd);
fail("Expected accept() to fail with EWOULDBLOCK");
} catch (PosixException e) {
assertTrue(e.hasErrno(OSErrorEnum.EWOULDBLOCK));
@@ -646,7 +639,7 @@ public void nonBlockingAccept() throws PosixException {
// A completed connect does not guarantee that the connection is already visible to a
// non-blocking accept(). Wait until the listening socket reports that it is readable.
- SelectResult res = lib.select(posixSupport, new int[]{srv.fd}, new int[0], new int[0], new Timeval(1, 0));
+ SelectResult res = posixSupport.select(new int[]{srv.fd}, new int[0], new int[0], new Timeval(1, 0));
assertTrue(res.getReadFds()[0]);
srv.accept(cli.address());
}
@@ -656,12 +649,12 @@ public void dgramSelect() throws PosixException {
UdpServer srv = new UdpServer(AF_INET.value);
UdpClient cli = new UdpClient(AF_INET.value);
- SelectResult res = lib.select(posixSupport, new int[]{srv.fd}, new int[0], new int[0], new Timeval(0, 100000));
+ SelectResult res = posixSupport.select(new int[]{srv.fd}, new int[0], new int[0], new Timeval(0, 100000));
assertFalse(res.getReadFds()[0]);
cli.sendto(DATA, 0, srv.usa());
- res = lib.select(posixSupport, new int[]{srv.fd}, new int[0], new int[0], new Timeval(0, 100000));
+ res = posixSupport.select(new int[]{srv.fd}, new int[0], new int[0], new Timeval(0, 100000));
assertTrue(res.getReadFds()[0]);
checkUsa(cli.address(), srv.recvfrom(DATA, 0));
@@ -676,12 +669,12 @@ public void streamSelect() throws PosixException {
TcpServer srv = new TcpServer(AF_INET.value);
TcpClient cli = new TcpClient(AF_INET.value);
- SelectResult res = lib.select(posixSupport, new int[]{srv.fd}, new int[0], new int[0], new Timeval(0, 100000));
+ SelectResult res = posixSupport.select(new int[]{srv.fd}, new int[0], new int[0], new Timeval(0, 100000));
assertFalse(res.getReadFds()[0]);
cli.connect(srv.usa());
- res = lib.select(posixSupport, new int[]{srv.fd, cli.fd}, new int[0], new int[0], new Timeval(0, 100000));
+ res = posixSupport.select(new int[]{srv.fd, cli.fd}, new int[0], new int[0], new Timeval(0, 100000));
assertTrue(res.getReadFds()[0]);
assertFalse(res.getReadFds()[1]);
@@ -694,7 +687,7 @@ public void streamSelect() throws PosixException {
c.send(DATA, 0);
- res = lib.select(posixSupport, new int[]{srv.fd, cli.fd, c.fd}, new int[0], new int[0], new Timeval(0, 100000));
+ res = posixSupport.select(new int[]{srv.fd, cli.fd, c.fd}, new int[0], new int[0], new Timeval(0, 100000));
assertFalse(res.getReadFds()[0]);
// c is readable immediately after shutdown(SHUT_RD), while the data sent to cli may arrive
@@ -703,63 +696,63 @@ public void streamSelect() throws PosixException {
boolean cliReadable = res.getReadFds()[1];
boolean cReadable = res.getReadFds()[2];
if (!cliReadable) {
- SelectResult cliRes = lib.select(posixSupport, new int[]{cli.fd}, new int[0], new int[0],
+ SelectResult cliRes = posixSupport.select(new int[]{cli.fd}, new int[0], new int[0],
new Timeval(1, 0));
cliReadable = cliRes.getReadFds()[0];
}
if (!cReadable) {
- SelectResult cRes = lib.select(posixSupport, new int[]{c.fd}, new int[0], new int[0], new Timeval(1, 0));
+ SelectResult cRes = posixSupport.select(new int[]{c.fd}, new int[0], new int[0], new Timeval(1, 0));
cReadable = cRes.getReadFds()[0];
}
assertTrue(cliReadable);
assertTrue(cReadable);
- assertEquals(0, lib.recv(posixSupport, c.fd, new byte[10], 0, 10, 0));
+ assertEquals(0, posixSupport.recv(c.fd, new byte[10], 0, 10, 0));
cli.recv(DATA, 0);
}
@Test
public void getnameinfo() throws PosixException, GetAddrInfoException {
- Object[] res = lib.getnameinfo(posixSupport, createUsa(new Inet6SockAddr(443, IN6ADDR_LOOPBACK, 0, 0)), NI_NUMERICSERV.value | NI_NUMERICHOST.value);
+ Object[] res = posixSupport.getnameinfo(createUsa(new Inet6SockAddr(443, IN6ADDR_LOOPBACK, 0, 0)), NI_NUMERICSERV.value | NI_NUMERICHOST.value);
assertThat(p2s(res[0]), anyOf(equalTo("::1"), equalTo("0:0:0:0:0:0:0:1%0")));
assertEquals("443", p2s(res[1]));
- res = lib.getnameinfo(posixSupport, createUsa(new Inet4SockAddr(443, INADDR_LOOPBACK.value)), 0);
+ res = posixSupport.getnameinfo(createUsa(new Inet4SockAddr(443, INADDR_LOOPBACK.value)), 0);
assertEquals("localhost", p2s(res[0]));
assertEquals("https", p2s(res[1]));
- res = lib.getnameinfo(posixSupport, createUsa(new Inet4SockAddr(53535, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value);
+ res = posixSupport.getnameinfo(createUsa(new Inet4SockAddr(53535, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value);
assertEquals("53535", p2s(res[1]));
}
@Test
public void getnameinfoUdp() throws PosixException, GetAddrInfoException {
assumeTrue(runsOnLinux());
- Object[] res = lib.getnameinfo(posixSupport, createUsa(new Inet4SockAddr(512, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value);
+ Object[] res = posixSupport.getnameinfo(createUsa(new Inet4SockAddr(512, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value);
assertEquals("exec", p2s(res[1]));
- res = lib.getnameinfo(posixSupport, createUsa(new Inet4SockAddr(512, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value | NI_DGRAM.value);
+ res = posixSupport.getnameinfo(createUsa(new Inet4SockAddr(512, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value | NI_DGRAM.value);
assertThat(p2s(res[1]), anyOf(equalTo("biff"), equalTo("comsat")));
}
@Test
public void getnameinfoErr() {
expectGetAddrInfoException(() -> {
- lib.getnameinfo(posixSupport, createUsa(new Inet4SockAddr(443, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value | NI_NAMEREQD.value);
+ posixSupport.getnameinfo(createUsa(new Inet4SockAddr(443, INADDR_LOOPBACK.value)), NI_NUMERICHOST.value | NI_NAMEREQD.value);
}, EAI_NONAME);
}
@Test
public void getaddrinfoErrNoInput() {
expectGetAddrInfoException(() -> {
- lib.getaddrinfo(posixSupport, null, null, AF_UNSPEC.value, 0, 0, 0);
+ posixSupport.getaddrinfo(null, null, AF_UNSPEC.value, 0, 0, 0);
}, EAI_NONAME);
}
@Test
public void getaddrinfoErrFamily() {
expectGetAddrInfoException(() -> {
- lib.getaddrinfo(posixSupport, null, s2p("http"), -42, 0, 0, 0);
+ posixSupport.getaddrinfo(null, s2p("http"), -42, 0, 0, 0);
}, EAI_FAMILY);
}
@@ -767,7 +760,7 @@ public void getaddrinfoErrFamily() {
public void getaddrinfoErrSockType() {
assumeTrue(runsOnLinux());
expectGetAddrInfoException(() -> {
- lib.getaddrinfo(posixSupport, null, s2p("http"), AF_UNSPEC.value, -42, 0, 0);
+ posixSupport.getaddrinfo(null, s2p("http"), AF_UNSPEC.value, -42, 0, 0);
}, EAI_SOCKTYPE);
}
@@ -775,7 +768,7 @@ public void getaddrinfoErrSockType() {
public void getaddrinfoErrService() {
assumeTrue(runsOnLinux());
expectGetAddrInfoException(() -> {
- lib.getaddrinfo(posixSupport, null, s2p("invalid service"), AF_UNSPEC.value, SOCK_DGRAM.value, 0, 0);
+ posixSupport.getaddrinfo(null, s2p("invalid service"), AF_UNSPEC.value, SOCK_DGRAM.value, 0, 0);
}, EAI_SERVICE);
}
@@ -783,7 +776,7 @@ public void getaddrinfoErrService() {
public void getaddrinfoErrAddrFamily() {
assumeTrue(runsOnLinux());
expectGetAddrInfoException(() -> {
- lib.getaddrinfo(posixSupport, s2p("::1"), null, AF_INET.value, 0, 0, 0);
+ posixSupport.getaddrinfo(s2p("::1"), null, AF_INET.value, 0, 0, 0);
}, EAI_ADDRFAMILY);
}
@@ -791,43 +784,43 @@ public void getaddrinfoErrAddrFamily() {
public void getaddrinfoBadFlags() {
assumeTrue(runsOnLinux());
expectGetAddrInfoException(() -> {
- lib.getaddrinfo(posixSupport, null, s2p("https"), AF_INET.value, 0, 0, AI_CANONNAME.value);
+ posixSupport.getaddrinfo(null, s2p("https"), AF_INET.value, 0, 0, AI_CANONNAME.value);
}, EAI_BADFLAGS);
}
@Test
public void getaddrinfoServiceOnly() throws PosixException, GetAddrInfoException {
Object service = s2p("https");
- AddrInfoCursor aic = lib.getaddrinfo(posixSupport, null, service, AF_UNSPEC.value, SOCK_STREAM.value, 0, 0);
- cleanup.add(() -> aicLib.release(aic));
+ AddrInfoCursor aic = posixSupport.getaddrinfo(null, service, AF_UNSPEC.value, SOCK_STREAM.value, 0, 0);
+ cleanup.add(() -> aic.release());
do {
- int family = aicLib.getFamily(aic);
+ int family = aic.getFamily();
- assertEquals(SOCK_STREAM.value, aicLib.getSockType(aic));
- assertNull(aicLib.getCanonName(aic));
+ assertEquals(SOCK_STREAM.value, aic.getSockType());
+ assertNull(aic.getCanonName());
- UniversalSockAddr usa = aicLib.getSockAddr(aic);
- assertEquals(family, usaLib.getFamily(usa));
+ UniversalSockAddr usa = aic.getSockAddr();
+ assertEquals(family, usa.getFamily());
if (family == AF_INET.value) {
- Inet4SockAddr addr2 = usaLib.asInet4SockAddr(usa);
+ Inet4SockAddr addr2 = usa.asInet4SockAddr();
assertEquals(INADDR_LOOPBACK.value, addr2.getAddress());
assertEquals(443, addr2.getPort());
}
- } while (aicLib.next(aic));
+ } while (aic.next());
}
@Test
public void getaddrinfoPassive() throws PosixException, GetAddrInfoException {
Object service = s2p("https");
- AddrInfoCursor aic = lib.getaddrinfo(posixSupport, null, service, AF_INET.value, 0, IPPROTO_TCP.value, AI_PASSIVE.value);
- cleanup.add(() -> aicLib.release(aic));
- assertEquals(AF_INET.value, aicLib.getFamily(aic));
- assertEquals(SOCK_STREAM.value, aicLib.getSockType(aic));
- assertEquals(IPPROTO_TCP.value, aicLib.getProtocol(aic));
- assertNull(aicLib.getCanonName(aic));
-
- UniversalSockAddr usa = aicLib.getSockAddr(aic);
- Inet4SockAddr addr = usaLib.asInet4SockAddr(usa);
+ AddrInfoCursor aic = posixSupport.getaddrinfo(null, service, AF_INET.value, 0, IPPROTO_TCP.value, AI_PASSIVE.value);
+ cleanup.add(aic::release);
+ assertEquals(AF_INET.value, aic.getFamily());
+ assertEquals(SOCK_STREAM.value, aic.getSockType());
+ assertEquals(IPPROTO_TCP.value, aic.getProtocol());
+ assertNull(aic.getCanonName());
+
+ UniversalSockAddr usa = aic.getSockAddr();
+ Inet4SockAddr addr = usa.asInet4SockAddr();
assertEquals(INADDR_ANY.value, addr.getAddress());
assertEquals(443, addr.getPort());
}
@@ -835,37 +828,37 @@ public void getaddrinfoPassive() throws PosixException, GetAddrInfoException {
@Test
public void getaddrinfoServerOnlyNoCanon() throws PosixException, GetAddrInfoException {
Object node = s2p("localhost");
- AddrInfoCursor aic = lib.getaddrinfo(posixSupport, node, null, AF_UNSPEC.value, SOCK_DGRAM.value, 0, 0);
- cleanup.add(() -> aicLib.release(aic));
+ AddrInfoCursor aic = posixSupport.getaddrinfo(node, null, AF_UNSPEC.value, SOCK_DGRAM.value, 0, 0);
+ cleanup.add(aic::release);
do {
- assertEquals(SOCK_DGRAM.value, aicLib.getSockType(aic));
- assertEquals(IPPROTO_UDP.value, aicLib.getProtocol(aic));
- assertNull(aicLib.getCanonName(aic));
-
- if (aicLib.getFamily(aic) == AF_INET.value) {
- UniversalSockAddr usa = aicLib.getSockAddr(aic);
- assertEquals(AF_INET.value, usaLib.getFamily(usa));
- Inet4SockAddr addr = usaLib.asInet4SockAddr(usa);
+ assertEquals(SOCK_DGRAM.value, aic.getSockType());
+ assertEquals(IPPROTO_UDP.value, aic.getProtocol());
+ assertNull(aic.getCanonName());
+
+ if (aic.getFamily() == AF_INET.value) {
+ UniversalSockAddr usa = aic.getSockAddr();
+ assertEquals(AF_INET.value, usa.getFamily());
+ Inet4SockAddr addr = usa.asInet4SockAddr();
assertEquals(INADDR_LOOPBACK.value, addr.getAddress());
assertEquals(0, addr.getPort());
}
- } while (aicLib.next(aic));
+ } while (aic.next());
}
@Test
public void getaddrinfo() throws PosixException, GetAddrInfoException {
Object node = s2p("localhost");
Object service = s2p("https");
- AddrInfoCursor aic = lib.getaddrinfo(posixSupport, node, service, AF_INET.value, 0, IPPROTO_TCP.value, AI_CANONNAME.value);
- cleanup.add(() -> aicLib.release(aic));
- assertEquals(AF_INET.value, aicLib.getFamily(aic));
- assertEquals(SOCK_STREAM.value, aicLib.getSockType(aic));
- assertEquals(IPPROTO_TCP.value, aicLib.getProtocol(aic));
- assertEquals("localhost", p2s(aicLib.getCanonName(aic)));
-
- UniversalSockAddr usa = aicLib.getSockAddr(aic);
- assertEquals(AF_INET.value, usaLib.getFamily(usa));
- Inet4SockAddr addr2 = usaLib.asInet4SockAddr(usa);
+ AddrInfoCursor aic = posixSupport.getaddrinfo(node, service, AF_INET.value, 0, IPPROTO_TCP.value, AI_CANONNAME.value);
+ cleanup.add(aic::release);
+ assertEquals(AF_INET.value, aic.getFamily());
+ assertEquals(SOCK_STREAM.value, aic.getSockType());
+ assertEquals(IPPROTO_TCP.value, aic.getProtocol());
+ assertEquals("localhost", p2s(aic.getCanonName()));
+
+ UniversalSockAddr usa = aic.getSockAddr();
+ assertEquals(AF_INET.value, usa.getFamily());
+ Inet4SockAddr addr2 = usa.asInet4SockAddr();
assertEquals(INADDR_LOOPBACK.value, addr2.getAddress());
assertEquals(443, addr2.getPort());
}
@@ -916,7 +909,7 @@ public void inet_addr() {
for (Map.Entry a : ip4Addresses.entrySet()) {
String src = a.getKey();
Integer expected = a.getValue();
- int actual = lib.inet_addr(posixSupport, s2p(src));
+ int actual = posixSupport.inet_addr(s2p(src));
assertEquals("inet_addr(\"" + src + "\")", expected == null ? INADDR_NONE.value : expected, actual);
}
}
@@ -928,7 +921,7 @@ public void inet_aton() {
Integer expected = a.getValue();
Integer actual;
try {
- actual = lib.inet_aton(posixSupport, s2p(src));
+ actual = posixSupport.inet_aton(s2p(src));
} catch (InvalidAddressException e) {
actual = null;
}
@@ -938,36 +931,36 @@ public void inet_aton() {
@Test
public void inet_ntoa() {
- assertEquals("0.0.0.0", p2s(lib.inet_ntoa(posixSupport, 0x00000000)));
- assertEquals("1.2.3.4", p2s(lib.inet_ntoa(posixSupport, 0x01020304)));
- assertEquals("18.52.86.120", p2s(lib.inet_ntoa(posixSupport, 0x12345678)));
- assertEquals("255.255.255.255", p2s(lib.inet_ntoa(posixSupport, 0xffffffff)));
+ assertEquals("0.0.0.0", p2s(posixSupport.inet_ntoa(0x00000000)));
+ assertEquals("1.2.3.4", p2s(posixSupport.inet_ntoa(0x01020304)));
+ assertEquals("18.52.86.120", p2s(posixSupport.inet_ntoa(0x12345678)));
+ assertEquals("255.255.255.255", p2s(posixSupport.inet_ntoa(0xffffffff)));
}
@Test
public void inet_pton() throws PosixException, InvalidAddressException {
- assertArrayEquals(new byte[]{1, 2, -2, -1}, lib.inet_pton(posixSupport, AF_INET.value, s2p("1.2.254.255")));
- assertArrayEquals(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, lib.inet_pton(posixSupport, AF_INET6.value, s2p("1::FF")));
- assertArrayEquals(MAPPED_LOOPBACK, lib.inet_pton(posixSupport, AF_INET6.value, s2p("::ffff:127.0.0.1")));
+ assertArrayEquals(new byte[]{1, 2, -2, -1}, posixSupport.inet_pton(AF_INET.value, s2p("1.2.254.255")));
+ assertArrayEquals(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, posixSupport.inet_pton(AF_INET6.value, s2p("1::FF")));
+ assertArrayEquals(MAPPED_LOOPBACK, posixSupport.inet_pton(AF_INET6.value, s2p("::ffff:127.0.0.1")));
}
@Test
public void inet_pton_eafnosupport() {
expectErrno(() -> {
- lib.inet_pton(posixSupport, AF_UNSPEC.value, s2p(""));
+ posixSupport.inet_pton(AF_UNSPEC.value, s2p(""));
}, OSErrorEnum.EAFNOSUPPORT);
}
@Test
public void inet_pton_invalid_inet6() {
Assert.assertThrows(InvalidAddressException.class,
- () -> lib.inet_pton(posixSupport, AF_INET6.value, s2p(":")));
+ () -> posixSupport.inet_pton(AF_INET6.value, s2p(":")));
}
@Test
public void inet_pton_invalid_inet4_as_inet6() {
Assert.assertThrows(InvalidAddressException.class,
- () -> lib.inet_pton(posixSupport, AF_INET6.value, s2p("127.0.0.1")));
+ () -> posixSupport.inet_pton(AF_INET6.value, s2p("127.0.0.1")));
}
@Test
@@ -980,7 +973,7 @@ public void inet_pton_invalid_inet4() throws PosixException {
};
for (String src : addresses) {
try {
- lib.inet_pton(posixSupport, AF_INET.value, s2p(src));
+ posixSupport.inet_pton(AF_INET.value, s2p(src));
fail("inet_pton(AF_INET, \"" + src + "\") was expected to fail");
} catch (InvalidAddressException e) {
// expected
@@ -993,33 +986,33 @@ public void inet_pton_inet4_octal() {
// native inet_pton on darwin accepts leading zeroes (but handles them as decimal)
assumeTrue("java".equals(backendName) || runsOnLinux());
Assert.assertThrows(InvalidAddressException.class,
- () -> lib.inet_pton(posixSupport, AF_INET.value, s2p("1.2.010.4")));
+ () -> posixSupport.inet_pton(AF_INET.value, s2p("1.2.010.4")));
}
@Test
public void inet_ntop() throws PosixException {
- assertEquals("1.0.255.254", p2s(lib.inet_ntop(posixSupport, AF_INET.value, new byte[]{1, 0, -1, -2, -3})));
- assertThat(p2s(lib.inet_ntop(posixSupport, AF_INET6.value, new byte[]{-3, -2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4})),
+ assertEquals("1.0.255.254", p2s(posixSupport.inet_ntop(AF_INET.value, new byte[]{1, 0, -1, -2, -3})));
+ assertThat(p2s(posixSupport.inet_ntop(AF_INET6.value, new byte[]{-3, -2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4})),
anyOf(equalTo("fdfe:0:ff00::1:203"), equalTo("fdfe:0:ff00:0:0:0:1:203")));
- assertEquals("::ffff:127.0.0.1", p2s(lib.inet_ntop(posixSupport, AF_INET6.value, MAPPED_LOOPBACK)));
+ assertEquals("::ffff:127.0.0.1", p2s(posixSupport.inet_ntop(AF_INET6.value, MAPPED_LOOPBACK)));
}
@Test
public void inet_ntop_eafnosupport() {
expectErrno(() -> {
- lib.inet_ntop(posixSupport, AF_UNSPEC.value, new byte[16]);
+ posixSupport.inet_ntop(AF_UNSPEC.value, new byte[16]);
}, OSErrorEnum.EAFNOSUPPORT);
}
@Test
public void inet_ntop_len() {
Assert.assertThrows(IllegalArgumentException.class,
- () -> lib.inet_ntop(posixSupport, AF_INET6.value, new byte[15]));
+ () -> posixSupport.inet_ntop(AF_INET6.value, new byte[15]));
}
@Test
public void gethostname() throws PosixException {
- assertTrue(p2s(lib.gethostname(posixSupport)).length() > 0);
+ assertFalse(p2s(posixSupport.gethostname()).isEmpty());
}
private static FamilySpecificSockAddr localAddress(int family, int port) {
@@ -1030,13 +1023,13 @@ private static FamilySpecificSockAddr localAddress(int family, int port) {
}
}
- private int checkBound(int family, UniversalSockAddr usa) {
- assertEquals(family, usaLib.getFamily(usa));
+ private static int checkBound(int family, UniversalSockAddr usa) {
+ assertEquals(family, usa.getFamily());
int port;
if (family == AF_INET.value) {
- port = usaLib.asInet4SockAddr(usa).getPort();
+ port = usa.asInet4SockAddr().getPort();
} else if (family == AF_INET6.value) {
- port = usaLib.asInet6SockAddr(usa).getPort();
+ port = usa.asInet6SockAddr().getPort();
} else {
throw CompilerDirectives.shouldNotReachHere();
}
@@ -1045,26 +1038,23 @@ private int checkBound(int family, UniversalSockAddr usa) {
}
private void checkUsa(FamilySpecificSockAddr expectedAddr, UniversalSockAddr actualUsa) {
- if (expectedAddr instanceof Inet4SockAddr) {
- Inet4SockAddr expected = (Inet4SockAddr) expectedAddr;
- assertEquals(AF_INET.value, usaLib.getFamily(actualUsa));
- Inet4SockAddr actual = usaLib.asInet4SockAddr(actualUsa);
+ if (expectedAddr instanceof Inet4SockAddr expected) {
+ assertEquals(AF_INET.value, actualUsa.getFamily());
+ Inet4SockAddr actual = actualUsa.asInet4SockAddr();
assertEquals(expected.getPort(), actual.getPort());
assertEquals(expected.getAddress(), actual.getAddress());
- } else if (expectedAddr instanceof Inet6SockAddr) {
- Inet6SockAddr expected = (Inet6SockAddr) expectedAddr;
- assertEquals(AF_INET6.value, usaLib.getFamily(actualUsa));
- Inet6SockAddr actual = usaLib.asInet6SockAddr(actualUsa);
+ } else if (expectedAddr instanceof Inet6SockAddr expected) {
+ assertEquals(AF_INET6.value, actualUsa.getFamily());
+ Inet6SockAddr actual = actualUsa.asInet6SockAddr();
assertEquals(expected.getPort(), actual.getPort());
assertArrayEquals(expected.getAddress(), actual.getAddress());
assertEquals(expected.getScopeId(), actual.getScopeId());
if ("native".equals(backendName)) {
assertEquals(expected.getFlowInfo(), actual.getFlowInfo());
}
- } else if (expectedAddr instanceof UnixSockAddr) {
- UnixSockAddr expected = (UnixSockAddr) expectedAddr;
- assertEquals(AF_UNIX.value, usaLib.getFamily(actualUsa));
- UnixSockAddr actual = usaLib.asUnixSockAddr(actualUsa);
+ } else if (expectedAddr instanceof UnixSockAddr expected) {
+ assertEquals(AF_UNIX.value, actualUsa.getFamily());
+ UnixSockAddr actual = actualUsa.asUnixSockAddr();
assertNullTerminatedArrayEquals(expected.getPath(), actual.getPath());
} else {
fail("Unexpected subclass of FamilySpecificSockAddr: " + expectedAddr.getClass().getName());
@@ -1080,11 +1070,11 @@ private byte[] getNulTerminatedTempFileName() throws IOException {
}
private Object s2p(String s) {
- return lib.createCStringFromString(posixSupport, toTruffleStringUncached(s));
+ return PosixSupportNodes.CreateCStringFromStringNode.executeUncached(posixSupport, toTruffleStringUncached(s));
}
private String p2s(Object p) {
- return lib.getCStringAsString(posixSupport, p).toJavaStringUncached();
+ return PosixSupportNodes.GetCStringAsStringNode.executeUncached(posixSupport, p).toJavaStringUncached();
}
private static void expectErrno(ThrowingRunnable runnable, OSErrorEnum... expectedErrorCodes) {
@@ -1103,19 +1093,19 @@ private static void expectGetAddrInfoException(ThrowingRunnable runnable, Mandat
}
private int createSocket(int family, int type, int protocol) throws PosixException {
- int sockfd = lib.socket(posixSupport, family, type, protocol);
- cleanup.add(() -> lib.close(posixSupport, sockfd));
+ int sockfd = posixSupport.socket(family, type, protocol);
+ cleanup.add(() -> posixSupport.close(sockfd));
return sockfd;
}
private UniversalSockAddr createUsa(FamilySpecificSockAddr src) throws PosixException {
if (src instanceof Inet4SockAddr inet4SockAddr) {
- return lib.createUniversalSockAddrInet4(posixSupport, inet4SockAddr);
+ return posixSupport.createUniversalSockAddrInet4(inet4SockAddr);
} else if (src instanceof Inet6SockAddr inet6SockAddr) {
- return lib.createUniversalSockAddrInet6(posixSupport, inet6SockAddr);
+ return posixSupport.createUniversalSockAddrInet6(inet6SockAddr);
} else if (src instanceof UnixSockAddr unixSockAddr) {
try {
- return lib.createUniversalSockAddrUnix(posixSupport, unixSockAddr);
+ return posixSupport.createUniversalSockAddrUnix(unixSockAddr);
} catch (InvalidUnixSocketPathException e) {
assumeNoException(e);
return null; // unreachable
@@ -1127,14 +1117,14 @@ private UniversalSockAddr createUsa(FamilySpecificSockAddr src) throws PosixExce
private int getIntSockOpt(int socket, int level, int option) throws PosixException {
byte[] buf = new byte[4];
- assertEquals(4, lib.getsockopt(posixSupport, socket, level, option, buf, 4));
+ assertEquals(4, posixSupport.getsockopt(socket, level, option, buf, 4));
return nativeByteArraySupport().getInt(buf, 0);
}
private void setIntSockOpt(int socket, int level, int option, int value) throws PosixException {
byte[] buf = new byte[4];
nativeByteArraySupport().putInt(buf, 0, value);
- lib.setsockopt(posixSupport, socket, level, option, buf, 4);
+ posixSupport.setsockopt(socket, level, option, buf, 4);
}
private static ByteArraySupport nativeByteArraySupport() {
@@ -1182,77 +1172,77 @@ private class Socket {
}
void bind(FamilySpecificSockAddr sockAddr) throws PosixException {
- lib.bind(posixSupport, fd, createUsa(sockAddr));
+ posixSupport.bind(fd, createUsa(sockAddr));
}
void bindAny() throws PosixException {
if (family == AF_INET.value) {
- lib.bind(posixSupport, fd, createUsa(new Inet4SockAddr(0, INADDR_ANY.value)));
+ posixSupport.bind(fd, createUsa(new Inet4SockAddr(0, INADDR_ANY.value)));
} else if (family == AF_INET6.value) {
- lib.bind(posixSupport, fd, createUsa(new Inet6SockAddr(0, IN6ADDR_ANY, 0, 0)));
+ posixSupport.bind(fd, createUsa(new Inet6SockAddr(0, IN6ADDR_ANY, 0, 0)));
} else {
throw CompilerDirectives.shouldNotReachHere();
}
}
void connect(UniversalSockAddr addr) throws PosixException {
- lib.connect(posixSupport, fd, addr);
+ posixSupport.connect(fd, addr);
}
void listen(int backlog) throws PosixException {
- lib.listen(posixSupport, fd, backlog);
+ posixSupport.listen(fd, backlog);
}
UniversalSockAddr getpeername() throws PosixException {
- return lib.getpeername(posixSupport, fd);
+ return posixSupport.getpeername(fd);
}
UniversalSockAddr getsockname() throws PosixException {
- return lib.getsockname(posixSupport, fd);
+ return posixSupport.getsockname(fd);
}
void recv(byte[] expectedData, int flags) throws PosixException {
byte[] buf = new byte[expectedData.length * 2];
- assertEquals(expectedData.length, lib.recv(posixSupport, fd, buf, 0, buf.length, flags));
+ assertEquals(expectedData.length, posixSupport.recv(fd, buf, 0, buf.length, flags));
assertArrayEquals(expectedData, Arrays.copyOf(buf, expectedData.length));
}
UniversalSockAddr recvfrom(byte[] expectedData, int flags) throws PosixException {
byte[] buf = new byte[expectedData.length * 2];
- RecvfromResult recvfromResult = lib.recvfrom(posixSupport, fd, buf, 0, buf.length, flags);
+ RecvfromResult recvfromResult = posixSupport.recvfrom(fd, buf, 0, buf.length, flags);
assertEquals(expectedData.length, recvfromResult.readBytes);
assertArrayEquals(expectedData, Arrays.copyOf(buf, expectedData.length));
return recvfromResult.sockAddr;
}
void send(byte[] data, int flags) throws PosixException {
- assertEquals(data.length, lib.send(posixSupport, fd, data, 0, data.length, flags));
+ assertEquals(data.length, posixSupport.send(fd, data, 0, data.length, flags));
}
void sendto(byte[] data, int flags, UniversalSockAddr destAddr) throws PosixException {
- assertEquals(data.length, lib.sendto(posixSupport, fd, data, 0, data.length, flags, destAddr));
+ assertEquals(data.length, posixSupport.sendto(fd, data, 0, data.length, flags, destAddr));
}
void write(byte[] data) throws PosixException {
- assertEquals(data.length, lib.write(posixSupport, fd, Buffer.wrap(data)));
+ assertEquals(data.length, posixSupport.write(fd, Buffer.wrap(data)));
}
void read(byte[] expectedData) throws PosixException {
- Buffer buf = lib.read(posixSupport, fd, expectedData.length * 2);
+ Buffer buf = posixSupport.read(fd, expectedData.length * 2L);
assertEquals(expectedData.length, buf.length);
assertArrayEquals(expectedData, Arrays.copyOf(buf.data, expectedData.length));
}
void shutdown(int how) throws PosixException {
- lib.shutdown(posixSupport, fd, how);
+ posixSupport.shutdown(fd, how);
}
void setBlocking(boolean block) throws PosixException {
- lib.setBlocking(posixSupport, fd, block);
+ posixSupport.setBlocking(fd, block);
}
boolean getBlocking() throws PosixException {
- return lib.getBlocking(posixSupport, fd);
+ return posixSupport.getBlocking(fd);
}
FamilySpecificSockAddr address() throws PosixException {
@@ -1276,8 +1266,8 @@ private class Server extends Socket {
}
int acceptFd(FamilySpecificSockAddr expectedAddress) throws PosixException {
- AcceptResult acceptResult = lib.accept(posixSupport, fd);
- cleanup.add(() -> lib.close(posixSupport, acceptResult.socketFd));
+ AcceptResult acceptResult = posixSupport.accept(fd);
+ cleanup.add(() -> posixSupport.close(acceptResult.socketFd));
checkUsa(expectedAddress, acceptResult.sockAddr);
return acceptResult.socketFd;
}
@@ -1292,7 +1282,7 @@ private class InetServer extends Server {
if (type == SOCK_STREAM.value) {
listen(5);
}
- UniversalSockAddr boundUsa = lib.getsockname(posixSupport, fd);
+ UniversalSockAddr boundUsa = posixSupport.getsockname(fd);
port = checkBound(family, boundUsa);
}
}
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 a71acd9aad..a94b8c4eac 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
@@ -67,8 +67,9 @@
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.runtime.PosixSupportLibrary;
+import com.oracle.graal.python.runtime.PosixSupport;
import com.oracle.graal.python.runtime.PythonContext;
+import com.oracle.graal.python.nodes.util.PosixSupportNodes;
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.graal.python.test.PythonTests;
import com.oracle.graal.python.util.Function;
@@ -91,9 +92,8 @@ public static String[] params() {
public void setUp() {
org.junit.Assume.assumeTrue(backendName.equals("java") || !IS_WINDOWS);
PythonTests.enterContext(Collections.singletonMap("python.PosixModuleBackend", backendName), new String[0]);
- Object posixSupport = PythonContext.get(null).getPosixSupport();
- PosixSupportLibrary posixLib = PosixSupportLibrary.getUncached();
- pathToString = p -> posixLib.getPathAsString(posixSupport, p.value).toJavaStringUncached();
+ PosixSupport posixSupport = PythonContext.get(null).getPosixSupport();
+ pathToString = p -> PosixSupportNodes.GetPathAsStringNode.executeUncached(posixSupport, p.value).toJavaStringUncached();
}
@After
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 eedd1c10cd..26829283a7 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
@@ -147,6 +147,65 @@ class TypeWithAttrInDict:
NativeTypeWithAttr.attr = "str"
+class VectorcallMethodReceiver:
+ def combine(self, positional, *, keyword="default"):
+ return type(self).__name__, positional, keyword
+
+
+NativeTypeWithAttr.combine = VectorcallMethodReceiver.combine
+
+
+NativeVectorcallMethodReceiver = CPyExtHeapType(
+ "NativeVectorcallMethodReceiver",
+ code='''
+ static PyObject* native_combine(PyObject* self, PyObject* const* args,
+ Py_ssize_t nargs, PyObject* kwnames) {
+ PyObject* positional = PyTuple_New(nargs);
+ if (positional == NULL) {
+ return NULL;
+ }
+ for (Py_ssize_t i = 0; i < nargs; i++) {
+ PyTuple_SET_ITEM(positional, i, Py_NewRef(args[i]));
+ }
+ PyObject* keywords = PyDict_New();
+ if (keywords == NULL) {
+ Py_DECREF(positional);
+ return NULL;
+ }
+ if (kwnames != NULL) {
+ Py_ssize_t nkw = PyTuple_GET_SIZE(kwnames);
+ for (Py_ssize_t i = 0; i < nkw; i++) {
+ if (PyDict_SetItem(keywords, PyTuple_GET_ITEM(kwnames, i), args[nargs + i]) < 0) {
+ Py_DECREF(positional);
+ Py_DECREF(keywords);
+ return NULL;
+ }
+ }
+ }
+ PyObject* result = PyTuple_Pack(2, positional, keywords);
+ Py_DECREF(positional);
+ Py_DECREF(keywords);
+ return result;
+ }
+
+ static PyMethodDef native_methods[] = {
+ {"combine", (PyCFunction)(void(*)(void))native_combine, METH_FASTCALL | METH_KEYWORDS, NULL},
+ {NULL, NULL, 0, NULL}
+ };
+ ''',
+ slots=['{Py_tp_methods, native_methods}'],
+)
+
+
+class NativeVectorcallMethodSubclass(NativeVectorcallMethodReceiver):
+ pass
+
+
+native_vectorcall_method_shadowed = NativeVectorcallMethodSubclass()
+native_vectorcall_method_shadowed.combine = lambda positional, *, keyword="default": (
+ "shadowed", positional, keyword)
+
+
class DelAttrObject:
def __init__(self):
self.a = 1
@@ -401,6 +460,43 @@ def __hash__(self):
argspec="Oss",
callfunction="PyObject_CallMethod"
)
+ test_PyObject_VectorcallMethod = CPyExtFunction(
+ lambda args: getattr(args[0], args[1])(
+ args[2], **({} if args[3] is None else {"keyword": args[3]})),
+ lambda: (
+ (VectorcallMethodReceiver(), "combine", "managed-positional", "managed-keyword"),
+ (VectorcallMethodReceiver(), "combine", "managed-positional", None),
+ (NativeTypeWithAttr(), "combine", "native-positional", "native-keyword"),
+ (NativeTypeWithAttr(), "combine", "native-positional", None),
+ (NativeVectorcallMethodReceiver(), "combine", "native-method-positional", "native-method-keyword"),
+ (NativeVectorcallMethodReceiver(), "combine", "native-method-positional", None),
+ (native_vectorcall_method_shadowed, "combine", "shadowed-positional", "shadowed-keyword"),
+ ),
+ code='''
+ static PyObject* wrap_PyObject_VectorcallMethod(PyObject* receiver, PyObject* name,
+ PyObject* positional, PyObject* keyword_value) {
+ PyObject* args[3] = {receiver, positional, keyword_value};
+ PyObject* keyword_names = NULL;
+ if (keyword_value != Py_None) {
+ PyObject* keyword_name = PyUnicode_FromString("keyword");
+ if (keyword_name == NULL) {
+ return NULL;
+ }
+ keyword_names = PyTuple_Pack(1, keyword_name);
+ Py_DECREF(keyword_name);
+ if (keyword_names == NULL) {
+ return NULL;
+ }
+ }
+ PyObject* result = PyObject_VectorcallMethod(name, args, 2, keyword_names);
+ Py_XDECREF(keyword_names);
+ return result;
+ }
+ ''',
+ arguments=["PyObject* receiver", "PyObject* name", "PyObject* positional", "PyObject* keyword_value"],
+ argspec="OOOO",
+ callfunction="wrap_PyObject_VectorcallMethod",
+ )
test_PyObject_Type = CPyExtFunction(
type,
lambda: (
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 8f05308339..43240045a9 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
@@ -92,6 +92,135 @@ def __getattribute__(self, key):
class TestObject(unittest.TestCase):
+ def test_get_method_keeps_method_descriptors_unbound(self):
+ module = compile_module_from_string(
+ """
+ #include
+
+ PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *, PyObject *, PyObject **);
+
+ static PyObject* native_descriptor_call(PyObject* self, PyObject* args, PyObject* kwargs) {
+ if (PyTuple_GET_SIZE(args) != 1 || (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0)) {
+ PyErr_SetString(PyExc_TypeError, "expected exactly one positional argument");
+ return NULL;
+ }
+ return Py_NewRef(PyTuple_GET_ITEM(args, 0));
+ }
+
+ static PyObject* native_descriptor_get(PyObject* self, PyObject* obj, PyObject* type) {
+ if (obj == NULL || obj == Py_None) {
+ return Py_NewRef(self);
+ }
+ return PyMethod_New(self, obj);
+ }
+
+ static PyTypeObject NativeMethodDescriptor_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "test_get_method.NativeMethodDescriptor",
+ .tp_basicsize = sizeof(PyObject),
+ .tp_call = native_descriptor_call,
+ .tp_descr_get = native_descriptor_get,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_METHOD_DESCRIPTOR,
+ };
+
+ static PyObject* get_method(PyObject* self, PyObject* args) {
+ PyObject* obj;
+ PyObject* name;
+ if (!PyArg_ParseTuple(args, "OO:get_method", &obj, &name)) {
+ return NULL;
+ }
+ PyObject* method = NULL;
+ int is_method = _PyObject_GetMethod(obj, name, &method);
+ if (method == NULL) {
+ return NULL;
+ }
+ PyObject* result = PyTuple_New(2);
+ if (result == NULL) {
+ Py_DECREF(method);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, 0, PyBool_FromLong(is_method));
+ PyTuple_SET_ITEM(result, 1, method);
+ return result;
+ }
+
+ static PyMethodDef methods[] = {
+ {"get_method", get_method, METH_VARARGS, NULL},
+ {NULL, NULL, 0, NULL}
+ };
+
+ static struct PyModuleDef module = {
+ PyModuleDef_HEAD_INIT, "test_get_method", NULL, -1, methods
+ };
+
+ PyMODINIT_FUNC PyInit_test_get_method(void) {
+ if (PyType_Ready(&NativeMethodDescriptor_Type) < 0) {
+ return NULL;
+ }
+ PyObject* m = PyModule_Create(&module);
+ if (m == NULL) {
+ return NULL;
+ }
+ PyObject* descriptor = NativeMethodDescriptor_Type.tp_alloc(&NativeMethodDescriptor_Type, 0);
+ if (descriptor == NULL || PyModule_AddObject(m, "native_method_descriptor", descriptor) < 0) {
+ Py_XDECREF(descriptor);
+ Py_DECREF(m);
+ return NULL;
+ }
+ return m;
+ }
+ """,
+ "test_get_method",
+ )
+
+ class C:
+ def method(self):
+ return self
+
+ obj = C()
+ is_method, method = module.get_method(obj, "method")
+ assert is_method is True
+ assert method(obj) is obj
+
+ Native = CPyExtType(
+ "GetMethodNative",
+ """
+ static PyObject* get_self(PyObject* self, PyObject* unused) {
+ return Py_NewRef(self);
+ }
+ """,
+ tp_methods='{"get_self", (PyCFunction)get_self, METH_NOARGS, ""}',
+ )
+ native_obj = Native()
+ is_method, method = module.get_method(native_obj, "get_self")
+ assert is_method is True
+ assert method(native_obj) is native_obj
+
+ class WithNativeMethodDescriptor:
+ native_method_descriptor = module.native_method_descriptor
+
+ native_descriptor_obj = WithNativeMethodDescriptor()
+ is_method, method = module.get_method(native_descriptor_obj, "native_method_descriptor")
+ assert is_method is True
+ assert method is module.native_method_descriptor
+ assert method(native_descriptor_obj) is native_descriptor_obj
+ assert native_descriptor_obj.native_method_descriptor() is native_descriptor_obj
+
+ obj.method = lambda: "instance attribute"
+ is_method, method = module.get_method(obj, "method")
+ assert is_method is False
+ assert method() == "instance attribute"
+
+ class WithGetAttribute:
+ def __getattribute__(self, name):
+ if name == "method":
+ return lambda: "custom getattribute"
+ return object.__getattribute__(self, name)
+
+ is_method, method = module.get_method(WithGetAttribute(), "method")
+ assert is_method is False
+ assert method() == "custom getattribute"
+
def test_iter_dict_before_getattr_property(self):
module = compile_module_from_string(
"""
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 2b6132af44..da45148006 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
@@ -1670,6 +1670,57 @@ def __call__(self, *args, **kwargs):
assert obj.__call__({'b': 2}, a=1) == {'a': 1, 'b': 2}
+def test_native_vectorcall():
+ NativeVectorcall = CPyExtType(
+ name='NativeVectorcall',
+ cmembers='vectorcallfunc vectorcall;',
+ code=r'''
+ static PyObject* native_vectorcall(PyObject* self, PyObject* const* args, size_t nargsf, PyObject* kwnames) {
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ Py_ssize_t nkwargs = kwnames ? PyTuple_GET_SIZE(kwnames) : 0;
+ PyObject* positional = PyTuple_New(nargs);
+ PyObject* keywords = PyDict_New();
+ if (!positional || !keywords) {
+ Py_XDECREF(positional);
+ Py_XDECREF(keywords);
+ return NULL;
+ }
+ for (Py_ssize_t i = 0; i < nargs; i++) {
+ Py_INCREF(args[i]);
+ PyTuple_SET_ITEM(positional, i, args[i]);
+ }
+ for (Py_ssize_t i = 0; i < nkwargs; i++) {
+ if (PyDict_SetItem(keywords, PyTuple_GET_ITEM(kwnames, i), args[nargs + i]) < 0) {
+ Py_DECREF(positional);
+ Py_DECREF(keywords);
+ return NULL;
+ }
+ }
+ return Py_BuildValue("NN", positional, keywords);
+ }
+
+ static PyObject* native_tp_call(PyObject* self, PyObject* args, PyObject* kwargs) {
+ return PyUnicode_FromString("tp_call");
+ }
+
+ static PyObject* native_vectorcall_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
+ NativeVectorcallObject* self = (NativeVectorcallObject*)type->tp_alloc(type, 0);
+ if (self) {
+ self->vectorcall = native_vectorcall;
+ }
+ return (PyObject*)self;
+ }
+ ''',
+ tp_flags='Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL',
+ tp_vectorcall_offset='offsetof(NativeVectorcallObject, vectorcall)',
+ tp_call='native_tp_call',
+ tp_new='native_vectorcall_new',
+ )
+
+ callable_obj = NativeVectorcall()
+ assert callable_obj(1, 2, keyword=3) == ((1, 2), {'keyword': 3})
+
+
def test_richcmp():
MyNativeIntSubType = CPyExtType("MyNativeIntSubTypeForRichCmpTest",
ready_code = "MyNativeIntSubTypeForRichCmpTestType.tp_new = PyLong_Type.tp_new;",
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 643e8d2cde..3ef5a5b2eb 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
@@ -9,6 +9,33 @@
from tests import util
+class AsyncGeneratorTest(unittest.TestCase):
+ def test_aclose_await_in_finally(self):
+ resumed = []
+
+ class Suspend:
+ def __await__(self):
+ return (yield "suspended")
+
+ async def gen():
+ try:
+ yield 1
+ finally:
+ resumed.append(await Suspend())
+
+ g = gen()
+ with self.assertRaises(StopIteration) as cm:
+ g.__anext__().send(None)
+ self.assertEqual(cm.exception.value, 1)
+
+ close = g.aclose()
+ self.assertEqual(close.send(None), "suspended")
+ self.assertEqual(resumed, [])
+ with self.assertRaises(StopIteration):
+ close.send(42)
+ self.assertEqual(resumed, [42])
+
+
class ExceptionTest(unittest.TestCase):
# Tests for the issue #23353: check that the currently handled exception
# is correctly saved/restored in PyEval_EvalFrameEx().
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_pwd.py b/graalpython/com.oracle.graal.python.test/src/tests/test_pwd.py
new file mode 100644
index 0000000000..54cddc373e
--- /dev/null
+++ b/graalpython/com.oracle.graal.python.test/src/tests/test_pwd.py
@@ -0,0 +1,180 @@
+# Copyright (c) 2026, Oracle and/or 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 shlex
+import shutil
+import subprocess
+import sys
+import tempfile
+import textwrap
+import unittest
+
+from tests.util import run_subprocess_with_graalpy_startup_retry
+
+
+POSIX_BACKEND_IS_JAVA = sys.implementation.name == "graalpy" and __graalpython__.posix_module_backend() == "java"
+
+
+@unittest.skipUnless(sys.platform == "linux", "requires Linux LD_PRELOAD")
+@unittest.skipIf(POSIX_BACKEND_IS_JAVA, "requires native password database lookups")
+class PwdLookupErrorTests(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ compiler = shlex.split(os.environ.get("CC", "cc"))
+ if not compiler or shutil.which(compiler[0]) is None:
+ raise unittest.SkipTest("requires a C compiler")
+ temporary_directory = tempfile.TemporaryDirectory()
+ cls.addClassCleanup(temporary_directory.cleanup)
+ source = os.path.join(temporary_directory.name, "pwd_lookup_error.c")
+ cls.library = os.path.join(temporary_directory.name, "pwd_lookup_error.so")
+ # Inject the libc error itself, so the test exercises the real pwd builtin
+ # and native POSIX backend without touching the host password database.
+ with open(source, "w") as f:
+ f.write(textwrap.dedent("""\
+ #include
+ #include
+ #include
+ #include
+
+ static int retry_count;
+
+ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer,
+ size_t buffer_size, struct passwd **result) {
+ *result = NULL;
+ if (uid == 2147483646) {
+ if (retry_count++ == 0) {
+ return ERANGE;
+ }
+ const char data[] = "graalpy_test_user\\0/home/graalpy_test_user\\0/bin/sh";
+ if (buffer_size < sizeof(data)) {
+ return ERANGE;
+ }
+ memcpy(buffer, data, sizeof(data));
+ pwd->pw_name = buffer;
+ pwd->pw_dir = buffer + strlen(buffer) + 1;
+ pwd->pw_shell = pwd->pw_dir + strlen(pwd->pw_dir) + 1;
+ pwd->pw_uid = uid;
+ pwd->pw_gid = uid;
+ pwd->pw_passwd = "x";
+ pwd->pw_gecos = "";
+ *result = pwd;
+ return 0;
+ }
+ errno = ENOENT;
+ return ENOENT;
+ }
+
+ int getpwnam_r(const char *name, struct passwd *pwd, char *buffer,
+ size_t buffer_size, struct passwd **result) {
+ *result = NULL;
+ errno = ENOENT;
+ return ENOENT;
+ }
+ """))
+ result = subprocess.run(
+ [*compiler, "-shared", "-fPIC", source, "-o", cls.library],
+ capture_output=True, text=True, timeout=60,
+ )
+ if result.returncode:
+ raise AssertionError(f"Could not compile password lookup shim:\n{result.stdout}\n{result.stderr}")
+
+ def run_child(self, code, *, no_site=True):
+ env = os.environ.copy()
+ env.pop("HOME", None)
+ env.pop("PYTHONUSERBASE", None)
+ env.pop("PYTHONNOUSERSITE", None)
+ env["LD_PRELOAD"] = self.library + (" " + env["LD_PRELOAD"] if env.get("LD_PRELOAD") else "")
+ args = [sys.executable]
+ if no_site:
+ args.append("-S")
+ args.extend(["-c", textwrap.dedent(code)])
+ result = run_subprocess_with_graalpy_startup_retry(args, env=env, text=True, timeout=60)
+ self.assertEqual(result.returncode, 0, f"{result.stdout}\n{result.stderr}")
+
+ def test_getpwuid_lookup_error_is_keyerror(self):
+ self.run_child("""\
+ import os
+ import pwd
+
+ try:
+ pwd.getpwuid(os.getuid())
+ except KeyError:
+ pass
+ else:
+ raise AssertionError("Expected KeyError for a failed password database lookup")
+ """)
+
+ def test_getpwuid_retries_erange(self):
+ self.run_child("""\
+ import pwd
+
+ entry = pwd.getpwuid(2147483646)
+ assert entry.pw_name == "graalpy_test_user", entry
+ assert entry.pw_dir == "/home/graalpy_test_user", entry
+ assert entry.pw_shell == "/bin/sh", entry
+ assert entry.pw_uid == 2147483646, entry
+ """)
+
+ def test_getpwnam_lookup_error_is_keyerror(self):
+ self.run_child("""\
+ import pwd
+
+ try:
+ pwd.getpwnam("graalpy_test_user")
+ except KeyError:
+ pass
+ else:
+ raise AssertionError("Expected KeyError for a failed password database lookup")
+ """)
+
+ def test_expanduser_with_lookup_error(self):
+ self.run_child("""\
+ import os
+
+ assert os.path.expanduser("~/.local") == "~/.local"
+ """)
+
+ def test_site_startup_with_lookup_error(self):
+ # No -S: exercise automatic site initialization before the script runs.
+ self.run_child("""\
+ import site
+
+ assert site.getuserbase() == "~/.local", site.getuserbase()
+ """, no_site=False)
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_sysconfig.py b/graalpython/com.oracle.graal.python.test/src/tests/test_sysconfig.py
index fdf49f6847..1434e5a962 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/test_sysconfig.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/test_sysconfig.py
@@ -60,6 +60,18 @@ def test_platform_sysconfigdata():
assert sys.abiflags in sysconfig.get_config_var("INCLUDEPY")
+@unittest.skipIf(sys.platform == "win32", "Windows has no system time zone database")
+def test_tzpath_searches_system_time_zones():
+ import sysconfig
+ tzpath = sysconfig.get_config_var("TZPATH")
+ assert tzpath == "/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo", tzpath
+ import os
+ import subprocess
+ env = {k: v for k, v in os.environ.items() if k != "PYTHONTZPATH"}
+ out = subprocess.check_output([sys.executable, "-c", "import zoneinfo; print(':'.join(zoneinfo.TZPATH))"], env=env, text=True)
+ assert out.strip() == tzpath, out
+
+
@unittest.skipUnless(sys.platform == "win32", "Windows-specific sysconfig behavior")
def test_windows_libpython_is_not_exposed():
import sysconfig
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 e3259b3eec..5e63c3f0e5 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
@@ -14,8 +14,12 @@ test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_aiter_class @ darwin-arm64
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_01 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_02 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_03 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_aclose_06 @ linux-x86_64
+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_aclose_07 @ linux-x86_64
+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_aclose_08 @ linux-x86_64
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_aclose_10 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_aclose_11 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_aclose_12 @ linux-x86_64
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_anext_04 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_anext_05 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_anext_06 @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
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 d9183e9829..6de50c6cd2 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
@@ -190,13 +190,18 @@ test.test_asyncio.test_events.PollEventLoopTests.test_run_until_complete @ darwi
test.test_asyncio.test_events.PollEventLoopTests.test_run_until_complete_stopped @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_asyncio.test_events.PollEventLoopTests.test_server_close @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_asyncio.test_events.PollEventLoopTests.test_ssl_connect_accepted_socket @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.test_asyncio.test_events.PollEventLoopTests.test_subprocess_close_after_finish @ linux-aarch64-github,linux-x86_64-github
+# test_subprocess_close_after_finish, test_subprocess_wait_no_same_group (and the already excluded
+# test_subprocess_exitcode) hang until the 600s timeout on the linux-amd64 and linux-aarch64 GitHub
+# runners, and the first also fails in upstream's GitHub Actions runs. Root cause: they wait for a
+# subprocess with no pipes, so only the SIGCHLD handler can wake the event loop, but
+# signal.set_wakeup_fd is a stub in GraalPy and the handler never runs while the main thread is
+# blocked in poll() unless the kernel happens to deliver the signal to that thread. A real
+# implementation is in progress on branch fix/signal-set-wakeup-fd.
test.test_asyncio.test_events.PollEventLoopTests.test_subprocess_exec_invalid_args @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
# GR-80225
!test.test_asyncio.test_events.PollEventLoopTests.test_subprocess_exitcode @ darwin-arm64,linux-aarch64-github
!test.test_asyncio.test_events.PollEventLoopTests.test_subprocess_shell @ linux-aarch64-github,linux-x86_64
test.test_asyncio.test_events.PollEventLoopTests.test_subprocess_shell_invalid_args @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.test_asyncio.test_events.PollEventLoopTests.test_subprocess_wait_no_same_group @ linux-aarch64-github
test.test_asyncio.test_events.PollEventLoopTests.test_timeout_rounding @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_asyncio.test_events.PollEventLoopTests.test_unclosed_pipe_transport @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_asyncio.test_events.PollEventLoopTests.test_write_pipe @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_datetime.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_datetime.txt
index 577d7e5728..1d87d58c54 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_datetime.txt
+++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_datetime.txt
@@ -1038,10 +1038,13 @@ test.datetimetester.ZoneInfoTest[Africa/Cairo]_Pure.test_gaps @ darwin-arm64,dar
test.datetimetester.ZoneInfoTest[Africa/Cairo]_Pure.test_system_transitions @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Fast.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Fast.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Fast.test_system_transitions @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64
+# The system-transition checks for the zones below compare the OS tzdata (/usr/share/zoneinfo)
+# with the JDK tz rules that back time.localtime; they fail on the self-hosted GitHub runners
+# whose tzdata (2026c) is newer than the labsjdk's, so they are not expected on the *-github tag sets.
+test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Fast.test_system_transitions @ darwin-arm64,linux-aarch64,linux-x86_64
test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Pure.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Pure.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Pure.test_system_transitions @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64
+test.datetimetester.ZoneInfoTest[Africa/Casablanca]_Pure.test_system_transitions @ darwin-arm64,linux-aarch64,linux-x86_64
test.datetimetester.ZoneInfoTest[Africa/Ceuta]_Fast.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Ceuta]_Fast.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Ceuta]_Fast.test_system_transitions @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
@@ -1084,10 +1087,10 @@ test.datetimetester.ZoneInfoTest[Africa/Douala]_Pure.test_gaps @ darwin-arm64,da
test.datetimetester.ZoneInfoTest[Africa/Douala]_Pure.test_system_transitions @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Fast.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Fast.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Fast.test_system_transitions @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64
+test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Fast.test_system_transitions @ darwin-arm64,linux-aarch64,linux-x86_64
test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Pure.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Pure.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Pure.test_system_transitions @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64
+test.datetimetester.ZoneInfoTest[Africa/El_Aaiun]_Pure.test_system_transitions @ darwin-arm64,linux-aarch64,linux-x86_64
test.datetimetester.ZoneInfoTest[Africa/Freetown]_Fast.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Freetown]_Fast.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[Africa/Freetown]_Fast.test_system_transitions @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64
@@ -1592,11 +1595,11 @@ test.datetimetester.ZoneInfoTest[America/Dominica]_Pure.test_gaps @ darwin-arm64
test.datetimetester.ZoneInfoTest[America/Dominica]_Pure.test_system_transitions @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[America/Edmonton]_Fast.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[America/Edmonton]_Fast.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.datetimetester.ZoneInfoTest[America/Edmonton]_Fast.test_system_transitions @ linux-aarch64,linux-aarch64-github,linux-x86_64
+test.datetimetester.ZoneInfoTest[America/Edmonton]_Fast.test_system_transitions @ linux-aarch64,linux-x86_64
!test.datetimetester.ZoneInfoTest[America/Edmonton]_Fast.test_system_transitions @ darwin-arm64
test.datetimetester.ZoneInfoTest[America/Edmonton]_Pure.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[America/Edmonton]_Pure.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.datetimetester.ZoneInfoTest[America/Edmonton]_Pure.test_system_transitions @ linux-aarch64,linux-aarch64-github,linux-x86_64
+test.datetimetester.ZoneInfoTest[America/Edmonton]_Pure.test_system_transitions @ linux-aarch64,linux-x86_64
!test.datetimetester.ZoneInfoTest[America/Edmonton]_Pure.test_system_transitions @ darwin-arm64
test.datetimetester.ZoneInfoTest[America/Eirunepe]_Fast.test_folds @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.datetimetester.ZoneInfoTest[America/Eirunepe]_Fast.test_gaps @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
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 9e9e08893b..e8b63d57ff 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
@@ -60,7 +60,8 @@ test.test_multiprocessing_spawn.test_manager.WithManagerTestSemaphore.test_bound
test.test_multiprocessing_spawn.test_manager.WithManagerTestSemaphore.test_semaphore @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64-github
test.test_multiprocessing_spawn.test_misc.ChallengeResponseTest.test_challengeresponse @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_multiprocessing_spawn.test_misc.MiscTestCase.test__all__ @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
-test.test_multiprocessing_spawn.test_misc.MiscTestCase.test_large_pool @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64-github
+# GR-80580
+!test.test_multiprocessing_spawn.test_misc.MiscTestCase.test_large_pool @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64-github
test.test_multiprocessing_spawn.test_misc.MiscTestCase.test_spawn_sys_executable_none_allows_import @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_multiprocessing_spawn.test_misc.OtherTest.test_answer_challenge_auth_failure @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
test.test_multiprocessing_spawn.test_misc.OtherTest.test_deliver_challenge_auth_failure @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64,win32-AMD64-github
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_os.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_os.txt
index 12bb472039..9bf9d69335 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_os.txt
+++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_os.txt
@@ -81,7 +81,8 @@ test.test_os.FileTests.test_symlink_keywords @ darwin-arm64,linux-aarch64,linux-
test.test_os.FileTests.test_write @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github,win32-AMD64-github
test.test_os.FwalkTests.test_compare_to_walk @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_os.FwalkTests.test_dir_fd @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
-test.test_os.FwalkTests.test_fd_finalization @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
+# Assumes stable lowest available FD; unrelated asynchronous finalizers can close descriptors between probes.
+!test.test_os.FwalkTests.test_fd_finalization
test.test_os.FwalkTests.test_fd_leak @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_os.FwalkTests.test_file_like_path @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
test.test_os.FwalkTests.test_walk_above_recursion_limit @ darwin-arm64,linux-aarch64,linux-aarch64-github,linux-x86_64,linux-x86_64-github
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 25f73178cd..54ddb4c584 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
@@ -27,7 +27,7 @@
import static com.oracle.graal.python.annotations.PythonOS.PLATFORM_WIN32;
import static com.oracle.graal.python.nodes.BuiltinNames.T__SIGNAL;
-import static com.oracle.graal.python.nodes.StringLiterals.T_PY_EXTENSION;
+import static com.oracle.graal.python.nodes.StringLiterals.J_PY_EXTENSION;
import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.isJavaString;
import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR;
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
@@ -103,9 +103,8 @@
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.WindowsVersion;
+import com.oracle.graal.python.runtime.PosixSupport.PosixException;
+import com.oracle.graal.python.runtime.PosixSupport.WindowsVersion;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
import com.oracle.graal.python.runtime.PythonImageBuildOptions;
@@ -304,7 +303,7 @@ public static PlatformInfo getPlatformInfo() {
public static final String MIME_TYPE = "text/x-python";
- public static final TruffleString[] T_DEFAULT_PYTHON_EXTENSIONS = new TruffleString[]{T_PY_EXTENSION, tsLiteral(".pyc")};
+ public static final String[] T_DEFAULT_PYTHON_EXTENSIONS = new String[]{J_PY_EXTENSION, ".pyc"};
public static final TruffleLogger LOGGER = TruffleLogger.getLogger(ID, PythonLanguage.class);
@@ -910,7 +909,7 @@ public static Source newSource(PythonContext ctxt, TruffleString tsrc, TruffleSt
String src = tsrc.toJavaStringUncached();
if (mayBeFile) {
try {
- TruffleFile truffleFile = ctxt.getPublicTruffleFileRelaxed(name, PythonLanguage.T_DEFAULT_PYTHON_EXTENSIONS);
+ TruffleFile truffleFile = ctxt.getPublicTruffleFileRelaxed(name.toJavaStringUncached(), PythonLanguage.T_DEFAULT_PYTHON_EXTENSIONS);
if (truffleFile.exists()) {
// XXX: (tfel): We don't know if the expression has anything to do with the
// filename that's given. We would really have to compare the entire
@@ -1075,7 +1074,7 @@ public WindowsVersion getWindowsVersion(Node node) {
CompilerDirectives.transferToInterpreterAndInvalidate();
assert !ImageInfo.inImageBuildtimeCode();
try {
- windowsVersion = PosixSupportLibrary.getUncached().getWindowsVersion(PythonContext.get(node).getPosixSupport());
+ windowsVersion = PythonContext.get(node).getPosixSupport().getWindowsVersion();
} catch (PosixException e) {
EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent();
Node previousNode = encapsulating.set(node);
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 80d97b5b94..0269286bc3 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
@@ -179,6 +179,7 @@
import com.oracle.graal.python.builtins.modules.io.BufferedWriterBuiltins;
import com.oracle.graal.python.builtins.modules.io.BufferedWriterMixinBuiltins;
import com.oracle.graal.python.builtins.modules.io.BytesIOBuiltins;
+import com.oracle.graal.python.builtins.modules.io.CommonFileIOBuiltins;
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.IOBaseDictBuiltins;
@@ -188,6 +189,7 @@
import com.oracle.graal.python.builtins.modules.io.StringIOBuiltins;
import com.oracle.graal.python.builtins.modules.io.TextIOBaseBuiltins;
import com.oracle.graal.python.builtins.modules.io.TextIOWrapperBuiltins;
+import com.oracle.graal.python.builtins.modules.io.WindowsConsoleIOBuiltins;
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;
@@ -632,7 +634,9 @@ private static PythonBuiltins[] initializeBuiltins(TruffleLanguage.Env env) {
new BufferedReaderMixinBuiltins(),
new BufferedWriterMixinBuiltins(),
new BufferedIOMixinBuiltins(),
+ new CommonFileIOBuiltins(),
new FileIOBuiltins(),
+ new WindowsConsoleIOBuiltins(),
new TextIOWrapperBuiltins(),
new IncrementalNewlineDecoderBuiltins(),
new BufferedRWPairBuiltins(),
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 416b1ccd48..a96555806d 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
@@ -120,6 +120,7 @@
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.io.WindowsConsoleIOBuiltins;
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;
@@ -921,7 +922,7 @@ It can be called either on the class (e.g. C.f()) or on an instance
"BufferedRandom",
PBufferedIOBase,
newBuilder().publishInModule("_io").basetype().addDict().slots(BufferedReaderMixinBuiltins.SLOTS, BufferedIOMixinBuiltins.SLOTS, BufferedRandomBuiltins.SLOTS)),
- PWindowsConsoleIO("_WindowsConsoleIO", PRawIOBase, newBuilder().moduleName("_io").basetype()),
+ PWindowsConsoleIO("_WindowsConsoleIO", PRawIOBase, newBuilder().moduleName("_io").basetype().addDict().slots(WindowsConsoleIOBuiltins.SLOTS)),
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)),
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 aa7a0cec47..561fa5222b 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -409,10 +409,11 @@ abstract static class Crc32Node extends PythonBinaryClinicBuiltinNode {
@Specialization(limit = "3")
static long b2a(VirtualFrame frame, Object buffer, long crc,
+ @Bind Node inliningTarget,
@Cached("createFor($node)") InteropCallData callData,
@CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) {
try {
- return crc32((int) crc, bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer));
+ return crc32(inliningTarget, (int) crc, bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer));
} finally {
bufferLib.release(buffer, frame, callData);
}
@@ -432,10 +433,11 @@ abstract static class CrcHqxNode extends PythonBinaryClinicBuiltinNode {
@Specialization(limit = "3")
static long b2a(VirtualFrame frame, Object buffer, long crc,
+ @Bind Node inliningTarget,
@Cached("createFor($node)") InteropCallData callData,
@CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) {
try {
- return crcHqx((int) crc, bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer));
+ return crcHqx(inliningTarget, (int) crc, bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer));
} finally {
bufferLib.release(buffer, frame, callData);
}
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 51ac7a8a55..cd369906d2 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
@@ -269,7 +269,6 @@
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonOptions;
import com.oracle.graal.python.runtime.exception.PException;
@@ -1609,6 +1608,7 @@ static PNone printAllGiven(VirtualFrame frame, Object[] values, TruffleString se
callWrite.execute(frame, writeMethod, strNode.execute(frame, inliningTarget, values[i]));
callWrite.execute(frame, writeMethod, sep);
}
+ LoopNode.reportLoopCount(inliningTarget, values.length == 0 ? 0 : values.length - 1);
if (lastValue >= 0) {
callWrite.execute(frame, writeMethod, strNode.execute(frame, inliningTarget, values[lastValue]));
}
@@ -2480,7 +2480,7 @@ private static Object doInput(Object prompt, Node node, PythonContext context) {
try {
long fileno = PyLongAsLongNode.executeUncached(PyObjectCallMethodObjArgs.executeUncached(stdin, T_FILENO));
if (fileno == 0) {
- tty = PosixSupportLibrary.getUncached().isatty(context.getPosixSupport(), 0);
+ tty = context.getPosixSupport().isatty(0);
}
} catch (AbstractTruffleException e) {
// not a tty
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 2dabf1adad..188e65f357 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
@@ -150,6 +150,7 @@
import com.oracle.truffle.api.frame.Frame;
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.InlinedConditionProfile;
import com.oracle.truffle.api.strings.TruffleString;
@@ -779,8 +780,9 @@ static PTuple lookup(VirtualFrame frame, Node inliningTarget, TruffleString enco
}
} else {
Object[] searchPaths = getSearchPaths(context);
- for (Object func : searchPaths) {
- Object obj = callNode.executeObject(frame, func, normalizedEncoding);
+ int i = 0;
+ for (; i < searchPaths.length; i++) {
+ Object obj = callNode.executeObject(frame, searchPaths[i], normalizedEncoding);
if (obj != PNone.NONE) {
if (isTupleProfile.profile(inliningTarget, !isTupleInstanceCheck(frame, inliningTarget, obj, 4, typeCheck, sizeNode))) {
throw raiseNode.raise(inliningTarget, TypeError, CODEC_SEARCH_MUST_RETURN_4);
@@ -789,6 +791,7 @@ static PTuple lookup(VirtualFrame frame, Node inliningTarget, TruffleString enco
break;
}
}
+ LoopNode.reportLoopCount(inliningTarget, i);
}
if (result != null) {
putSearchPath(context, normalizedEncoding, result);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FaulthandlerModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FaulthandlerModuleBuiltins.java
index bccac49aa9..0c6321b671 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FaulthandlerModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FaulthandlerModuleBuiltins.java
@@ -86,8 +86,8 @@
import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext;
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
+import com.oracle.graal.python.runtime.PosixSupport;
+import com.oracle.graal.python.runtime.PosixSupport.PosixException;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonOptions;
import com.oracle.graal.python.runtime.exception.ExceptionUtils;
@@ -104,7 +104,6 @@
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.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.strings.TruffleString;
@@ -281,10 +280,9 @@ abstract static class SigSegvNode extends PythonUnaryClinicBuiltinNode {
static PNone doIt(VirtualFrame frame, boolean releaseGil,
@Bind PythonContext context,
@Bind Node inliningTarget,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
- return raiseFatalSignal(frame, context, inliningTarget, posixLib, gil, constructAndRaiseNode, "SEGV", releaseGil);
+ return raiseFatalSignal(frame, context, inliningTarget, gil, constructAndRaiseNode, "SEGV", releaseGil);
}
@Override
@@ -300,14 +298,13 @@ abstract static class SigAbrtNode extends PythonBuiltinNode {
static PNone doIt(VirtualFrame frame,
@Bind PythonContext context,
@Bind Node inliningTarget,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
- return raiseFatalSignal(frame, context, inliningTarget, posixLib, gil, constructAndRaiseNode, "ABRT", false);
+ return raiseFatalSignal(frame, context, inliningTarget, gil, constructAndRaiseNode, "ABRT", false);
}
}
- private static PNone raiseFatalSignal(VirtualFrame frame, PythonContext context, Node inliningTarget, PosixSupportLibrary posixLib, GilNode gil,
+ private static PNone raiseFatalSignal(VirtualFrame frame, PythonContext context, Node inliningTarget, GilNode gil,
PConstructAndRaiseNode.Lazy constructAndRaiseNode, String signalName, boolean releaseGil) {
try {
int signum = SignalModuleBuiltins.signalFromName(context, signalName);
@@ -315,7 +312,7 @@ private static PNone raiseFatalSignal(VirtualFrame frame, PythonContext context,
gil.release(true);
}
try {
- posixLib.signalSelf(context.getPosixSupport(), signum);
+ context.getPosixSupport().signalSelf(signum);
} finally {
if (releaseGil) {
gil.acquire();
@@ -408,8 +405,8 @@ public void write(int b) {
public void flush() throws IOException {
super.flush();
try {
- PosixSupportLibrary.getUncached().write(PythonContext.get(null).getPosixSupport(), fd, PosixSupportLibrary.Buffer.wrap(bb.toArray()));
- } catch (PosixSupportLibrary.PosixException e) {
+ PythonContext.get(null).getPosixSupport().write(fd, PosixSupport.Buffer.wrap(bb.toArray()));
+ } catch (PosixSupport.PosixException e) {
// Ignore
}
}
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 caca032aba..efd562580e 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
@@ -80,8 +80,7 @@
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
import com.oracle.graal.python.runtime.PosixConstants;
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.PosixSupport.PosixException;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.exception.PException;
import com.oracle.graal.python.runtime.object.PFactory;
@@ -135,11 +134,10 @@ protected ArgumentClinicProvider getArgumentClinic() {
synchronized PNone flock(VirtualFrame frame, int fd, int operation,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posix,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_FCNTL_FLOCK, fd, operation);
try {
- posix.flock(getPosixSupport(), fd, operation);
+ getPosixSupport().flock(fd, operation);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -157,7 +155,6 @@ abstract static class LockfNode extends PythonClinicBuiltinNode {
PNone lockf(VirtualFrame frame, int fd, int code, Object lenObj, Object startObj, int whence,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posix,
@Cached PyLongAsLongNode asLongNode,
@Cached PRaiseNode raiseNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
@@ -181,7 +178,7 @@ PNone lockf(VirtualFrame frame, int fd, int code, Object lenObj, Object startObj
len = asLongNode.execute(frame, inliningTarget, lenObj);
}
try {
- posix.fcntlLock(getPosixSupport(), fd, (code & LOCK_NB.value) == 0, lockType, whence, start, len);
+ getPosixSupport().fcntlLock(fd, (code & LOCK_NB.value) == 0, lockType, whence, start, len);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -206,7 +203,6 @@ abstract static class IoctlNode extends PythonClinicBuiltinNode {
Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutateArg,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib,
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
@Cached("createFor($node)") InteropCallData callData,
@@ -262,7 +258,7 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat
bufferLib.readIntoByteArray(buffer, 0, ioctlArg, 0, len);
}
try {
- int ret = callIoctlBytes(frame, inliningTarget, fd, request, ioctlArg, releaseGil, posixLib, gilNode, constructAndRaiseNode);
+ int ret = callIoctlBytes(frame, inliningTarget, fd, request, ioctlArg, releaseGil, gilNode, constructAndRaiseNode);
if (writable && mutateArg) {
return ret;
} else {
@@ -294,7 +290,7 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat
}
byte[] ioctlArg = new byte[len + 1];
copyToByteArrayNode.execute(stringArg, 0, ioctlArg, 0, len, utf8);
- callIoctlBytes(frame, inliningTarget, fd, request, ioctlArg, true, posixLib, gilNode, constructAndRaiseNode);
+ callIoctlBytes(frame, inliningTarget, fd, request, ioctlArg, true, gilNode, constructAndRaiseNode);
return PFactory.createBytes(context.getLanguage(inliningTarget), ioctlArg, len);
}
@@ -307,7 +303,7 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat
try {
gilNode.release(true);
try {
- return posixLib.ioctlInt(getPosixSupport(), fd, request, intArg);
+ return getPosixSupport().ioctlInt(fd, request, intArg);
} finally {
gilNode.acquire();
}
@@ -316,14 +312,14 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat
}
}
- private int callIoctlBytes(VirtualFrame frame, Node inliningTarget, int fd, long request, byte[] ioctlArg, boolean releaseGil, PosixSupportLibrary posixLib, GilNode gilNode,
+ private int callIoctlBytes(VirtualFrame frame, Node inliningTarget, int fd, long request, byte[] ioctlArg, boolean releaseGil, GilNode gilNode,
PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
if (releaseGil) {
gilNode.release(true);
}
try {
- return posixLib.ioctlBytes(getPosixSupport(), fd, request, ioctlArg);
+ return getPosixSupport().ioctlBytes(fd, request, ioctlArg);
} finally {
if (releaseGil) {
gilNode.acquire();
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 9c163df123..796cecdbba 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
@@ -165,7 +165,6 @@
import com.oracle.graal.python.nodes.util.CannotCastException;
import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode;
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
-import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
import com.oracle.graal.python.nodes.util.ToNativePrimitiveStorageNode;
import com.oracle.graal.python.pegparser.InputType;
import com.oracle.graal.python.runtime.ExecutionContext;
@@ -173,7 +172,6 @@
import com.oracle.graal.python.runtime.ExecutionContext.InteropCallContext;
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonImageBuildOptions;
import com.oracle.graal.python.runtime.PythonOptions;
@@ -407,7 +405,7 @@ private void runFile(PythonContext context, TruffleString inputFilePath) {
source = builder.build();
// TODO we should handle non-IO errors better
} catch (IOException e) {
- ErrorAndMessagePair error = OSErrorEnum.fromException(e, TruffleString.EqualNode.getUncached());
+ ErrorAndMessagePair error = OSErrorEnum.fromException(e);
String msg = String.format("%s: can't open file '%s': [Errno %d] %s\n", context.getOption(PythonOptions.Executable), inputFilePath, error.oserror.getNumber(), error.message);
// CPython uses fprintf(stderr, ...)
try {
@@ -630,19 +628,18 @@ private static Object doLoadBytecodeFile(Object bytecodePath, Object sourcePath,
@GenerateNodeFactory
public abstract static class ReadFileNode extends PythonUnaryBuiltinNode {
@Specialization
- PBytes doString(VirtualFrame frame, Object filenameObj,
+ static PBytes doString(VirtualFrame frame, Object filenameObj,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @Cached CastToTruffleStringNode castToTruffleStringNode,
- @Cached TruffleString.EqualNode eqNode,
+ @Cached CastToJavaStringNode castToStringNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- TruffleString filename = castToTruffleStringNode.execute(inliningTarget, filenameObj);
+ String filename = castToStringNode.execute(filenameObj);
TruffleFile file = context.getPublicTruffleFileRelaxed(filename, PythonLanguage.T_DEFAULT_PYTHON_EXTENSIONS);
byte[] bytes = file.readAllBytes();
return PFactory.createBytes(context.getLanguage(inliningTarget), bytes);
} catch (Exception ex) {
- ErrorAndMessagePair errAndMsg = OSErrorEnum.fromException(ex, eqNode);
+ ErrorAndMessagePair errAndMsg = OSErrorEnum.fromException(ex);
throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, errAndMsg.oserror.getNumber(), errAndMsg.message);
}
}
@@ -972,9 +969,8 @@ static boolean isAvailable(@Bind PythonContext context) {
@GenerateNodeFactory
public abstract static class PosixModuleBackendNode extends PythonBuiltinNode {
@Specialization
- TruffleString posixModuleBackend(
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) {
- return posixLib.getBackend(getPosixSupport());
+ TruffleString posixModuleBackend() {
+ return getPosixSupport().getBackend();
}
}
@@ -1251,7 +1247,6 @@ abstract static class DumpHeapNode extends PythonBuiltinNode {
TruffleString doit(VirtualFrame frame,
@Bind Node inliningTarget,
@Cached TruffleString.FromJavaStringNode fromJavaStringNode,
- @Cached TruffleString.EqualNode eqNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
TruffleFile tempFile;
try {
@@ -1259,7 +1254,7 @@ TruffleString doit(VirtualFrame frame,
tempFile = context.getEnv().createTempFile(context.getEnv().getCurrentWorkingDirectory(), J_GRAALPYTHON_ID, ".hprof");
tempFile.delete();
} catch (IOException e) {
- throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, e, eqNode);
+ throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, e);
}
PythonUtils.dumpHeap(tempFile.getPath());
return fromJavaStringNode.execute(tempFile.getPath(), TS_ENCODING);
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 25c615978c..d691dc79f4 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
@@ -888,7 +888,7 @@ private static Object doCreate(PythonObject moduleSpec, Node inliningTarget, Pyt
} catch (ImportException ie) {
throw ie.reraise();
} catch (IOException e) {
- throw PConstructAndRaiseNode.getUncached().raiseOSError(null, e, TruffleString.EqualNode.getUncached());
+ throw PConstructAndRaiseNode.getUncached().raiseOSError(null, e);
}
}
}
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 8650f46bf0..3ab1107790 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
+ * Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
@@ -57,6 +57,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.InlinedConditionProfile;
@@ -159,6 +160,7 @@ static Object tee(VirtualFrame frame, Object iterable, int n,
for (int i = 1; i < n; i++) {
tupleObjs[i] = TeeBuiltins.CopyNode.copy(to, language);
}
+ LoopNode.reportLoopCount(inliningTarget, n - 1);
return PFactory.createTuple(language, tupleObjs);
}
}
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 07dad36ccb..8d9a97fb34 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, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2026, Oracle and/or 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,6 +84,7 @@
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.LoopNode;
import com.oracle.truffle.api.nodes.Node;
@CoreFunctions(defineModule = "jarray")
@@ -227,6 +228,7 @@ static Object fromSequence(PSequence sequence, Object type,
throw CompilerDirectives.shouldNotReachHere("failed to set array item");
}
}
+ LoopNode.reportLoopCount(inliningTarget, length);
return array;
}
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 619cb9dc1d..ae410da54a 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, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2026, Oracle and/or 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 @@
@CoreFunctions(defineModule = J_JAVA)
public final class JavaModuleBuiltins extends PythonBuiltins {
- private static final TruffleString T_JAR = tsLiteral(".jar");
+ private static final String J_JAR = ".jar";
@Override
protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
@@ -159,9 +159,11 @@ abstract static class AddToClassPathNode extends PythonBuiltinNode {
@Specialization
static PNone add(Object[] args,
@Bind Node inliningTarget,
+ @Bind PythonContext context,
@Cached CastToTruffleStringNode castToString,
+ @Cached TruffleString.ToJavaStringNode toJavaStringNode,
@Cached PRaiseNode raiseNode) {
- Env env = PythonContext.get(inliningTarget).getEnv();
+ Env env = context.getEnv();
if (!env.isHostLookupAllowed()) {
throw raiseNode.raise(inliningTarget, PythonErrorType.NotImplementedError, ErrorMessages.HOST_ACCESS_NOT_ALLOWED);
}
@@ -172,7 +174,8 @@ static PNone add(Object[] args,
entry = castToString.execute(inliningTarget, arg);
// Always allow accessing JAR files in the language home; folders are allowed
// implicitly
- env.addToHostClassPath(PythonContext.get(inliningTarget).getPublicTruffleFileRelaxed(entry, T_JAR));
+ String jEntry = toJavaStringNode.execute(entry);
+ env.addToHostClassPath(context.getPublicTruffleFileRelaxed(jEntry, J_JAR));
} catch (CannotCastException e) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CLASSPATH_ARG_MUST_BE_STRING, i + 1, arg);
} catch (SecurityException e) {
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 a5ee509dec..029f6ac3cf 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
@@ -954,6 +954,7 @@ public abstract static class GcdNode extends PythonVarargsBuiltinNode {
@Specialization(guards = {"args.length > 1", "keywords.length == 0"})
public static Object gcd(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] args, @SuppressWarnings("unused") PKeyword[] keywords,
+ @Bind Node inliningTarget,
@Cached Gcd2Node gdcNode,
@Cached LoopConditionProfile profile) {
Object res = args[0];
@@ -961,6 +962,7 @@ public static Object gcd(VirtualFrame frame, @SuppressWarnings("unused") Object
for (int i = 1; profile.inject(i < args.length); i++) {
res = gdcNode.execute(frame, res, args[i]);
}
+ LoopNode.reportLoopCount(inliningTarget, args.length - 1);
return res;
}
@@ -1116,6 +1118,7 @@ static Object gcd(VirtualFrame frame, @SuppressWarnings("unused") Object self, O
Object m = mulNode.execute(frame, f, b);
a = absNode.execute(frame, m);
}
+ LoopNode.reportLoopCount(inliningTarget, args.length - 1);
return a;
}
@@ -2342,6 +2345,7 @@ public double hypot2(VirtualFrame frame, @SuppressWarnings("unused") Object self
}
coordinates[i] = x;
}
+ LoopNode.reportLoopCount(inliningTarget, arguments.length);
if (Double.isInfinite(max)) {
return max;
}
@@ -2364,6 +2368,7 @@ public double hypot2(VirtualFrame frame, @SuppressWarnings("unused") Object self
csum += x;
frac += (oldcsum - csum) + x;
}
+ LoopNode.reportLoopCount(inliningTarget, arguments.length);
return max * Math.sqrt(csum - 1.0 + frac);
}
}
@@ -2824,6 +2829,7 @@ static double doGeneric(VirtualFrame frame, Object p, Object q,
max = x;
}
}
+ LoopNode.reportLoopCount(inliningTarget, len);
if (infProfile.profile(inliningTarget, Double.isInfinite(max))) {
return max;
}
@@ -2845,6 +2851,7 @@ static double doGeneric(VirtualFrame frame, Object p, Object q,
csum += x;
frac += (oldcsum - csum) + x;
}
+ LoopNode.reportLoopCount(inliningTarget, len);
return max * Math.sqrt(csum - 1.0 + frac);
}
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MsvcrtModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MsvcrtModuleBuiltins.java
index 69d21c7834..d89c46b6fe 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MsvcrtModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MsvcrtModuleBuiltins.java
@@ -59,14 +59,13 @@
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.PosixConstants;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
+import com.oracle.graal.python.runtime.PosixSupport;
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;
@@ -102,18 +101,17 @@ public abstract static class LockingNode extends PythonTernaryClinicBuiltinNode
Object locking(VirtualFrame frame, int fd, int mode, long nbytes,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached GilNode gilNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_MSVCRT_LOCKING, fd, mode, nbytes);
try {
gilNode.release(true);
try {
- posixLib.msvcrtLocking(getPosixSupport(), fd, mode, nbytes);
+ getPosixSupport().msvcrtLocking(fd, mode, nbytes);
} finally {
gilNode.acquire();
}
- } catch (PosixSupportLibrary.PosixException e) {
+ } catch (PosixSupport.PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
return PNone.NONE;
@@ -133,11 +131,10 @@ public abstract static class SetModeNode extends PythonBinaryClinicBuiltinNode {
@Specialization
int setMode(VirtualFrame frame, int fd, int flags,
@Bind Node inliningTarget,
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.setMode(getPosixSupport(), fd, flags);
- } catch (PosixSupportLibrary.PosixException e) {
+ return getPosixSupport().setMode(fd, flags);
+ } catch (PosixSupport.PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
@@ -156,12 +153,11 @@ public abstract static class GetOsfHandleNode extends PythonUnaryClinicBuiltinNo
long getOsfHandle(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_MSVCRT_GET_OSFHANDLE, fd);
try {
- return posixLib.getOsfHandle(getPosixSupport(), fd);
- } catch (PosixSupportLibrary.PosixException e) {
+ return getPosixSupport().getOsfHandle(fd);
+ } catch (PosixSupport.PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
@@ -181,12 +177,11 @@ public abstract static class OpenOsfHandleNode extends PythonBinaryClinicBuiltin
int openOsfHandle(VirtualFrame frame, long handle, int flags,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
- @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_MSVCRT_OPEN_OSFHANDLE, handle, flags);
try {
- return posixLib.openOsfHandle(getPosixSupport(), handle, flags);
- } catch (PosixSupportLibrary.PosixException e) {
+ return getPosixSupport().openOsfHandle(handle, flags);
+ } catch (PosixSupport.PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
}
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 237185e05a..2c62d1340b 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
@@ -64,7 +64,7 @@
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.CastToJavaStringNode;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
+import com.oracle.graal.python.nodes.util.PosixSupportNodes;
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -121,11 +121,13 @@ private TruffleString getTruffleStringPath(String fspath) {
abstract static class PathSplitRootNode extends PythonUnaryClinicBuiltinNode {
@Specialization
@TruffleBoundary
- Object splitroot(PosixPath path) {
+ Object splitroot(PosixPath path,
+ @Bind Node inliningTarget,
+ @Cached PosixSupportNodes.GetPathAsStringNode getPathAsStringNode) {
// TODO should call WINAPI PathCchSkipRoot
PythonLanguage language = PythonLanguage.get(null);
- TruffleString pathString = PosixSupportLibrary.getUncached().getPathAsString(getPosixSupport(), path.value);
+ TruffleString pathString = getPathAsStringNode.execute(inliningTarget, getPosixSupport(), path.value);
int len = pathString.codePointLengthUncached(TS_ENCODING);
int index = pathString.indexOfCodePointUncached(':', 0, len, TS_ENCODING);
if (index <= 0) {
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 a0ba1abd22..c474896891 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
@@ -102,6 +102,7 @@
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
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.TupleNodes;
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
@@ -118,17 +119,18 @@
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode;
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
+import com.oracle.graal.python.nodes.util.PosixSupportNodes;
+import com.oracle.graal.python.nodes.util.PosixSupportNodes.DecodeFilesystemStringNode;
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
import com.oracle.graal.python.runtime.PosixConstants;
import com.oracle.graal.python.runtime.PosixConstants.IntConstant;
import com.oracle.graal.python.runtime.PosixSupport;
-import com.oracle.graal.python.runtime.PosixSupportLibrary;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.Buffer;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.OpenPtyResult;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixErrnoException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
-import com.oracle.graal.python.runtime.PosixSupportLibrary.Timeval;
+import com.oracle.graal.python.runtime.PosixSupport.Buffer;
+import com.oracle.graal.python.runtime.PosixSupport.OpenPtyResult;
+import com.oracle.graal.python.runtime.PosixSupport.PosixErrnoException;
+import com.oracle.graal.python.runtime.PosixSupport.PosixException;
+import com.oracle.graal.python.runtime.PosixSupport.Timeval;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonOptions;
import com.oracle.graal.python.runtime.exception.PException;
@@ -147,6 +149,7 @@
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.Idempotent;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NeverDefault;
@@ -154,6 +157,7 @@
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;
@@ -326,12 +330,12 @@ public void initialize(Python3Core core) {
public void postInitialize(Python3Core core) {
super.postInitialize(core);
- PosixSupportLibrary posixLib = PosixSupportLibrary.getUncached();
- Object posixSupport = core.getContext().getPosixSupport();
+ PosixSupport posixSupport = core.getContext().getPosixSupport();
PythonModule posix = PythonLanguage.getPythonOS() == PythonOS.PLATFORM_WIN32
- ? core.lookupBuiltinModule(T_NT) : core.lookupBuiltinModule(T_POSIX);
+ ? core.lookupBuiltinModule(T_NT)
+ : core.lookupBuiltinModule(T_POSIX);
- if (posixLib.getBackend(posixSupport).toJavaStringUncached().equals("java")) {
+ if (posixSupport.getBackend().toJavaStringUncached().equals("java")) {
posix.setAttribute(toTruffleStringUncached("geteuid"), PNone.NO_VALUE);
posix.setAttribute(toTruffleStringUncached("getegid"), PNone.NO_VALUE);
posix.setAttribute(toTruffleStringUncached("WNOHANG"), EMULATED_WNOHANG);
@@ -353,8 +357,7 @@ public void patchPostInitialize(Python3Core core) {
}
private void populateEnviron(Python3Core core) {
- PosixSupportLibrary posixLib = PosixSupportLibrary.getUncached();
- Object posixSupport = core.getContext().getPosixSupport();
+ PosixSupport posixSupport = core.getContext().getPosixSupport();
PythonLanguage language = core.getLanguage();
Map getenv = core.getContext().getEnv().getEnvironment();
@@ -378,13 +381,13 @@ private void populateEnviron(Python3Core core) {
Object k;
Object v;
if (PythonLanguage.getPythonOS() == PythonOS.PLATFORM_WIN32) {
- k = posixLib.createWideStringFromString(posixSupport, toTruffleStringUncached(pyenvLauncherKey));
- v = posixLib.createWideStringFromString(posixSupport, value);
+ k = PosixSupportNodes.CreateWideStringFromStringNode.executeUncached(posixSupport, toTruffleStringUncached(pyenvLauncherKey));
+ v = PosixSupportNodes.CreateWideStringFromStringNode.executeUncached(posixSupport, value);
} else {
- k = posixLib.createPathFromString(posixSupport, toTruffleStringUncached(pyenvLauncherKey));
- v = posixLib.createPathFromString(posixSupport, value);
+ k = PosixSupportNodes.CreatePathFromStringNode.executeUncached(posixSupport, toTruffleStringUncached(pyenvLauncherKey));
+ v = PosixSupportNodes.CreatePathFromStringNode.executeUncached(posixSupport, value);
}
- posixLib.setenv(posixSupport, k, v, true);
+ posixSupport.setenv(k, v, true);
} catch (PosixException ignored) {
}
val = toEnv(language, value);
@@ -444,9 +447,9 @@ static PNone putenv(VirtualFrame frame, Object nameObject, Object valueObject,
@Cached BytesNodes.ToBytesNode toBytesNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode,
+ @Cached PosixSupportNodes.CreateWideStringFromStringNode createWideStringFromStringNode,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
@Cached PRaiseNode raiseNode) {
// Unlike in other posix builtins, we go through str -> bytes -> byte[] -> String
@@ -458,19 +461,19 @@ static PNone putenv(VirtualFrame frame, Object nameObject, Object valueObject,
if (PythonLanguage.getPythonOS() == PythonOS.PLATFORM_WIN32) {
TruffleString name = (TruffleString) nameObject;
TruffleString value = (TruffleString) valueObject;
- nameOpaque = checkNull(inliningTarget, posixLib.createWideStringFromString(posixSupport, name), raiseNode);
- valueOpaque = checkNull(inliningTarget, posixLib.createWideStringFromString(posixSupport, value), raiseNode);
+ nameOpaque = checkNull(inliningTarget, createWideStringFromStringNode.execute(inliningTarget, posixSupport, name), raiseNode);
+ valueOpaque = checkNull(inliningTarget, createWideStringFromStringNode.execute(inliningTarget, posixSupport, value), raiseNode);
checkWindowsEnvName(inliningTarget, name, codePointLengthNode, indexOfCodePointNode, raiseNode);
} else {
byte[] name = toBytesNode.execute((PBytes) nameObject);
byte[] value = toBytesNode.execute((PBytes) valueObject);
- nameOpaque = checkNull(inliningTarget, posixLib.createCStringFromBytes(posixSupport, name), raiseNode);
- valueOpaque = checkNull(inliningTarget, posixLib.createCStringFromBytes(posixSupport, value), raiseNode);
+ nameOpaque = checkNull(inliningTarget, posixSupport.createCStringFromBytes(name), raiseNode);
+ valueOpaque = checkNull(inliningTarget, posixSupport.createCStringFromBytes(value), raiseNode);
checkEqualSign(inliningTarget, name, raiseNode);
}
auditNode.audit(frame, inliningTarget, T_OS_PUTENV, nameObject, valueObject);
try {
- posixLib.setenv(posixSupport, nameOpaque, valueOpaque, true);
+ posixSupport.setenv(nameOpaque, valueOpaque, true);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -490,6 +493,7 @@ private static void checkEqualSign(Node inliningTarget, byte[] bytes, PRaiseNode
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.ILLEGAL_ENVIRONMENT_VARIABLE_NAME);
}
}
+ LoopNode.reportLoopCount(inliningTarget, bytes.length);
}
private static void checkWindowsEnvName(Node inliningTarget, TruffleString name, TruffleString.CodePointLengthNode codePointLengthNode,
@@ -521,22 +525,22 @@ static PNone putenv(VirtualFrame frame, Object nameObject,
@Cached BytesNodes.ToBytesNode toBytesNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode,
+ @Cached PosixSupportNodes.CreateWideStringFromStringNode createWideStringFromStringNode,
@Cached SysModuleBuiltins.AuditNode auditNode,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
@Cached PRaiseNode raiseNode) {
Object nameOpaque;
if (PythonLanguage.getPythonOS() == PythonOS.PLATFORM_WIN32) {
TruffleString name = (TruffleString) nameObject;
- nameOpaque = checkNull(inliningTarget, posixLib.createWideStringFromString(context.getPosixSupport(), name), raiseNode);
+ nameOpaque = checkNull(inliningTarget, createWideStringFromStringNode.execute(inliningTarget, context.getPosixSupport(), name), raiseNode);
PutenvNode.checkWindowsEnvName(inliningTarget, name, codePointLengthNode, indexOfCodePointNode, raiseNode);
} else {
byte[] name = toBytesNode.execute((PBytes) nameObject);
- nameOpaque = checkNull(inliningTarget, posixLib.createCStringFromBytes(context.getPosixSupport(), name), raiseNode);
+ nameOpaque = checkNull(inliningTarget, context.getPosixSupport().createCStringFromBytes(name), raiseNode);
}
auditNode.audit(frame, inliningTarget, T_OS_UNSETENV, nameObject);
try {
- posixLib.unsetenv(context.getPosixSupport(), nameOpaque);
+ context.getPosixSupport().unsetenv(nameOpaque);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -565,12 +569,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile isPListProfile,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PyTupleCheckNode tupleCheckNode,
@Cached ToArrayNode toArrayNode,
@Cached ObjectToOpaquePathNode toOpaquePathNode,
+ @Cached PosixSupportNodes.GetPathAsBytesNode getPathAsBytesNode,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
@@ -592,16 +596,17 @@ static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
Object[] opaqueArgs = new Object[args.length];
for (int i = 0; i < args.length; ++i) {
Object opaquePath = toOpaquePathNode.execute(frame, inliningTarget, args[i], i == 0);
- Buffer bytes = posixLib.getPathAsBytes(context.getPosixSupport(), opaquePath);
- opaqueArgs[i] = posixLib.createCStringFromBytes(context.getPosixSupport(), bytes.data);
+ Buffer bytes = getPathAsBytesNode.execute(inliningTarget, context.getPosixSupport(), opaquePath);
+ opaqueArgs[i] = context.getPosixSupport().createCStringFromBytes(bytes.data);
}
+ LoopNode.reportLoopCount(inliningTarget, args.length);
// TODO ValueError "execv() arg 2 first element cannot be empty"
auditNode.audit(frame, inliningTarget, T_OS_EXEC, path.originalObject, argv, PNone.NONE);
gil.release(true);
try {
- posixLib.execv(context.getPosixSupport(), path.value, opaqueArgs);
+ context.getPosixSupport().execv(path.value, opaqueArgs);
} catch (PosixException e) {
gil.acquire();
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -616,9 +621,8 @@ static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
@GenerateNodeFactory
public abstract static class GetPidNode extends PythonBuiltinNode {
@Specialization
- static long getPid(@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) {
- return posixLib.getpid(context.getPosixSupport());
+ static long getPid(@Bind PythonContext context) {
+ return context.getPosixSupport().getpid();
}
}
@@ -626,9 +630,8 @@ static long getPid(@Bind PythonContext context,
@GenerateNodeFactory
public abstract static class GetUidNode extends PythonBuiltinNode {
@Specialization
- static long getUid(@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) {
- return posixLib.getuid(context.getPosixSupport());
+ static long getUid(@Bind PythonContext context) {
+ return context.getPosixSupport().getuid();
}
}
@@ -638,10 +641,9 @@ public abstract static class GetEUidNode extends PythonBuiltinNode {
@Specialization
static long getUid(@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.geteuid(context.getPosixSupport());
+ return context.getPosixSupport().geteuid();
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(null, e);
}
@@ -652,9 +654,8 @@ static long getUid(@Bind Node inliningTarget,
@GenerateNodeFactory
public abstract static class GetGidNode extends PythonBuiltinNode {
@Specialization
- static long getGid(@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) {
- return posixLib.getgid(context.getPosixSupport());
+ static long getGid(@Bind PythonContext context) {
+ return context.getPosixSupport().getgid();
}
}
@@ -664,10 +665,9 @@ public abstract static class GetEGidNode extends PythonBuiltinNode {
@Specialization
static long getGid(@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getegid(context.getPosixSupport());
+ return context.getPosixSupport().getegid();
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(null, e);
}
@@ -680,10 +680,9 @@ public abstract static class GetPpidNode extends PythonBuiltinNode {
@Specialization
static long getPpid(@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getppid(context.getPosixSupport());
+ return context.getPosixSupport().getppid();
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(null, e);
}
@@ -730,10 +729,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static long getPgid(VirtualFrame frame, long pid,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getpgid(context.getPosixSupport(), pid);
+ return context.getPosixSupport().getpgid(pid);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -754,10 +752,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static Object setPgid(VirtualFrame frame, long pid, long pgid,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.setpgid(context.getPosixSupport(), pid, pgid);
+ context.getPosixSupport().setpgid(pid, pgid);
return PNone.NONE;
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -772,10 +769,9 @@ public abstract static class SetPgrpdNode extends PythonBuiltinNode {
static Object getPpid(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.setpgid(context.getPosixSupport(), 0, 0);
+ context.getPosixSupport().setpgid(0, 0);
return PNone.NONE;
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -789,10 +785,9 @@ public abstract static class GetPgrpNode extends PythonBuiltinNode {
@Specialization
static long getPpid(@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getpgrp(context.getPosixSupport());
+ return context.getPosixSupport().getpgrp();
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(null, e);
}
@@ -812,10 +807,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static long getSid(VirtualFrame frame, long pid,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getsid(context.getPosixSupport(), pid);
+ return context.getPosixSupport().getsid(pid);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -830,10 +824,9 @@ public abstract static class SetSidNode extends PythonBuiltinNode {
static Object setsid(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.setsid(context.getPosixSupport());
+ context.getPosixSupport().setsid();
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -848,10 +841,9 @@ abstract static class GetGroupsNode extends PythonBuiltinNode {
static Object getgroups(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- long[] groups = posixLib.getgroups(context.getPosixSupport());
+ long[] groups = context.getPosixSupport().getgroups();
return PFactory.createList(context.getLanguage(inliningTarget), new LongSequenceStorage(groups));
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -867,12 +859,11 @@ public abstract static class OpenPtyNode extends PythonBuiltinNode {
static Object openpty(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- OpenPtyResult result = posixLib.openpty(context.getPosixSupport());
- posixLib.setInheritable(context.getPosixSupport(), result.masterFd(), false);
- posixLib.setInheritable(context.getPosixSupport(), result.slaveFd(), false);
+ OpenPtyResult result = context.getPosixSupport().openpty();
+ context.getPosixSupport().setInheritable(result.masterFd(), false);
+ context.getPosixSupport().setInheritable(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);
@@ -897,7 +888,6 @@ protected ArgumentClinicProvider getArgumentClinic() {
static int open(VirtualFrame frame, PosixPath path, int flags, int mode, int dirFd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached InlinedBranchProfile errorProfile,
@Cached GilNode gil,
@@ -911,7 +901,7 @@ static int open(VirtualFrame frame, PosixPath path, int flags, int mode, int dir
try {
while (true) {
try {
- return posixLib.openat(context.getPosixSupport(), dirFd, path.value, fixedFlags, mode);
+ return context.getPosixSupport().openat(dirFd, path.value, fixedFlags, mode);
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
if (e.hasErrno(OSErrorEnum.EINTR)) {
@@ -942,13 +932,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone close(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
gil.release(true);
try {
- posixLib.close(context.getPosixSupport(), fd);
+ context.getPosixSupport().close(fd);
} finally {
gil.acquire();
}
@@ -974,17 +963,16 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PBytes doRead(VirtualFrame frame, int fd, int length,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile1,
@Cached InlinedBranchProfile errorProfile2,
@Cached GilNode gil,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
if (length < 0) {
int error = OSErrorEnum.EINVAL.getNumber();
- throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, posixLib.strerror(context.getPosixSupport(), error));
+ throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, context.getPosixSupport().strerror(error));
}
try {
- return read(fd, length, inliningTarget, posixLib, context.getPosixSupport(), errorProfile1, gil);
+ return read(fd, length, inliningTarget, context.getPosixSupport(), errorProfile1, gil);
} catch (PosixException e) {
errorProfile2.enter(inliningTarget);
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -993,14 +981,13 @@ static PBytes doRead(VirtualFrame frame, int fd, int length,
public static PBytes read(int fd, int length,
Node inliningTarget,
- PosixSupportLibrary posixLib,
PosixSupport posixSupport,
InlinedBranchProfile errorProfile, GilNode gil) throws PosixException {
gil.release(true);
try {
while (true) {
try {
- Buffer result = posixLib.read(posixSupport, fd, length);
+ Buffer result = posixSupport.read(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
@@ -1039,12 +1026,11 @@ static long doWrite(VirtualFrame frame, int fd, Object dataBuffer,
@Cached("createFor($node)") InteropCallData callData,
@CachedLibrary("dataBuffer") PythonBufferAccessLibrary bufferLib,
@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, context.getPosixSupport(), errorProfile, gil);
+ return write(fd, bufferLib.getInternalOrCopiedByteArray(dataBuffer), bufferLib.getBufferLength(dataBuffer), inliningTarget, context.getPosixSupport(), errorProfile, gil);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
} finally {
@@ -1053,13 +1039,13 @@ static long doWrite(VirtualFrame frame, int fd, Object dataBuffer,
}
public static long write(int fd, byte[] dataBytes,
- int dataLen, Node inliningTarget, PosixSupportLibrary posixLib, PosixSupport posixSupport,
+ int dataLen, Node inliningTarget, PosixSupport posixSupport,
InlinedBranchProfile errorProfile, GilNode gil) throws PosixException {
gil.release(true);
try {
while (true) {
try {
- return posixLib.write(posixSupport, fd, new Buffer(dataBytes, dataLen));
+ return posixSupport.write(fd, new Buffer(dataBytes, dataLen));
} catch (PosixErrnoException e) {
errorProfile.enter(inliningTarget);
if (e.hasErrno(OSErrorEnum.EINTR)) {
@@ -1089,10 +1075,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static int dup(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.dup(context.getPosixSupport(), fd);
+ return context.getPosixSupport().dup(fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1115,17 +1100,16 @@ protected ArgumentClinicProvider getArgumentClinic() {
static int dup2(VirtualFrame frame, int fd, int fd2, boolean inheritable,
@Bind Node inliningTarget,
@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(context.getPosixSupport(), error));
+ throw constructAndRaiseNode.get(inliningTarget).raiseOSError(frame, error, context.getPosixSupport().strerror(error));
}
try {
- return posixLib.dup2(context.getPosixSupport(), fd, fd2, inheritable);
+ return context.getPosixSupport().dup2(fd, fd2, inheritable);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1146,10 +1130,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static boolean getInheritable(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getInheritable(context.getPosixSupport(), fd);
+ return context.getPosixSupport().getInheritable(fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1171,11 +1154,10 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone setInheritable(VirtualFrame frame, int fd, int inheritable,
@Bind Node inliningTarget,
@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(context.getPosixSupport(), fd, inheritable != 0);
+ context.getPosixSupport().setInheritable(fd, inheritable != 0);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1192,12 +1174,11 @@ static PTuple pipe(VirtualFrame frame,
@Bind Node inliningTarget,
@Cached GilNode gil,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
int[] pipe;
gil.release(true);
try {
- pipe = posixLib.pipe(context.getPosixSupport());
+ pipe = context.getPosixSupport().pipe();
} catch (PosixException e) {
gil.acquire(); // need to acquire the gil to construct the OSError object
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -1238,10 +1219,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static long lseek(VirtualFrame frame, int fd, long pos, int how,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.lseek(context.getPosixSupport(), fd, pos, mapPythonSeekWhenceToPosix(how));
+ return context.getPosixSupport().lseek(fd, pos, mapPythonSeekWhenceToPosix(how));
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1263,7 +1243,6 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone ftruncate(VirtualFrame frame, int fd, long length,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached GilNode gil,
@Cached InlinedBranchProfile errorProfile,
@@ -1273,7 +1252,7 @@ static PNone ftruncate(VirtualFrame frame, int fd, long length,
try {
gil.release(true);
try {
- posixLib.ftruncate(context.getPosixSupport(), fd, length);
+ context.getPosixSupport().ftruncate(fd, length);
} finally {
gil.acquire();
}
@@ -1305,7 +1284,6 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone truncate(VirtualFrame frame, PosixPath path, long length,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Exclusive @Cached SysModuleBuiltins.AuditNode auditNode,
@Exclusive @Cached GilNode gil,
@Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
@@ -1313,7 +1291,7 @@ static PNone truncate(VirtualFrame frame, PosixPath path, long length,
try {
gil.release(true);
try {
- posixLib.truncate(context.getPosixSupport(), path.value, length);
+ context.getPosixSupport().truncate(path.value, length);
} finally {
gil.acquire();
}
@@ -1327,12 +1305,11 @@ static PNone truncate(VirtualFrame frame, PosixPath path, long length,
static PNone ftruncate(VirtualFrame frame, PosixFd fd, long length,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Exclusive @Cached SysModuleBuiltins.AuditNode auditNode,
@Exclusive @Cached GilNode gil,
@Exclusive @Cached InlinedBranchProfile errorProfile,
@Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
- return FtruncateNode.ftruncate(frame, fd.fd, length, inliningTarget, context, posixLib, auditNode, gil, errorProfile, constructAndRaiseNode);
+ return FtruncateNode.ftruncate(frame, fd.fd, length, inliningTarget, context, auditNode, gil, errorProfile, constructAndRaiseNode);
}
}
@@ -1350,12 +1327,11 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone fsync(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
while (true) {
try {
- posixLib.fsync(context.getPosixSupport(), fd);
+ context.getPosixSupport().fsync(fd);
return PNone.NONE;
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
@@ -1383,10 +1359,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static boolean getBlocking(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getBlocking(context.getPosixSupport(), fd);
+ return context.getPosixSupport().getBlocking(fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1408,10 +1383,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone setBlocking(VirtualFrame frame, int fd, boolean blocking,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.setBlocking(context.getPosixSupport(), fd, blocking);
+ context.getPosixSupport().setBlocking(fd, blocking);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1433,11 +1407,10 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PTuple getTerminalSize(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
// TODO default value should be fileno(stdout)
try {
- int[] result = posixLib.getTerminalSize(context.getPosixSupport(), fd);
+ int[] result = context.getPosixSupport().getTerminalSize(fd);
return PFactory.createStructSeq(context.getLanguage(inliningTarget), TERMINAL_SIZE_DESC, result[0], result[1]);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
@@ -1461,11 +1434,10 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd, boolean followSymlinks,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Shared("positive") @Cached InlinedConditionProfile positiveLongProfile,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- long[] out = posixLib.fstatat(context.getPosixSupport(), dirFd, path.value, followSymlinks);
+ long[] out = context.getPosixSupport().fstatat(dirFd, path.value, followSymlinks);
return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
@@ -1490,11 +1462,10 @@ static PTuple doStatFdWithFollowSymlinks(VirtualFrame frame, PosixFd fd, int dir
static PTuple doStatFd(VirtualFrame frame, PosixFd fd, @SuppressWarnings("unused") int dirFd, @SuppressWarnings("unused") boolean followSymlinks,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Shared("positive") @Cached InlinedConditionProfile positiveLongProfile,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- long[] out = posixLib.fstat(context.getPosixSupport(), fd.fd);
+ long[] out = context.getPosixSupport().fstat(fd.fd);
return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject);
@@ -1521,12 +1492,11 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PTuple doStatPath(VirtualFrame frame, PosixPath path, int dirFd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile positiveLongProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
// TODO we used to return all zeros when the filename was equal to sys.executable
- long[] out = posixLib.fstatat(context.getPosixSupport(), dirFd, path.value, false);
+ long[] out = context.getPosixSupport().fstatat(dirFd, path.value, false);
return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
@@ -1548,13 +1518,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PTuple doStatFd(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile positiveLongProfile,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
while (true) {
try {
- long[] out = posixLib.fstat(context.getPosixSupport(), fd);
+ long[] out = context.getPosixSupport().fstat(fd);
return createStatResult(inliningTarget, context.getLanguage(inliningTarget), positiveLongProfile, out);
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
@@ -1590,16 +1559,15 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PTuple doStatvfs(VirtualFrame frame, PosixFileHandle posixFileHandle,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile posixPathProfile,
@Cached InlinedConditionProfile positiveLongProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
long[] out;
try {
if (posixPathProfile.profile(inliningTarget, posixFileHandle instanceof PosixPath)) {
- out = posixLib.statvfs(context.getPosixSupport(), ((PosixPath) posixFileHandle).value);
+ out = context.getPosixSupport().statvfs(((PosixPath) posixFileHandle).value);
} else {
- out = posixLib.fstatvfs(context.getPosixSupport(), ((PosixFd) posixFileHandle).fd);
+ out = context.getPosixSupport().fstatvfs(((PosixFd) posixFileHandle).fd);
}
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, posixFileHandle.originalObject);
@@ -1617,12 +1585,11 @@ abstract static class FStatvfsNode extends PythonUnaryClinicBuiltinNode {
static PTuple doStatvfs(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile positiveLongProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
long[] out;
try {
- out = posixLib.fstatvfs(context.getPosixSupport(), fd);
+ out = context.getPosixSupport().fstatvfs(fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd);
}
@@ -1644,10 +1611,9 @@ abstract static class UnameNode extends PythonBuiltinNode {
static PTuple uname(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return PFactory.createStructSeq(context.getLanguage(inliningTarget), UNAME_RESULT_DESC, posixLib.uname(context.getPosixSupport()));
+ return PFactory.createStructSeq(context.getLanguage(inliningTarget), UNAME_RESULT_DESC, context.getPosixSupport().uname());
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1668,13 +1634,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
@Specialization
static PNone unlink(VirtualFrame frame, PosixPath path, int dirFd,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_REMOVE, path.originalObject, dirFdForAudit(dirFd));
try {
- posixLib.unlinkat(context.getPosixSupport(), dirFd, path.value, false);
+ context.getPosixSupport().unlinkat(dirFd, path.value, false);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
@@ -1715,10 +1680,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone link(VirtualFrame frame, PosixPath src, PosixPath dst, int srcDirFd, int dstDirFd, boolean followSymlinks,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.linkat(context.getPosixSupport(), srcDirFd, src.value, dstDirFd, dst.value, followSymlinks ? AT_SYMLINK_FOLLOW.value : 0);
+ context.getPosixSupport().linkat(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);
}
@@ -1743,10 +1707,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone symlink(VirtualFrame frame, PosixPath src, PosixPath dst, @SuppressWarnings("unused") boolean targetIsDir, int dirFd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.symlinkat(context.getPosixSupport(), src.value, dirFd, dst.value);
+ context.getPosixSupport().symlinkat(src.value, dirFd, dst.value);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, src.originalObject, dst.originalObject);
}
@@ -1769,13 +1732,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
@Specialization
static PNone mkdir(VirtualFrame frame, PosixPath path, int mode, int dirFd,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_MKDIR, path.originalObject, mode, dirFdForAudit(dirFd));
try {
- posixLib.mkdirat(context.getPosixSupport(), dirFd, path.value, mode);
+ context.getPosixSupport().mkdirat(dirFd, path.value, mode);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
@@ -1797,13 +1759,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
@Specialization
static PNone rmdir(VirtualFrame frame, PosixPath path, int dirFd,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Cached SysModuleBuiltins.AuditNode auditNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_RMDIR, path.originalObject, dirFdForAudit(dirFd));
try {
- posixLib.unlinkat(context.getPosixSupport(), dirFd, path.value, true);
+ context.getPosixSupport().unlinkat(dirFd, path.value, true);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
@@ -1818,10 +1779,10 @@ abstract static class GetcwdNode extends PythonBuiltinNode {
static TruffleString getcwd(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
+ @Cached PosixSupportNodes.GetPathAsStringNode getPathAsStringNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- return posixLib.getPathAsString(context.getPosixSupport(), posixLib.getcwd(context.getPosixSupport()));
+ return getPathAsStringNode.execute(inliningTarget, context.getPosixSupport(), context.getPosixSupport().getcwd());
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1835,11 +1796,11 @@ abstract static class GetcwdbNode extends PythonBuiltinNode {
static PBytes getcwdb(VirtualFrame frame,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
+ @Cached OpaquePathToBytesNode opaquePathToBytesNode,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- Object path = posixLib.getcwd(context.getPosixSupport());
- return opaquePathToBytes(path, posixLib, context.getPosixSupport(), context.getLanguage(inliningTarget));
+ Object path = context.getPosixSupport().getcwd();
+ return opaquePathToBytesNode.execute(inliningTarget, context.getPosixSupport(), path, context.getLanguage(inliningTarget));
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
}
@@ -1860,10 +1821,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone chdirPath(VirtualFrame frame, PosixPath path,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.chdir(context.getPosixSupport(), path.value);
+ context.getPosixSupport().chdir(path.value);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
@@ -1874,10 +1834,9 @@ static PNone chdirPath(VirtualFrame frame, PosixPath path,
static PNone chdirFd(VirtualFrame frame, PosixFd fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
try {
- posixLib.fchdir(context.getPosixSupport(), fd.fd);
+ context.getPosixSupport().fchdir(fd.fd);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, fd.originalObject);
}
@@ -1899,12 +1858,11 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PNone fchdir(VirtualFrame frame, int fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedBranchProfile errorProfile,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
while (true) {
try {
- posixLib.fchdir(context.getPosixSupport(), fd);
+ context.getPosixSupport().fchdir(fd);
return PNone.NONE;
} catch (PosixException e) {
errorProfile.enter(inliningTarget);
@@ -1931,11 +1889,10 @@ protected ArgumentClinicProvider getArgumentClinic() {
@Specialization
static boolean isatty(int fd,
@Cached GilNode gil,
- @Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) {
+ @Bind PythonContext context) {
gil.release(true);
try {
- return posixLib.isatty(context.getPosixSupport(), fd);
+ return context.getPosixSupport().isatty(fd);
} finally {
gil.acquire();
}
@@ -1955,13 +1912,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
@Specialization
static PScandirIterator scandirPath(VirtualFrame frame, PosixPath path,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_SCANDIR, path.originalObject == null ? PNone.NONE : path.originalObject);
try {
- return PFactory.createScandirIterator(context.getLanguage(inliningTarget), context, posixLib.opendir(context.getPosixSupport(), path.value), path, false);
+ return PFactory.createScandirIterator(context.getLanguage(inliningTarget), context, context.getPosixSupport().opendir(path.value), path, false);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
@@ -1970,12 +1926,11 @@ static PScandirIterator scandirPath(VirtualFrame frame, PosixPath path,
@Specialization
static PScandirIterator scandirFd(VirtualFrame frame, PosixFd fd,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_SCANDIR, fd.originalObject);
- Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, context.getPosixSupport(), fd, constructAndRaiseNode);
+ Object dirStream = dupAndFdopendir(frame, inliningTarget, context.getPosixSupport(), fd, constructAndRaiseNode);
return PFactory.createScandirIterator(context.getLanguage(inliningTarget), context, dirStream, fd, true);
}
}
@@ -1994,13 +1949,14 @@ protected ArgumentClinicProvider getArgumentClinic() {
static PList listdirPath(VirtualFrame frame, PosixPath path,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
+ @Shared @Cached OpaquePathToBytesNode opaquePathToBytesNode,
+ @Shared @Cached PosixSupportNodes.GetPathAsStringNode getPathAsStringNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_LISTDIR, path.originalObject == null ? PNone.NONE : path.originalObject);
try {
- return listdir(frame, inliningTarget, posixLib.opendir(context.getPosixSupport(), path.value), path.wasBufferLike, false, posixLib, constructAndRaiseNode,
- context.getLanguage(inliningTarget), context.getPosixSupport());
+ return listdir(frame, inliningTarget, context.getPosixSupport().opendir(path.value), path.wasBufferLike, false, constructAndRaiseNode,
+ context.getLanguage(inliningTarget), context.getPosixSupport(), opaquePathToBytesNode, getPathAsStringNode);
} catch (PosixException e) {
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e, path.originalObject);
}
@@ -2010,38 +1966,41 @@ static PList listdirPath(VirtualFrame frame, PosixPath path,
static PList listdirFd(VirtualFrame frame, PosixFd fd,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Shared @Cached SysModuleBuiltins.AuditNode auditNode,
+ @Shared @Cached OpaquePathToBytesNode opaquePathToBytesNode,
+ @Shared @Cached PosixSupportNodes.GetPathAsStringNode getPathAsStringNode,
@Shared @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
auditNode.audit(frame, inliningTarget, T_OS_LISTDIR, fd.originalObject);
- Object dirStream = dupAndFdopendir(frame, inliningTarget, posixLib, context.getPosixSupport(), fd, constructAndRaiseNode);
- return listdir(frame, inliningTarget, dirStream, false, true, posixLib, constructAndRaiseNode, context.getLanguage(inliningTarget), context.getPosixSupport());
+ Object dirStream = dupAndFdopendir(frame, inliningTarget, context.getPosixSupport(), fd, constructAndRaiseNode);
+ return listdir(frame, inliningTarget, dirStream, false, true, constructAndRaiseNode, context.getLanguage(inliningTarget), context.getPosixSupport(), opaquePathToBytesNode,
+ getPathAsStringNode);
}
- private static PList listdir(VirtualFrame frame, Node inliningTarget, Object dirStream, boolean produceBytes, boolean needsRewind, PosixSupportLibrary posixLib,
- PConstructAndRaiseNode.Lazy constructAndRaiseNode, PythonLanguage language, PosixSupport posixSupport) {
+ private static PList listdir(VirtualFrame frame, Node inliningTarget, Object dirStream, boolean produceBytes, boolean needsRewind, PConstructAndRaiseNode.Lazy constructAndRaiseNode,
+ PythonLanguage language, PosixSupport posixSupport, OpaquePathToBytesNode opaquePathToBytesNode,
+ PosixSupportNodes.GetPathAsStringNode getPathAsStringNode) {
List