Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions Python/assemble.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ instr_size(instruction *instr)
}

struct assembler {
PyObject *a_bytecode; /* bytes containing bytecode */
PyBytesWriter *a_bytecode_writer; /* writer containing bytecode */
PyObject *a_bytecode; /* bytes containing bytecode */
int a_offset; /* offset into bytecode */
PyBytesWriter *a_except_table_writer; /* writer containing exception table */
PyObject *a_except_table; /* bytes containing exception table */
int a_except_table_off; /* offset into exception table */
/* Location Info */
Expand All @@ -64,38 +66,40 @@ assemble_init(struct assembler *a, int firstlineno)
{
memset(a, 0, sizeof(struct assembler));
a->a_lineno = firstlineno;
a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
if (a->a_bytecode == NULL) {
a->a_bytecode_writer = PyBytesWriter_Create(DEFAULT_CODE_SIZE);
if (a->a_bytecode_writer == NULL) {
goto error;
}
a->a_linetable_writer = PyBytesWriter_Create(DEFAULT_CNOTAB_SIZE);
if (a->a_linetable_writer == NULL) {
goto error;
}
a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
if (a->a_except_table == NULL) {
a->a_except_table_writer = PyBytesWriter_Create(DEFAULT_LNOTAB_SIZE);
if (a->a_except_table_writer == NULL) {
goto error;
}
return SUCCESS;
error:
Py_CLEAR(a->a_bytecode);
PyBytesWriter_Discard(a->a_bytecode_writer);
PyBytesWriter_Discard(a->a_linetable_writer);
Py_CLEAR(a->a_except_table);
PyBytesWriter_Discard(a->a_except_table_writer);
return ERROR;
}

static void
assemble_free(struct assembler *a)
{
Py_XDECREF(a->a_bytecode);
PyBytesWriter_Discard(a->a_bytecode_writer);
PyBytesWriter_Discard(a->a_linetable_writer);
PyBytesWriter_Discard(a->a_except_table_writer);
Py_XDECREF(a->a_bytecode);
Py_XDECREF(a->a_linetable);
Py_XDECREF(a->a_except_table);
}

static inline void
write_except_byte(struct assembler *a, int byte) {
unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table);
unsigned char *p = (unsigned char *) PyBytesWriter_GetData(a->a_except_table_writer);
p[a->a_except_table_off++] = byte;
}

Expand Down Expand Up @@ -133,9 +137,9 @@ assemble_emit_exception_table_entry(struct assembler *a, int start, int end,
int handler_offset,
_PyExceptHandlerInfo *handler)
{
Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table);
Py_ssize_t len = PyBytesWriter_GetSize(a->a_except_table_writer);
if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) {
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, len * 2));
RETURN_IF_ERROR(PyBytesWriter_Resize(a->a_except_table_writer, len * 2));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about PyBytesWriter_Grow(..., a->a_except_table_off + MAX_SIZE_OF_ENTRY)?

}
int size = end-start;
assert(end > start);
Expand Down Expand Up @@ -412,7 +416,7 @@ write_instr(_Py_CODEUNIT *codestr, instruction *instr, int ilen)
static int
assemble_emit_instr(struct assembler *a, instruction *instr)
{
Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
Py_ssize_t len = PyBytesWriter_GetSize(a->a_bytecode_writer);
_Py_CODEUNIT *code;

int size = instr_size(instr);
Expand All @@ -421,9 +425,9 @@ assemble_emit_instr(struct assembler *a, instruction *instr)
PyErr_NoMemory();
return ERROR;
}
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, len * 2));
RETURN_IF_ERROR(PyBytesWriter_Resize(a->a_bytecode_writer, len * 2));
}
code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
code = (_Py_CODEUNIT *)PyBytesWriter_GetData(a->a_bytecode_writer) + a->a_offset;
a->a_offset += size;
write_instr(code, instr, size);
return SUCCESS;
Expand All @@ -444,7 +448,12 @@ assemble_emit(struct assembler *a, instr_sequence *instrs,

RETURN_IF_ERROR(assemble_exception_table(a, instrs));

RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off));
a->a_except_table = PyBytesWriter_FinishWithSize(a->a_except_table_writer,
a->a_except_table_off);
a->a_except_table_writer = NULL;
if (a->a_except_table == NULL) {
return ERROR;
}
RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_except_table));

a->a_linetable = PyBytesWriter_FinishWithSize(a->a_linetable_writer,
Expand All @@ -455,7 +464,12 @@ assemble_emit(struct assembler *a, instr_sequence *instrs,
}
RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable));

RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT)));
a->a_bytecode = PyBytesWriter_FinishWithSize(a->a_bytecode_writer,
a->a_offset * sizeof(_Py_CODEUNIT));
a->a_bytecode_writer = NULL;
if (a->a_bytecode == NULL) {
return ERROR;
}
RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_bytecode));
return SUCCESS;
}
Expand Down
Loading