Skip to content

Commit 9e5794b

Browse files
Merge branch 'main' into Xmader/fix/xhr-poll-error
2 parents f68344d + 6d9a396 commit 9e5794b

File tree

4 files changed

+47
-20
lines changed

4 files changed

+47
-20
lines changed

.github/workflows/test-and-publish.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ jobs:
201201
WORKFLOW_BUILD_TYPE=${{ inputs.build_type }}
202202
BUILD_TYPE=${WORKFLOW_BUILD_TYPE:-"Debug"} poetry build --format=wheel
203203
ls -lah ./dist/
204+
- name: Make the wheels we build also support lower versions of macOS
205+
if: ${{ matrix.os == 'macos-12' || matrix.os == 'macos-14' }}
206+
# Change the platform tag part of the wheel filename to `macosx_11_0_xxx` (means to support macOS 11.0 and above)
207+
# See https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-format
208+
# A wheel package file will only be selected by pip to install if the platform tag satisfies, regardless of whether the binary compatibility actually is.
209+
# Otherwise, pip would fallback to compile from the source distribution.
210+
run: |
211+
cd ./dist/
212+
for file in *.whl; do
213+
mv "$file" "$(echo "$file" | sed -E 's/macosx_[0-9]+_[0-9]+/macosx_11_0/')";
214+
done
204215
- name: Upload wheel as CI artifacts
205216
uses: actions/upload-artifact@v3
206217
with:

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# PythonMonkey
22

3-
![Testing Suite](https://github.com/Kings-Distributed-Systems/PythonMonkey/actions/workflows/tests.yaml/badge.svg)
3+
[![Test and Publish Suite](https://github.com/Distributive-Network/PythonMonkey/actions/workflows/test-and-publish.yaml/badge.svg)](https://github.com/Distributive-Network/PythonMonkey/actions/workflows/test-and-publish.yaml)
44

55
## About
66
[PythonMonkey](https://pythonmonkey.io) is a Mozilla [SpiderMonkey](https://firefox-source-docs.mozilla.org/js/index.html) JavaScript engine embedded into the Python Runtime,
77
using the Python engine to provide the Javascript host environment.
88

99
We feature JavaScript Array and Object methods implemented on Python List and Dictionaries using the cPython C API, and the inverse using the Mozilla Firefox Spidermonkey JavaScript C++ API.
1010

11-
This product is in an advanced stage, approximately 98% to MVP as of August 2024. It is under active development by [Distributive](https://distributive.network/).
11+
This project has reached MVP as of September 2024. It is under maintenance by [Distributive](https://distributive.network/).
1212

1313
External contributions and feedback are welcome and encouraged.
1414

@@ -73,7 +73,7 @@ Read this if you want to build a local version.
7373
- llvm
7474
- rust
7575
- python3.8 or later with header files (python3-dev)
76-
- spidermonkey 115.1.0 or later
76+
- spidermonkey latest from mozilla-central
7777
- npm (nodejs)
7878
- [Poetry](https://python-poetry.org/docs/#installation)
7979
- [poetry-dynamic-versioning](https://github.com/mtkennerly/poetry-dynamic-versioning)
@@ -462,7 +462,7 @@ List of commands:
462462
```console
463463
$ pmjs
464464

465-
Welcome to PythonMonkey v0.4.0.
465+
Welcome to PythonMonkey v1.0.0.
466466
Type ".help" for more information.
467467
> .python import sys
468468
> .python sys.path

src/PyObjectProxyHandler.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ bool PyObjectProxyHandler::handleGetOwnPropertyDescriptor(JSContext *cx, JS::Han
4444
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc, PyObject *item) {
4545
// see if we're calling a function
4646
if (id.isString()) {
47-
JS::RootedString idString(cx, id.toString());
48-
const char *methodName = JS_EncodeStringToUTF8(cx, idString).get();
47+
JS::UniqueChars idString = JS_EncodeStringToUTF8(cx, JS::RootedString(cx, id.toString()));
48+
const char *methodName = idString.get();
49+
4950
if (!strcmp(methodName, "toString") || !strcmp(methodName, "toLocaleString") || !strcmp(methodName, "valueOf")) {
5051
JS::RootedObject objectPrototype(cx);
5152
if (!JS_GetClassPrototype(cx, JSProto_Object, &objectPrototype)) {

src/modules/pythonmonkey/pythonmonkey.cc

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,39 @@
4848

4949
JS::PersistentRootedObject jsFunctionRegistry;
5050

51+
/**
52+
* @brief During a GC, string buffers may have moved, so we need to re-point our JSStringProxies
53+
* The char buffer pointer obtained by previous `JS::Get{Latin1,TwoByte}LinearStringChars` calls remains valid only as long as no GC occurs.
54+
*/
55+
void updateCharBufferPointers() {
56+
if (_Py_IsFinalizing()) {
57+
return; // do not move char pointers around if python is finalizing
58+
}
59+
60+
JS::AutoCheckCannotGC nogc;
61+
for (const JSStringProxy *jsStringProxy: jsStringProxies) {
62+
JSLinearString *str = JS_ASSERT_STRING_IS_LINEAR(jsStringProxy->jsString->toString());
63+
void *updatedCharBufPtr; // pointer to the moved char buffer after a GC
64+
if (JS::LinearStringHasLatin1Chars(str)) {
65+
updatedCharBufPtr = (void *)JS::GetLatin1LinearStringChars(nogc, str);
66+
} else { // utf16 / ucs2 string
67+
updatedCharBufPtr = (void *)JS::GetTwoByteLinearStringChars(nogc, str);
68+
}
69+
((PyUnicodeObject *)(jsStringProxy))->data.any = updatedCharBufPtr;
70+
}
71+
}
72+
5173
void pythonmonkeyGCCallback(JSContext *cx, JSGCStatus status, JS::GCReason reason, void *data) {
5274
if (status == JSGCStatus::JSGC_END) {
5375
JS::ClearKeptObjects(GLOBAL_CX);
5476
while (JOB_QUEUE->runFinalizationRegistryCallbacks(GLOBAL_CX));
77+
updateCharBufferPointers();
78+
}
79+
}
5580

56-
if (_Py_IsFinalizing()) {
57-
return; // do not move char pointers around if python is finalizing
58-
}
59-
60-
JS::AutoCheckCannotGC nogc;
61-
for (const JSStringProxy *jsStringProxy: jsStringProxies) { // char buffers may have moved, so we need to re-point our JSStringProxies
62-
JSLinearString *str = (JSLinearString *)(jsStringProxy->jsString->toString()); // jsString is guaranteed to be linear
63-
if (JS::LinearStringHasLatin1Chars(str)) {
64-
(((PyUnicodeObject *)(jsStringProxy))->data.any) = (void *)JS::GetLatin1LinearStringChars(nogc, str);
65-
}
66-
else { // utf16 / ucs2 string
67-
(((PyUnicodeObject *)(jsStringProxy))->data.any) = (void *)JS::GetTwoByteLinearStringChars(nogc, str);
68-
}
69-
}
81+
void nurseryCollectionCallback(JSContext *cx, JS::GCNurseryProgress progress, JS::GCReason reason, void *data) {
82+
if (progress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END) {
83+
updateCharBufferPointers();
7084
}
7185
}
7286

@@ -565,6 +579,7 @@ PyMODINIT_FUNC PyInit_pythonmonkey(void)
565579
JS_SetGCParameter(GLOBAL_CX, JSGC_MAX_BYTES, (uint32_t)-1);
566580

567581
JS_SetGCCallback(GLOBAL_CX, pythonmonkeyGCCallback, NULL);
582+
JS::AddGCNurseryCollectionCallback(GLOBAL_CX, nurseryCollectionCallback, NULL);
568583

569584
JS::RealmCreationOptions creationOptions = JS::RealmCreationOptions();
570585
JS::RealmBehaviors behaviours = JS::RealmBehaviors();

0 commit comments

Comments
 (0)