Skip to content

Commit f68344d

Browse files
authored
Merge branch 'main' into Xmader/fix/xhr-poll-error
2 parents 376ccd3 + c140da7 commit f68344d

12 files changed

+108
-64
lines changed

.git-blame-ignore-revs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,10 @@ aae30e864449442cf0b04e94f8a242b1b667de9a
55
16dc3153b3cb684ca72445ed058babc8f5d97f42
66

77
# chore(linting): lint all C++ files
8-
58cd4b45777b046f03a63255c1d93e289e1cab5e
8+
58cd4b45777b046f03a63255c1d93e289e1cab5e
9+
10+
# chore(linting): lint PyBytesProxyHandler.cc
11+
d540ed6e0edfe9538dc726cf587dfb2cc76dde34
12+
13+
# chore(linting): lint PyObjectProxyHandler.cc
14+
1d45ea98e42294cce16deec5454725d4de36f59f

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,6 @@ jobs:
129129
matrix:
130130
os: [ 'ubuntu-20.04', 'macos-12', 'macos-14', 'windows-2022', 'pi' ]
131131
python_version: [ '3.8', '3.9', '3.10', '3.11', '3.12' ]
132-
exclude:
133-
# actions/setup-python: The version '3.8'/'3.9' with architecture 'arm64' was not found for macOS.
134-
# see https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
135-
- os: 'macos-14'
136-
python_version: '3.8'
137-
- os: 'macos-14'
138-
python_version: '3.9'
139132
runs-on: ${{ matrix.os }}
140133
steps:
141134
- uses: actions/checkout@v4

.github/workflows/update-mozcentral-version.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ name: 'Create pull requests to update mozilla-central version to the latest'
22

33
on:
44
schedule:
5-
- cron: "00 14 * * 1" # run every Monday at 14:00 UTC (10:00 Eastern Daylight Time)
5+
- cron: "00 14 */100,1-7 * 1" # run on the first Monday of each month at 14:00 UTC (10:00 Eastern Daylight Time)
6+
# See https://blog.healthchecks.io/2022/09/schedule-cron-job-the-funky-way/
67
workflow_call:
78
workflow_dispatch: # or you can run it manually
89

@@ -33,8 +34,10 @@ jobs:
3334
add-paths: mozcentral.version
3435
commit-message: |
3536
chore(deps): upgrade SpiderMonkey to `${{ env.MOZCENTRAL_VERSION }}`
37+
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
3638
branch: chore/upgrade-spidermonkey-to-${{ env.MOZCENTRAL_VERSION_SHORT }}
3739
title: Upgrade SpiderMonkey to mozilla-central commit `${{ env.MOZCENTRAL_VERSION }}`
3840
body: |
3941
Changeset: https://hg.mozilla.org/mozilla-central/rev/${{ env.MOZCENTRAL_VERSION }}
4042
labels: dependencies
43+
assignees: Xmader

include/JSStringProxy.hh

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include <Python.h>
1717

18+
#include <unordered_set>
19+
1820
/**
1921
* @brief The typedef for the backing store that will be used by JSStringProxy objects. All it contains is a pointer to the JSString
2022
*
@@ -24,6 +26,8 @@ typedef struct {
2426
JS::PersistentRootedValue *jsString;
2527
} JSStringProxy;
2628

29+
extern std::unordered_set<JSStringProxy *> jsStringProxies; // a collection of all JSStringProxy objects, used during a GCCallback to ensure they continue to point to the correct char buffer
30+
2731
/**
2832
* @brief This struct is a bundle of methods used by the JSStringProxy type
2933
*
@@ -37,7 +41,7 @@ public:
3741
*/
3842
static void JSStringProxy_dealloc(JSStringProxy *self);
3943

40-
/**
44+
/**
4145
* @brief copy protocol method for both copy and deepcopy
4246
*
4347
* @param self - The JSObjectProxy
@@ -49,13 +53,13 @@ public:
4953
// docs for methods, copied from cpython
5054
PyDoc_STRVAR(stringproxy_deepcopy__doc__,
5155
"__deepcopy__($self, memo, /)\n"
52-
"--\n"
53-
"\n");
56+
"--\n"
57+
"\n");
5458

5559
PyDoc_STRVAR(stringproxy_copy__doc__,
56-
"__copy__($self, /)\n"
57-
"--\n"
58-
"\n");
60+
"__copy__($self, /)\n"
61+
"--\n"
62+
"\n");
5963

6064
/**
6165
* @brief Struct for the other methods

mozcentral.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8a28ad54f9f516c41ceddfa7ea32368fccf4a0eb
1+
a283127a5d0aa005c54d339e8ca27414b55f079b

src/JSStringProxy.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212

1313
#include "include/StrType.hh"
1414

15-
15+
std::unordered_set<JSStringProxy *> jsStringProxies;
1616
extern JSContext *GLOBAL_CX;
1717

1818

1919
void JSStringProxyMethodDefinitions::JSStringProxy_dealloc(JSStringProxy *self)
2020
{
21+
jsStringProxies.erase(self);
2122
delete self->jsString;
2223
}
2324

src/PyBytesProxyHandler.cc

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,30 @@ static bool array_valueOf(JSContext *cx, unsigned argc, JS::Value *vp) {
2626
return false;
2727
}
2828

29-
JS::PersistentRootedObject* arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
29+
JS::PersistentRootedObject *arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
3030
JS::RootedObject rootedArrayBuffer(cx, arrayBuffer->get());
3131

3232
auto byteLength = JS::GetArrayBufferByteLength(rootedArrayBuffer);
3333

34-
bool isSharedMemory;
34+
bool isSharedMemory;
3535
JS::AutoCheckCannotGC autoNoGC(cx);
3636
uint8_t *data = JS::GetArrayBufferData(rootedArrayBuffer, &isSharedMemory, autoNoGC);
37-
37+
3838
size_t numberOfDigits = 0;
3939
for (size_t i = 0; i < byteLength; i++) {
40-
numberOfDigits += data[i] < 10 ? 1 : data[i] < 100 ? 2 : 3;
40+
numberOfDigits += data[i] < 10 ? 1 : data[i] < 100 ? 2 : 3;
4141
}
4242
const size_t STRING_LENGTH = byteLength + numberOfDigits;
43-
JS::Latin1Char* buffer = (JS::Latin1Char *)malloc(sizeof(JS::Latin1Char) * STRING_LENGTH);
44-
43+
JS::Latin1Char *buffer = (JS::Latin1Char *)malloc(sizeof(JS::Latin1Char) * STRING_LENGTH);
44+
4545
size_t charIndex = 0;
46-
sprintf((char*)&buffer[charIndex], "%d", data[0]);
46+
snprintf((char *)&buffer[charIndex], 4, "%d", data[0]);
4747
charIndex += data[0] < 10 ? 1 : data[0] < 100 ? 2 : 3;
4848

4949
for (size_t dataIndex = 1; dataIndex < byteLength; dataIndex++) {
5050
buffer[charIndex] = ',';
5151
charIndex++;
52-
sprintf((char*)&buffer[charIndex], "%d", data[dataIndex]);
52+
snprintf((char *)&buffer[charIndex], 4, "%d", data[dataIndex]);
5353
charIndex += data[dataIndex] < 10 ? 1 : data[dataIndex] < 100 ? 2 : 3;
5454
}
5555

@@ -84,7 +84,7 @@ static bool iterator_next(JSContext *cx, unsigned argc, JS::Value *vp) {
8484
JS::RootedObject thisObj(cx);
8585
if (!args.computeThis(cx, &thisObj)) return false;
8686

87-
JS::PersistentRootedObject* arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(thisObj, BytesIteratorSlotIteratedObject);
87+
JS::PersistentRootedObject *arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(thisObj, BytesIteratorSlotIteratedObject);
8888
JS::RootedObject rootedArrayBuffer(cx, arrayBuffer->get());
8989

9090
JS::RootedValue rootedNextIndex(cx, JS::GetReservedSlot(thisObj, BytesIteratorSlotNextIndex));
@@ -112,7 +112,7 @@ static bool iterator_next(JSContext *cx, unsigned argc, JS::Value *vp) {
112112
if (!JS_SetProperty(cx, result, "done", done)) return false;
113113

114114
if (itemKind == ITEM_KIND_VALUE) {
115-
bool isSharedMemory;
115+
bool isSharedMemory;
116116
JS::AutoCheckCannotGC autoNoGC(cx);
117117
uint8_t *data = JS::GetArrayBufferData(rootedArrayBuffer, &isSharedMemory, autoNoGC);
118118

@@ -125,7 +125,7 @@ static bool iterator_next(JSContext *cx, unsigned argc, JS::Value *vp) {
125125
JS::RootedValue rootedNextIndex(cx, JS::Int32Value(nextIndex));
126126
items[0].set(rootedNextIndex);
127127

128-
bool isSharedMemory;
128+
bool isSharedMemory;
129129
JS::AutoCheckCannotGC autoNoGC(cx);
130130
uint8_t *data = JS::GetArrayBufferData(rootedArrayBuffer, &isSharedMemory, autoNoGC);
131131

@@ -216,8 +216,8 @@ static bool array_iterator_func(JSContext *cx, unsigned argc, JS::Value *vp, int
216216
if (!JS::Construct(cx, constructor_val, JS::HandleValueArray::empty(), &obj)) return false;
217217
if (!obj) return false;
218218

219-
JS::PersistentRootedObject* arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
220-
219+
JS::PersistentRootedObject *arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
220+
221221
JS::SetReservedSlot(obj, BytesIteratorSlotIteratedObject, JS::PrivateValue(arrayBuffer));
222222
JS::SetReservedSlot(obj, BytesIteratorSlotNextIndex, JS::Int32Value(0));
223223
JS::SetReservedSlot(obj, BytesIteratorSlotItemKind, JS::Int32Value(itemKind));
@@ -253,13 +253,13 @@ bool PyBytesProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleI
253253
JS::HandleValue v, JS::HandleValue receiver,
254254
JS::ObjectOpResult &result) const {
255255

256-
// block all modifications
257-
256+
// block all modifications
257+
258258
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
259259

260260
PyErr_Format(PyExc_TypeError,
261-
"'%.100s' object has only read-only attributes",
262-
Py_TYPE(self)->tp_name);
261+
"'%.100s' object has only read-only attributes",
262+
Py_TYPE(self)->tp_name);
263263

264264
return result.failReadOnly();
265265
}
@@ -298,7 +298,7 @@ bool PyBytesProxyHandler::getOwnPropertyDescriptor(
298298

299299
// "length" and "byteLength" properties have the same value
300300
if ((JS_StringEqualsLiteral(cx, idString, "length", &isProperty) && isProperty) || (JS_StringEqualsLiteral(cx, id.toString(), "byteLength", &isProperty) && isProperty)) {
301-
JS::PersistentRootedObject* arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
301+
JS::PersistentRootedObject *arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
302302

303303
JS::RootedObject rootedArrayBuffer(cx, arrayBuffer->get());
304304

@@ -314,7 +314,7 @@ bool PyBytesProxyHandler::getOwnPropertyDescriptor(
314314

315315
// "buffer" property
316316
if (JS_StringEqualsLiteral(cx, idString, "buffer", &isProperty) && isProperty) {
317-
JS::PersistentRootedObject* arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
317+
JS::PersistentRootedObject *arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
318318

319319
desc.set(mozilla::Some(
320320
JS::PropertyDescriptor::Data(
@@ -392,10 +392,10 @@ bool PyBytesProxyHandler::getOwnPropertyDescriptor(
392392
// item
393393
Py_ssize_t index;
394394
if (idToIndex(cx, id, &index)) {
395-
JS::PersistentRootedObject* arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
395+
JS::PersistentRootedObject *arrayBuffer = JS::GetMaybePtrFromReservedSlot<JS::PersistentRootedObject>(proxy, OtherSlot);
396396
JS::RootedObject rootedArrayBuffer(cx, arrayBuffer->get());
397397

398-
bool isSharedMemory;
398+
bool isSharedMemory;
399399
JS::AutoCheckCannotGC autoNoGC(cx);
400400
uint8_t *data = JS::GetArrayBufferData(rootedArrayBuffer, &isSharedMemory, autoNoGC);
401401

@@ -406,7 +406,7 @@ bool PyBytesProxyHandler::getOwnPropertyDescriptor(
406406
));
407407

408408
return true;
409-
}
409+
}
410410

411411
PyObject *attrName = idToKey(cx, id);
412412
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);

src/PyListProxyHandler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,8 +2099,8 @@ void PyListProxyHandler::finalize(JS::GCContext *gcx, JSObject *proxy) const {
20992099
// We cannot call Py_DECREF here when shutting down as the thread state is gone.
21002100
// Then, when shutting down, there is only on reference left, and we don't need
21012101
// to free the object since the entire process memory is being released.
2102-
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
2103-
if (Py_REFCNT(self) > 1) {
2102+
if (!_Py_IsFinalizing()) {
2103+
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
21042104
Py_DECREF(self);
21052105
}
21062106
}

src/PyObjectProxyHandler.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ void PyObjectProxyHandler::finalize(JS::GCContext *gcx, JSObject *proxy) const {
8787
// We cannot call Py_DECREF here when shutting down as the thread state is gone.
8888
// Then, when shutting down, there is only on reference left, and we don't need
8989
// to free the object since the entire process memory is being released.
90-
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
91-
if (Py_REFCNT(self) > 1) {
90+
if (!_Py_IsFinalizing()) {
91+
PyObject *self = JS::GetMaybePtrFromReservedSlot<PyObject>(proxy, PyObjectSlot);
9292
Py_DECREF(self);
9393
}
9494
}
@@ -109,12 +109,12 @@ bool PyObjectProxyHandler::ownPropertyKeys(JSContext *cx, JS::HandleObject proxy
109109
}
110110

111111
return handleOwnPropertyKeys(cx, nonDunderKeys, PyList_Size(nonDunderKeys), props);
112-
}
112+
}
113113
else {
114114
if (PyErr_Occurred()) {
115-
PyErr_Clear();
115+
PyErr_Clear();
116116
}
117-
117+
118118
return handleOwnPropertyKeys(cx, PyList_New(0), 0, props);
119119
}
120120
}

src/StrType.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ PyObject *StrType::proxifyString(JSContext *cx, JS::HandleValue strVal) {
112112
JS::RootedObject obj(cx);
113113
pyString->jsString = new JS::PersistentRootedValue(cx);
114114
pyString->jsString->setString((JSString *)lstr);
115+
jsStringProxies.insert(pyString);
115116

116117
// Initialize as legacy string (https://github.com/python/cpython/blob/v3.12.0b1/Include/cpython/unicodeobject.h#L78-L93)
117118
// see https://github.com/python/cpython/blob/v3.11.3/Objects/unicodeobject.c#L1230-L1245

0 commit comments

Comments
 (0)