Skip to content

Commit e9f7ca1

Browse files
committed
Fix stuff for references (still no working hydration)
1 parent e10e592 commit e9f7ca1

File tree

4 files changed

+32
-13
lines changed

4 files changed

+32
-13
lines changed

Include/cpython/code.h

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct PyCodeObject {
112112
/* Hydration */
113113
struct context *co_hydra_context;
114114
Py_ssize_t co_hydra_offset;
115+
Py_ssize_t co_hydra_refs_pos;
115116

116117
};
117118

Include/internal/pycore_code.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,9 @@ struct _PyCodeConstructor {
243243
PyObject *exceptiontable;
244244

245245
/* Hydration */
246-
struct context *hydra_context;
247-
Py_ssize_t hydra_offset;
246+
struct context *hydra_context; // Hydration context
247+
Py_ssize_t hydra_offset; // Index in data stream where to start
248+
Py_ssize_t hydra_refs_pos; // Where to reset refs_pos
248249
};
249250

250251
// Using an "arguments struct" like this is helpful for maintainability

Objects/codeobject.c

+1
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
366366
/* hydration */
367367
co->co_hydra_context = con->hydra_context;
368368
co->co_hydra_offset = con->hydra_offset;
369+
co->co_hydra_refs_pos = con->hydra_refs_pos;
369370

370371
/* derived values */
371372
co->co_varnames = NULL;

Python/marshal.c

+27-11
Original file line numberDiff line numberDiff line change
@@ -1405,11 +1405,14 @@ r_object(RFILE *p)
14051405
PyObject* columntable = NULL;
14061406
PyObject *exceptiontable = NULL;
14071407
struct _PyCodeConstructor con = { 0 }; // All zeros
1408+
Py_ssize_t first_ref = -1;
14081409

1410+
assert(flag == 0); // We don't handle references to code objects
14091411
v = NULL;
14101412

14111413
/* XXX ignore long->int overflows for now */
14121414
const char *save_ptr = p->ptr;
1415+
Py_ssize_t save_refs_pos = p->refs_pos;
14131416

14141417
datasize = (int)r_long(p);
14151418
if (PyErr_Occurred())
@@ -1422,9 +1425,8 @@ r_object(RFILE *p)
14221425
if (PyErr_Occurred())
14231426
goto code_error;
14241427
posonlyargcount = (int)r_long(p);
1425-
if (PyErr_Occurred()) {
1428+
if (PyErr_Occurred())
14261429
goto code_error;
1427-
}
14281430
kwonlyargcount = (int)r_long(p);
14291431
if (PyErr_Occurred())
14301432
goto code_error;
@@ -1434,10 +1436,10 @@ r_object(RFILE *p)
14341436
flags = (int)r_long(p);
14351437
if (PyErr_Occurred())
14361438
goto code_error;
1437-
14381439
firstlineno = (int)r_long(p);
1439-
if (firstlineno == -1 && PyErr_Occurred())
1440-
break;
1440+
if (PyErr_Occurred())
1441+
goto code_error;
1442+
14411443
name = r_object(p);
14421444
if (name == NULL)
14431445
goto code_error;
@@ -1461,14 +1463,21 @@ r_object(RFILE *p)
14611463
PyCodeObject *to_update = NULL;
14621464

14631465
if (p->ctx != NULL && p->ctx->code == NULL) {
1464-
assert(nrefs == 0);
1465-
p->ptr = save_ptr + datasize;
1466-
1466+
// Return a dehydrated code object
14671467
con.hydra_context = p->ctx;
14681468
con.hydra_offset = save_ptr - 1 - p->ctx->buf; // Back up over typecode
1469+
con.hydra_refs_pos = save_refs_pos;
1470+
p->ptr = save_ptr + datasize;
1471+
while (p->refs_pos < save_refs_pos + nrefs) {
1472+
Py_ssize_t ref = r_ref_reserve(FLAG_REF, p);
1473+
if (first_ref < 0)
1474+
first_ref = ref;
1475+
}
1476+
// We'll call r_ref_insert() below
14691477
}
14701478
else {
14711479
if (p->ctx != NULL && p->ctx->code != NULL) {
1480+
// Rehydrating
14721481
to_update = p->ctx->code;
14731482
p->ctx->code = NULL;
14741483
}
@@ -1511,7 +1520,7 @@ r_object(RFILE *p)
15111520
con.exceptiontable = exceptiontable;
15121521

15131522
if (_PyCode_Validate(&con) < 0) {
1514-
printf("Failed to validate\n");
1523+
printf("Failed to validate code object\n"); // TODO: delete
15151524
goto code_error;
15161525
}
15171526
};
@@ -1523,11 +1532,17 @@ r_object(RFILE *p)
15231532
v = (PyObject *)_PyCode_New(&con);
15241533
}
15251534
if (v == NULL) {
1526-
printf("Failed to create\n");
1535+
printf("Failed to create code object\n"); // TODO: delete
15271536
goto code_error;
15281537
}
15291538

1530-
v = r_ref_insert(v, idx, flag, p); // TODO: NO
1539+
if (first_ref >= 0) {
1540+
// Overwrite skipped references with v
1541+
assert(p->ctx != NULL && p->ctx->code == NULL);
1542+
while (first_ref < p->refs_pos) {
1543+
r_ref_insert(v, first_ref++, FLAG_REF, p);
1544+
}
1545+
}
15311546

15321547
code_error:
15331548
Py_XDECREF(code);
@@ -1960,6 +1975,7 @@ _PyCode_Hydrate(PyCodeObject *code)
19601975
rf.end = s + n;
19611976
rf.depth = 0;
19621977
rf.refs = ctx->refs;
1978+
rf.refs_pos = code->co_hydra_refs_pos;
19631979
rf.ctx = ctx;
19641980
ctx->code = code;
19651981

0 commit comments

Comments
 (0)