py, compiler: Improve passes; add an extra pass for native emitter.

This commit is contained in:
Damien George 2014-05-07 17:24:22 +01:00
parent ca25c15d56
commit 36db6bcf54
12 changed files with 216 additions and 201 deletions

View File

@ -42,7 +42,7 @@
#define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800) #define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)
struct _asm_thumb_t { struct _asm_thumb_t {
int pass; uint pass;
uint code_offset; uint code_offset;
uint code_size; uint code_size;
byte *code_base; byte *code_base;
@ -58,14 +58,9 @@ struct _asm_thumb_t {
asm_thumb_t *asm_thumb_new(uint max_num_labels) { asm_thumb_t *asm_thumb_new(uint max_num_labels) {
asm_thumb_t *as; asm_thumb_t *as;
as = m_new(asm_thumb_t, 1); as = m_new0(asm_thumb_t, 1);
as->pass = 0;
as->code_offset = 0;
as->code_size = 0;
as->code_base = NULL;
as->max_num_labels = max_num_labels; as->max_num_labels = max_num_labels;
as->label_offsets = m_new(int, max_num_labels); as->label_offsets = m_new(int, max_num_labels);
as->num_locals = 0;
return as; return as;
} }
@ -89,16 +84,16 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) {
m_del_obj(asm_thumb_t, as); m_del_obj(asm_thumb_t, as);
} }
void asm_thumb_start_pass(asm_thumb_t *as, int pass) { void asm_thumb_start_pass(asm_thumb_t *as, uint pass) {
as->pass = pass; as->pass = pass;
as->code_offset = 0; as->code_offset = 0;
if (pass == ASM_THUMB_PASS_2) { if (pass == ASM_THUMB_PASS_COMPUTE) {
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int)); memset(as->label_offsets, -1, as->max_num_labels * sizeof(int));
} }
} }
void asm_thumb_end_pass(asm_thumb_t *as) { void asm_thumb_end_pass(asm_thumb_t *as) {
if (as->pass == ASM_THUMB_PASS_2) { if (as->pass == ASM_THUMB_PASS_COMPUTE) {
// calculate size of code in bytes // calculate size of code in bytes
as->code_size = as->code_offset; as->code_size = as->code_offset;
as->code_base = m_new(byte, as->code_size); as->code_base = m_new(byte, as->code_size);
@ -120,7 +115,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) {
// all functions must go through this one to emit bytes // all functions must go through this one to emit bytes
STATIC byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int num_bytes_to_write) { STATIC byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int num_bytes_to_write) {
//printf("emit %d\n", num_bytes_to_write); //printf("emit %d\n", num_bytes_to_write);
if (as->pass < ASM_THUMB_PASS_3) { if (as->pass < ASM_THUMB_PASS_EMIT) {
as->code_offset += num_bytes_to_write; as->code_offset += num_bytes_to_write;
return as->dummy_data; return as->dummy_data;
} else { } else {
@ -224,12 +219,12 @@ void asm_thumb_exit(asm_thumb_t *as) {
void asm_thumb_label_assign(asm_thumb_t *as, uint label) { void asm_thumb_label_assign(asm_thumb_t *as, uint label) {
assert(label < as->max_num_labels); assert(label < as->max_num_labels);
if (as->pass == ASM_THUMB_PASS_2) { if (as->pass < ASM_THUMB_PASS_EMIT) {
// assign label offset // assign label offset
assert(as->label_offsets[label] == -1); assert(as->label_offsets[label] == -1);
as->label_offsets[label] = as->code_offset; as->label_offsets[label] = as->code_offset;
} else if (as->pass == ASM_THUMB_PASS_3) { } else {
// ensure label offset has not changed from PASS_2 to PASS_3 // ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset); //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
assert(as->label_offsets[label] == as->code_offset); assert(as->label_offsets[label] == as->code_offset);
} }
@ -383,20 +378,35 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) {
} }
} }
// i32 is stored as a full word in the code, and aligned to machine-word boundary
// TODO this is very inefficient, improve it!
void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32) {
// align on machine-word + 2
if ((as->code_offset & 3) == 0) {
asm_thumb_op16(as, ASM_THUMB_OP_NOP);
}
// jump over the i32 value (instruction prefect adds 4 to PC)
asm_thumb_op16(as, OP_B_N(0));
// store i32 on machine-word aligned boundary
asm_thumb_data(as, 4, i32);
// do the actual load of the i32 value
asm_thumb_mov_reg_i32_optimised(as, reg_dest, i32);
}
#define OP_STR_TO_SP_OFFSET(rlo_dest, word_offset) (0x9000 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) #define OP_STR_TO_SP_OFFSET(rlo_dest, word_offset) (0x9000 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
#define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) #define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) { void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) {
assert(rlo_src < REG_R8); assert(rlo_src < REG_R8);
int word_offset = as->num_locals - local_num - 1; int word_offset = as->num_locals - local_num - 1;
assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset)); asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset));
} }
void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) { void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
assert(rlo_dest < REG_R8); assert(rlo_dest < REG_R8);
int word_offset = as->num_locals - local_num - 1; int word_offset = as->num_locals - local_num - 1;
assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset)); asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset));
} }
@ -405,7 +415,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) { void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) {
assert(rlo_dest < REG_R8); assert(rlo_dest < REG_R8);
int word_offset = as->num_locals - local_num - 1; int word_offset = as->num_locals - local_num - 1;
assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset)); asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset));
} }

View File

@ -24,9 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define ASM_THUMB_PASS_1 (1) #define ASM_THUMB_PASS_COMPUTE (1)
#define ASM_THUMB_PASS_2 (2) #define ASM_THUMB_PASS_EMIT (2)
#define ASM_THUMB_PASS_3 (3)
#define REG_R0 (0) #define REG_R0 (0)
#define REG_R1 (1) #define REG_R1 (1)
@ -71,7 +70,7 @@ typedef struct _asm_thumb_t asm_thumb_t;
asm_thumb_t *asm_thumb_new(uint max_num_labels); asm_thumb_t *asm_thumb_new(uint max_num_labels);
void asm_thumb_free(asm_thumb_t *as, bool free_code); void asm_thumb_free(asm_thumb_t *as, bool free_code);
void asm_thumb_start_pass(asm_thumb_t *as, int pass); void asm_thumb_start_pass(asm_thumb_t *as, uint pass);
void asm_thumb_end_pass(asm_thumb_t *as); void asm_thumb_end_pass(asm_thumb_t *as);
uint asm_thumb_get_code_size(asm_thumb_t *as); uint asm_thumb_get_code_size(asm_thumb_t *as);
void *asm_thumb_get_code(asm_thumb_t *as); void *asm_thumb_get_code(asm_thumb_t *as);
@ -188,6 +187,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);
void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, machine_uint_t i32_src); // convenience void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, machine_uint_t i32_src); // convenience
void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32_src); // convenience void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32_src); // convenience
void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32); // convenience
void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src); // convenience void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src); // convenience
void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience
void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience

View File

@ -112,7 +112,7 @@
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80) #define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
struct _asm_x64_t { struct _asm_x64_t {
int pass; uint pass;
uint code_offset; uint code_offset;
uint code_size; uint code_size;
byte *code_base; byte *code_base;
@ -138,14 +138,9 @@ void *alloc_mem(uint req_size, uint *alloc_size, bool is_exec) {
asm_x64_t *asm_x64_new(uint max_num_labels) { asm_x64_t *asm_x64_new(uint max_num_labels) {
asm_x64_t *as; asm_x64_t *as;
as = m_new(asm_x64_t, 1); as = m_new0(asm_x64_t, 1);
as->pass = 0;
as->code_offset = 0;
as->code_size = 0;
as->code_base = NULL;
as->max_num_labels = max_num_labels; as->max_num_labels = max_num_labels;
as->label_offsets = m_new(int, max_num_labels); as->label_offsets = m_new(int, max_num_labels);
as->num_locals = 0;
return as; return as;
} }
@ -170,17 +165,17 @@ void asm_x64_free(asm_x64_t *as, bool free_code) {
m_del_obj(asm_x64_t, as); m_del_obj(asm_x64_t, as);
} }
void asm_x64_start_pass(asm_x64_t *as, int pass) { void asm_x64_start_pass(asm_x64_t *as, uint pass) {
as->pass = pass; as->pass = pass;
as->code_offset = 0; as->code_offset = 0;
if (pass == ASM_X64_PASS_2) { if (pass == ASM_X64_PASS_COMPUTE) {
// reset all labels // reset all labels
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int)); memset(as->label_offsets, -1, as->max_num_labels * sizeof(int));
} }
} }
void asm_x64_end_pass(asm_x64_t *as) { void asm_x64_end_pass(asm_x64_t *as) {
if (as->pass == ASM_X64_PASS_2) { if (as->pass == ASM_X64_PASS_COMPUTE) {
// calculate size of code in bytes // calculate size of code in bytes
as->code_size = as->code_offset; as->code_size = as->code_offset;
//as->code_base = m_new(byte, as->code_size); need to allocale executable memory //as->code_base = m_new(byte, as->code_size); need to allocale executable memory
@ -204,7 +199,7 @@ void asm_x64_end_pass(asm_x64_t *as) {
// all functions must go through this one to emit bytes // all functions must go through this one to emit bytes
STATIC byte *asm_x64_get_cur_to_write_bytes(asm_x64_t *as, int num_bytes_to_write) { STATIC byte *asm_x64_get_cur_to_write_bytes(asm_x64_t *as, int num_bytes_to_write) {
//printf("emit %d\n", num_bytes_to_write); //printf("emit %d\n", num_bytes_to_write);
if (as->pass < ASM_X64_PASS_3) { if (as->pass < ASM_X64_PASS_EMIT) {
as->code_offset += num_bytes_to_write; as->code_offset += num_bytes_to_write;
return as->dummy_data; return as->dummy_data;
} else { } else {
@ -367,6 +362,15 @@ void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r
} }
} }
// src_i64 is stored as a full word in the code, and aligned to machine-word boundary
void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64) {
// mov instruction uses 2 bytes for the instruction, before the i64
while (((as->code_offset + 2) & (WORD_SIZE - 1)) != 0) {
asm_x64_nop(as);
}
asm_x64_mov_i64_to_r64(as, src_i64, dest_r64);
}
void asm_x64_mov_i32_to_disp(asm_x64_t *as, int src_i32, int dest_r32, int dest_disp) void asm_x64_mov_i32_to_disp(asm_x64_t *as, int src_i32, int dest_r32, int dest_disp)
{ {
assert(0); assert(0);
@ -487,12 +491,12 @@ void asm_x64_setcc_r8(asm_x64_t *as, int jcc_type, int dest_r8) {
void asm_x64_label_assign(asm_x64_t *as, int label) { void asm_x64_label_assign(asm_x64_t *as, int label) {
assert(label < as->max_num_labels); assert(label < as->max_num_labels);
if (as->pass == ASM_X64_PASS_2) { if (as->pass < ASM_X64_PASS_EMIT) {
// assign label offset // assign label offset
assert(as->label_offsets[label] == -1); assert(as->label_offsets[label] == -1);
as->label_offsets[label] = as->code_offset; as->label_offsets[label] = as->code_offset;
} else if (as->pass == ASM_X64_PASS_3) { } else {
// ensure label offset has not changed from PASS_2 to PASS_3 // ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset); //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
assert(as->label_offsets[label] == as->code_offset); assert(as->label_offsets[label] == as->code_offset);
} }

View File

@ -24,9 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define ASM_X64_PASS_1 (1) #define ASM_X64_PASS_COMPUTE (1)
#define ASM_X64_PASS_2 (2) #define ASM_X64_PASS_EMIT (2)
#define ASM_X64_PASS_3 (3)
#define REG_RAX (0) #define REG_RAX (0)
#define REG_RCX (1) #define REG_RCX (1)
@ -54,7 +53,7 @@ typedef struct _asm_x64_t asm_x64_t;
asm_x64_t* asm_x64_new(uint max_num_labels); asm_x64_t* asm_x64_new(uint max_num_labels);
void asm_x64_free(asm_x64_t* as, bool free_code); void asm_x64_free(asm_x64_t* as, bool free_code);
void asm_x64_start_pass(asm_x64_t *as, int pass); void asm_x64_start_pass(asm_x64_t *as, uint pass);
void asm_x64_end_pass(asm_x64_t *as); void asm_x64_end_pass(asm_x64_t *as);
uint asm_x64_get_code_size(asm_x64_t* as); uint asm_x64_get_code_size(asm_x64_t* as);
void* asm_x64_get_code(asm_x64_t* as); void* asm_x64_get_code(asm_x64_t* as);
@ -71,6 +70,7 @@ void asm_x64_mov_i32_to_r64(asm_x64_t* as, int src_i32, int dest_r64);
void asm_x64_mov_i64_to_r64(asm_x64_t* as, int64_t src_i64, int dest_r64); void asm_x64_mov_i64_to_r64(asm_x64_t* as, int64_t src_i64, int dest_r64);
void asm_x64_mov_i32_to_disp(asm_x64_t* as, int src_i32, int dest_r32, int dest_disp); void asm_x64_mov_i32_to_disp(asm_x64_t* as, int src_i32, int dest_r32, int dest_disp);
void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r64); void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r64);
void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64);
void asm_x64_xor_r64_to_r64(asm_x64_t *as, int src_r64, int dest_r64); void asm_x64_xor_r64_to_r64(asm_x64_t *as, int src_r64, int dest_r64);
void asm_x64_add_r64_to_r64(asm_x64_t* as, int src_r64, int dest_r64); void asm_x64_add_r64_to_r64(asm_x64_t* as, int src_r64, int dest_r64);
void asm_x64_add_i32_to_r32(asm_x64_t* as, int src_i32, int dest_r32); void asm_x64_add_i32_to_r32(asm_x64_t* as, int src_i32, int dest_r32);

View File

@ -994,7 +994,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
// leaves function object on stack // leaves function object on stack
// returns function name // returns function name
qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) { qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this function // create a new scope for this function
scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options); scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options);
// store the function scope so the compiling function can use it at each pass // store the function scope so the compiling function can use it at each pass
@ -1043,7 +1043,7 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
// leaves class object on stack // leaves class object on stack
// returns class name // returns class name
qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) { qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this class // create a new scope for this class
scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (mp_parse_node_t)pns, emit_options); scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (mp_parse_node_t)pns, emit_options);
// store the class scope so the compiling function can use it at each pass // store the class scope so the compiling function can use it at each pass
@ -1510,7 +1510,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
} }
void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
scope_declare_global(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); scope_declare_global(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
} else { } else {
@ -1524,7 +1524,7 @@ void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
} }
void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
scope_declare_nonlocal(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); scope_declare_nonlocal(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
} else { } else {
@ -2056,7 +2056,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren) && MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren)
&& MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2]) && MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2])
) { ) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
qstr const_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); qstr const_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
if (!MP_PARSE_NODE_IS_SMALL_INT(((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0])) { if (!MP_PARSE_NODE_IS_SMALL_INT(((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0])) {
@ -2153,7 +2153,7 @@ void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
//mp_parse_node_t pn_params = pns->nodes[0]; //mp_parse_node_t pn_params = pns->nodes[0];
//mp_parse_node_t pn_body = pns->nodes[1]; //mp_parse_node_t pn_body = pns->nodes[1];
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this lambda // create a new scope for this lambda
scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (mp_parse_node_t)pns, comp->scope_cur->emit_options); scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (mp_parse_node_t)pns, comp->scope_cur->emit_options);
// store the lambda scope so the compiling function (this one) can use it at each pass // store the lambda scope so the compiling function (this one) can use it at each pass
@ -2499,7 +2499,7 @@ void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)); assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1]; mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1];
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this comprehension // create a new scope for this comprehension
scope_t *s = scope_new_and_link(comp, kind, (mp_parse_node_t)pns, comp->scope_cur->emit_options); scope_t *s = scope_new_and_link(comp, kind, (mp_parse_node_t)pns, comp->scope_cur->emit_options);
// store the comprehension scope so the compiling function (this one) can use it at each pass // store the comprehension scope so the compiling function (this one) can use it at each pass
@ -3020,7 +3020,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
comp->next_label = 1; comp->next_label = 1;
EMIT_ARG(start_pass, pass, scope); EMIT_ARG(start_pass, pass, scope);
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// reset maximum stack sizes in scope // reset maximum stack sizes in scope
// they will be computed in this first pass // they will be computed in this first pass
scope->stack_size = 0; scope->stack_size = 0;
@ -3028,7 +3028,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
} }
#if MICROPY_EMIT_CPYTHON #if MICROPY_EMIT_CPYTHON
if (comp->pass == PASS_3) { if (comp->pass == MP_PASS_EMIT) {
scope_print_info(scope); scope_print_info(scope);
} }
#endif #endif
@ -3053,7 +3053,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// work out number of parameters, keywords and default parameters, and add them to the id_info array // work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc) // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
comp->have_star = false; comp->have_star = false;
apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param); apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
} }
@ -3073,7 +3073,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// work out number of parameters, keywords and default parameters, and add them to the id_info array // work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc) // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
comp->have_star = false; comp->have_star = false;
apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param); apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
} }
@ -3104,7 +3104,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
#else #else
qstr qstr_arg = MP_QSTR_; qstr qstr_arg = MP_QSTR_;
#endif #endif
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
bool added; bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added); id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
assert(added); assert(added);
@ -3141,7 +3141,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn;
assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef); assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
bool added; bool added;
id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added); id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added);
assert(added); assert(added);
@ -3177,6 +3177,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
} }
#if MICROPY_EMIT_INLINE_THUMB #if MICROPY_EMIT_INLINE_THUMB
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) { STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
comp->pass = pass; comp->pass = pass;
comp->scope_cur = scope; comp->scope_cur = scope;
@ -3187,7 +3188,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return; return;
} }
if (comp->pass > PASS_1) { if (comp->pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur); EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur);
} }
@ -3199,7 +3200,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
//qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name //qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
// parameters are in pns->nodes[1] // parameters are in pns->nodes[1]
if (comp->pass == PASS_2) { if (comp->pass == MP_PASS_CODE_SIZE) {
mp_parse_node_t *pn_params; mp_parse_node_t *pn_params;
int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params); int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params); scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params);
@ -3212,7 +3213,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
int num = list_get(&pn_body, PN_suite_block_stmts, &nodes); int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
/* /*
if (comp->pass == PASS_3) { if (comp->pass == MP_PASS_EMIT) {
//printf("----\n"); //printf("----\n");
scope_print_info(scope); scope_print_info(scope);
} }
@ -3250,7 +3251,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return; return;
} }
uint lab = comp_next_label(comp); uint lab = comp_next_label(comp);
if (pass > PASS_1) { if (pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0])); EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]));
} }
} else if (op == MP_QSTR_align) { } else if (op == MP_QSTR_align) {
@ -3258,7 +3259,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
compile_syntax_error(comp, nodes[i], "inline assembler 'align' requires 1 argument"); compile_syntax_error(comp, nodes[i], "inline assembler 'align' requires 1 argument");
return; return;
} }
if (pass > PASS_1) { if (pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(align, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0])); EMIT_INLINE_ASM_ARG(align, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]));
} }
} else if (op == MP_QSTR_data) { } else if (op == MP_QSTR_data) {
@ -3266,7 +3267,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
compile_syntax_error(comp, nodes[i], "inline assembler 'data' requires at least 2 arguments"); compile_syntax_error(comp, nodes[i], "inline assembler 'data' requires at least 2 arguments");
return; return;
} }
if (pass > PASS_1) { if (pass > MP_PASS_SCOPE) {
machine_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]); machine_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
for (uint i = 1; i < n_args; i++) { for (uint i = 1; i < n_args; i++) {
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[i])) { if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[i])) {
@ -3277,13 +3278,13 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
} }
} }
} else { } else {
if (pass > PASS_1) { if (pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg); EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg);
} }
} }
} }
if (comp->pass > PASS_1) { if (comp->pass > MP_PASS_SCOPE) {
bool success = EMIT_INLINE_ASM(end_pass); bool success = EMIT_INLINE_ASM(end_pass);
if (!success) { if (!success) {
comp->had_error = true; comp->had_error = true;
@ -3438,10 +3439,10 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
if (false) { if (false) {
#if MICROPY_EMIT_INLINE_THUMB #if MICROPY_EMIT_INLINE_THUMB
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) { } else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
compile_scope_inline_asm(comp, s, PASS_1); compile_scope_inline_asm(comp, s, MP_PASS_SCOPE);
#endif #endif
} else { } else {
compile_scope(comp, s, PASS_1); compile_scope(comp, s, MP_PASS_SCOPE);
} }
// update maximim number of labels needed // update maximim number of labels needed
@ -3482,9 +3483,9 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
comp->emit_method_table = NULL; comp->emit_method_table = NULL;
comp->emit_inline_asm = emit_inline_thumb; comp->emit_inline_asm = emit_inline_thumb;
comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table; comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
compile_scope_inline_asm(comp, s, PASS_2); compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
if (!comp->had_error) { if (!comp->had_error) {
compile_scope_inline_asm(comp, s, PASS_3); compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
} }
#endif #endif
@ -3514,6 +3515,10 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
#endif #endif
comp->emit = emit_native; comp->emit = emit_native;
comp->emit_method_table->set_native_types(comp->emit, s->emit_options == MP_EMIT_OPT_VIPER); comp->emit_method_table->set_native_types(comp->emit, s->emit_options == MP_EMIT_OPT_VIPER);
// native emitters need an extra pass to compute stack size
compile_scope(comp, s, MP_PASS_STACK_SIZE);
break; break;
#endif // MICROPY_EMIT_NATIVE #endif // MICROPY_EMIT_NATIVE
@ -3527,10 +3532,14 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
} }
#endif // !MICROPY_EMIT_CPYTHON #endif // !MICROPY_EMIT_CPYTHON
// compile pass 2 and pass 3 // second last pass: compute code size
compile_scope(comp, s, PASS_2);
if (!comp->had_error) { if (!comp->had_error) {
compile_scope(comp, s, PASS_3); compile_scope(comp, s, MP_PASS_CODE_SIZE);
}
// final pass: emit code
if (!comp->had_error) {
compile_scope(comp, s, MP_PASS_EMIT);
} }
} }
} }

View File

@ -35,9 +35,10 @@
*/ */
typedef enum { typedef enum {
PASS_1 = 1, // work out id's and their kind, and number of labels MP_PASS_SCOPE = 1, // work out id's and their kind, and number of labels
PASS_2 = 2, // work out stack size and code size and label offsets MP_PASS_STACK_SIZE = 2, // work out maximum stack size
PASS_3 = 3, // emit code MP_PASS_CODE_SIZE = 3, // work out code size and label offsets
MP_PASS_EMIT = 4, // emit code
} pass_kind_t; } pass_kind_t;
#define MP_EMIT_STAR_FLAG_SINGLE (0x01) #define MP_EMIT_STAR_FLAG_SINGLE (0x01)

View File

@ -83,7 +83,7 @@ void emit_bc_free(emit_t *emit) {
// all functions must go through this one to emit code info // all functions must go through this one to emit code info
STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_write) { STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_write) {
//printf("emit %d\n", num_bytes_to_write); //printf("emit %d\n", num_bytes_to_write);
if (emit->pass < PASS_3) { if (emit->pass < MP_PASS_EMIT) {
emit->code_info_offset += num_bytes_to_write; emit->code_info_offset += num_bytes_to_write;
return emit->dummy_data; return emit->dummy_data;
} else { } else {
@ -123,7 +123,7 @@ STATIC void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, u
// all functions must go through this one to emit byte code // all functions must go through this one to emit byte code
STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_write) { STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_write) {
//printf("emit %d\n", num_bytes_to_write); //printf("emit %d\n", num_bytes_to_write);
if (emit->pass < PASS_3) { if (emit->pass < MP_PASS_EMIT) {
emit->byte_code_offset += num_bytes_to_write; emit->byte_code_offset += num_bytes_to_write;
return emit->dummy_data; return emit->dummy_data;
} else { } else {
@ -221,7 +221,7 @@ STATIC void emit_write_byte_code_byte_qstr(emit_t* emit, byte b, qstr qstr) {
// unsigned labels are relative to ip following this instruction, stored as 16 bits // unsigned labels are relative to ip following this instruction, stored as 16 bits
STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint label) { STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint label) {
uint byte_code_offset; uint byte_code_offset;
if (emit->pass < PASS_3) { if (emit->pass < MP_PASS_EMIT) {
byte_code_offset = 0; byte_code_offset = 0;
} else { } else {
byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3; byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3;
@ -235,7 +235,7 @@ STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint
// signed labels are relative to ip following this instruction, stored as 16 bits, in excess // signed labels are relative to ip following this instruction, stored as 16 bits, in excess
STATIC void emit_write_byte_code_byte_signed_label(emit_t* emit, byte b1, uint label) { STATIC void emit_write_byte_code_byte_signed_label(emit_t* emit, byte b1, uint label) {
int byte_code_offset; int byte_code_offset;
if (emit->pass < PASS_3) { if (emit->pass < MP_PASS_EMIT) {
byte_code_offset = 0; byte_code_offset = 0;
} else { } else {
byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3 + 0x8000; byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3 + 0x8000;
@ -256,13 +256,13 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
emit->scope = scope; emit->scope = scope;
emit->last_source_line_offset = 0; emit->last_source_line_offset = 0;
emit->last_source_line = 1; emit->last_source_line = 1;
if (pass == PASS_2) { if (pass < MP_PASS_EMIT) {
memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint)); memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(uint));
} }
emit->byte_code_offset = 0; emit->byte_code_offset = 0;
emit->code_info_offset = 0; emit->code_info_offset = 0;
// write code info size (don't know size at this stage in PASS_2 so need to use maximum space (4 bytes) to write it) // write code info size; use maximum space (4 bytes) to write it; TODO possible optimise this
{ {
byte* c = emit_get_cur_to_write_code_info(emit, 4); byte* c = emit_get_cur_to_write_code_info(emit, 4);
machine_uint_t s = emit->code_info_size; machine_uint_t s = emit->code_info_size;
@ -319,13 +319,13 @@ STATIC void emit_bc_end_pass(emit_t *emit) {
*emit_get_cur_to_write_code_info(emit, 1) = 0; // end of line number info *emit_get_cur_to_write_code_info(emit, 1) = 0; // end of line number info
emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned
if (emit->pass == PASS_2) { if (emit->pass == MP_PASS_CODE_SIZE) {
// calculate size of code in bytes // calculate size of code in bytes
emit->code_info_size = emit->code_info_offset; emit->code_info_size = emit->code_info_offset;
emit->byte_code_size = emit->byte_code_offset; emit->byte_code_size = emit->byte_code_offset;
emit->code_base = m_new0(byte, emit->code_info_size + emit->byte_code_size); emit->code_base = m_new0(byte, emit->code_info_size + emit->byte_code_size);
} else if (emit->pass == PASS_3) { } else if (emit->pass == MP_PASS_EMIT) {
qstr *arg_names = m_new(qstr, emit->scope->num_pos_args + emit->scope->num_kwonly_args); qstr *arg_names = m_new(qstr, emit->scope->num_pos_args + emit->scope->num_kwonly_args);
for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) { for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) {
arg_names[i] = emit->scope->id_info[i].qstr; arg_names[i] = emit->scope->id_info[i].qstr;
@ -383,12 +383,12 @@ STATIC void emit_bc_pre(emit_t *emit, int stack_size_delta) {
STATIC void emit_bc_label_assign(emit_t *emit, uint l) { STATIC void emit_bc_label_assign(emit_t *emit, uint l) {
emit_bc_pre(emit, 0); emit_bc_pre(emit, 0);
assert(l < emit->max_num_labels); assert(l < emit->max_num_labels);
if (emit->pass == PASS_2) { if (emit->pass < MP_PASS_EMIT) {
// assign label offset // assign label offset
assert(emit->label_offsets[l] == -1); assert(emit->label_offsets[l] == -1);
emit->label_offsets[l] = emit->byte_code_offset; emit->label_offsets[l] = emit->byte_code_offset;
} else if (emit->pass == PASS_3) { } else {
// ensure label offset has not changed from PASS_2 to PASS_3 // ensure label offset has not changed from MP_PASS_CODE_SIZE to MP_PASS_EMIT
//printf("l%d: (at %d vs %d)\n", l, emit->byte_code_offset, emit->label_offsets[l]); //printf("l%d: (at %d vs %d)\n", l, emit->byte_code_offset, emit->label_offsets[l]);
assert(emit->label_offsets[l] == emit->byte_code_offset); assert(emit->label_offsets[l] == emit->byte_code_offset);
} }
@ -827,17 +827,13 @@ STATIC void emit_bc_raise_varargs(emit_t *emit, int n_args) {
STATIC void emit_bc_yield_value(emit_t *emit) { STATIC void emit_bc_yield_value(emit_t *emit) {
emit_bc_pre(emit, 0); emit_bc_pre(emit, 0);
if (emit->pass == PASS_2) {
emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
}
emit_write_byte_code_byte(emit, MP_BC_YIELD_VALUE); emit_write_byte_code_byte(emit, MP_BC_YIELD_VALUE);
} }
STATIC void emit_bc_yield_from(emit_t *emit) { STATIC void emit_bc_yield_from(emit_t *emit) {
emit_bc_pre(emit, -1); emit_bc_pre(emit, -1);
if (emit->pass == PASS_2) {
emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
}
emit_write_byte_code_byte(emit, MP_BC_YIELD_FROM); emit_write_byte_code_byte(emit, MP_BC_YIELD_FROM);
} }

View File

@ -72,7 +72,7 @@ STATIC void emit_cpy_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope)
emit->stack_size = 0; emit->stack_size = 0;
emit->last_emit_was_return_value = false; emit->last_emit_was_return_value = false;
emit->scope = scope; emit->scope = scope;
if (pass == PASS_2) { if (pass < MP_PASS_EMIT) {
memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(int)); memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(int));
} }
} }
@ -114,7 +114,7 @@ static void emit_pre(emit_t *emit, int stack_size_delta, int byte_code_size) {
emit->scope->stack_size = emit->stack_size; emit->scope->stack_size = emit->stack_size;
} }
emit->last_emit_was_return_value = false; emit->last_emit_was_return_value = false;
if (emit->pass == PASS_3 && byte_code_size > 0) { if (emit->pass == MP_PASS_EMIT && byte_code_size > 0) {
if (emit->byte_code_offset >= 1000) { if (emit->byte_code_offset >= 1000) {
printf("%d ", emit->byte_code_offset); printf("%d ", emit->byte_code_offset);
} else { } else {
@ -127,12 +127,12 @@ static void emit_pre(emit_t *emit, int stack_size_delta, int byte_code_size) {
STATIC void emit_cpy_label_assign(emit_t *emit, uint l) { STATIC void emit_cpy_label_assign(emit_t *emit, uint l) {
emit_pre(emit, 0, 0); emit_pre(emit, 0, 0);
assert(l < emit->max_num_labels); assert(l < emit->max_num_labels);
if (emit->pass == PASS_2) { if (emit->pass < PASS_EMIT) {
// assign label offset // assign label offset
assert(emit->label_offsets[l] == -1); assert(emit->label_offsets[l] == -1);
emit->label_offsets[l] = emit->byte_code_offset; emit->label_offsets[l] = emit->byte_code_offset;
} else if (emit->pass == PASS_3) { } else {
// ensure label offset has not changed from PASS_2 to PASS_3 // ensure label offset has not changed from MP_PASS_CODE_SIZE to MP_PASS_EMIT
assert(emit->label_offsets[l] == emit->byte_code_offset); assert(emit->label_offsets[l] == emit->byte_code_offset);
//printf("l%d: (at %d)\n", l, emit->byte_code_offset); //printf("l%d: (at %d)\n", l, emit->byte_code_offset);
} }
@ -140,28 +140,28 @@ STATIC void emit_cpy_label_assign(emit_t *emit, uint l) {
STATIC void emit_cpy_import_name(emit_t *emit, qstr qstr) { STATIC void emit_cpy_import_name(emit_t *emit, qstr qstr) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("IMPORT_NAME %s\n", qstr_str(qstr)); printf("IMPORT_NAME %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_import_from(emit_t *emit, qstr qstr) { STATIC void emit_cpy_import_from(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("IMPORT_FROM %s\n", qstr_str(qstr)); printf("IMPORT_FROM %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_import_star(emit_t *emit) { STATIC void emit_cpy_import_star(emit_t *emit) {
emit_pre(emit, -1, 1); emit_pre(emit, -1, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("IMPORT_STAR\n"); printf("IMPORT_STAR\n");
} }
} }
STATIC void emit_cpy_load_const_tok(emit_t *emit, mp_token_kind_t tok) { STATIC void emit_cpy_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST "); printf("LOAD_CONST ");
switch (tok) { switch (tok) {
case MP_TOKEN_KW_FALSE: printf("False"); break; case MP_TOKEN_KW_FALSE: printf("False"); break;
@ -175,21 +175,21 @@ STATIC void emit_cpy_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
STATIC void emit_cpy_load_const_small_int(emit_t *emit, machine_int_t arg) { STATIC void emit_cpy_load_const_small_int(emit_t *emit, machine_int_t arg) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST " INT_FMT "\n", arg); printf("LOAD_CONST " INT_FMT "\n", arg);
} }
} }
STATIC void emit_cpy_load_const_int(emit_t *emit, qstr qstr) { STATIC void emit_cpy_load_const_int(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST %s\n", qstr_str(qstr)); printf("LOAD_CONST %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_load_const_dec(emit_t *emit, qstr qstr) { STATIC void emit_cpy_load_const_dec(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST %s\n", qstr_str(qstr)); printf("LOAD_CONST %s\n", qstr_str(qstr));
} }
} }
@ -233,7 +233,7 @@ STATIC void print_quoted_str(qstr qstr, bool bytes) {
STATIC void emit_cpy_load_const_str(emit_t *emit, qstr qstr, bool bytes) { STATIC void emit_cpy_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST "); printf("LOAD_CONST ");
print_quoted_str(qstr, bytes); print_quoted_str(qstr, bytes);
printf("\n"); printf("\n");
@ -247,35 +247,35 @@ STATIC void emit_cpy_load_null(emit_t *emit) {
STATIC void emit_cpy_load_fast(emit_t *emit, qstr qstr, uint id_flags, int local_num) { STATIC void emit_cpy_load_fast(emit_t *emit, qstr qstr, uint id_flags, int local_num) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_FAST %d %s\n", local_num, qstr_str(qstr)); printf("LOAD_FAST %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_load_deref(emit_t *emit, qstr qstr, int local_num) { STATIC void emit_cpy_load_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_DEREF %d %s\n", local_num, qstr_str(qstr)); printf("LOAD_DEREF %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_load_name(emit_t *emit, qstr qstr) { STATIC void emit_cpy_load_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_NAME %s\n", qstr_str(qstr)); printf("LOAD_NAME %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_load_global(emit_t *emit, qstr qstr) { STATIC void emit_cpy_load_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_GLOBAL %s\n", qstr_str(qstr)); printf("LOAD_GLOBAL %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_load_attr(emit_t *emit, qstr qstr) { STATIC void emit_cpy_load_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_ATTR %s\n", qstr_str(qstr)); printf("LOAD_ATTR %s\n", qstr_str(qstr));
} }
} }
@ -286,140 +286,140 @@ STATIC void emit_cpy_load_method(emit_t *emit, qstr qstr) {
STATIC void emit_cpy_load_build_class(emit_t *emit) { STATIC void emit_cpy_load_build_class(emit_t *emit) {
emit_pre(emit, 1, 1); emit_pre(emit, 1, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_BUILD_CLASS\n"); printf("LOAD_BUILD_CLASS\n");
} }
} }
STATIC void emit_cpy_load_subscr(emit_t *emit) { STATIC void emit_cpy_load_subscr(emit_t *emit) {
emit_pre(emit, -1, 1); emit_pre(emit, -1, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BINARY_SUBSCR\n"); printf("BINARY_SUBSCR\n");
} }
} }
STATIC void emit_cpy_store_fast(emit_t *emit, qstr qstr, int local_num) { STATIC void emit_cpy_store_fast(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_FAST %d %s\n", local_num, qstr_str(qstr)); printf("STORE_FAST %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_store_deref(emit_t *emit, qstr qstr, int local_num) { STATIC void emit_cpy_store_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_DEREF %d %s\n", local_num, qstr_str(qstr)); printf("STORE_DEREF %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_store_name(emit_t *emit, qstr qstr) { STATIC void emit_cpy_store_name(emit_t *emit, qstr qstr) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_NAME %s\n", qstr_str(qstr)); printf("STORE_NAME %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_store_global(emit_t *emit, qstr qstr) { STATIC void emit_cpy_store_global(emit_t *emit, qstr qstr) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_GLOBAL %s\n", qstr_str(qstr)); printf("STORE_GLOBAL %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_store_attr(emit_t *emit, qstr qstr) { STATIC void emit_cpy_store_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, -2, 3); emit_pre(emit, -2, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_ATTR %s\n", qstr_str(qstr)); printf("STORE_ATTR %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_store_subscr(emit_t *emit) { STATIC void emit_cpy_store_subscr(emit_t *emit) {
emit_pre(emit, -3, 1); emit_pre(emit, -3, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_SUBSCR\n"); printf("STORE_SUBSCR\n");
} }
} }
STATIC void emit_cpy_delete_fast(emit_t *emit, qstr qstr, int local_num) { STATIC void emit_cpy_delete_fast(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DELETE_FAST %d %s\n", local_num, qstr_str(qstr)); printf("DELETE_FAST %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_delete_deref(emit_t *emit, qstr qstr, int local_num) { STATIC void emit_cpy_delete_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DELETE_DEREF %d %s\n", local_num, qstr_str(qstr)); printf("DELETE_DEREF %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_delete_name(emit_t *emit, qstr qstr) { STATIC void emit_cpy_delete_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DELETE_NAME %s\n", qstr_str(qstr)); printf("DELETE_NAME %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_delete_global(emit_t *emit, qstr qstr) { STATIC void emit_cpy_delete_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DELETE_GLOBAL %s\n", qstr_str(qstr)); printf("DELETE_GLOBAL %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_delete_attr(emit_t *emit, qstr qstr) { STATIC void emit_cpy_delete_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DELETE_ATTR %s\n", qstr_str(qstr)); printf("DELETE_ATTR %s\n", qstr_str(qstr));
} }
} }
STATIC void emit_cpy_delete_subscr(emit_t *emit) { STATIC void emit_cpy_delete_subscr(emit_t *emit) {
emit_pre(emit, -2, 1); emit_pre(emit, -2, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DELETE_SUBSCR\n"); printf("DELETE_SUBSCR\n");
} }
} }
STATIC void emit_cpy_dup_top(emit_t *emit) { STATIC void emit_cpy_dup_top(emit_t *emit) {
emit_pre(emit, 1, 1); emit_pre(emit, 1, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DUP_TOP\n"); printf("DUP_TOP\n");
} }
} }
STATIC void emit_cpy_dup_top_two(emit_t *emit) { STATIC void emit_cpy_dup_top_two(emit_t *emit) {
emit_pre(emit, 2, 1); emit_pre(emit, 2, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("DUP_TOP_TWO\n"); printf("DUP_TOP_TWO\n");
} }
} }
STATIC void emit_cpy_pop_top(emit_t *emit) { STATIC void emit_cpy_pop_top(emit_t *emit) {
emit_pre(emit, -1, 1); emit_pre(emit, -1, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("POP_TOP\n"); printf("POP_TOP\n");
} }
} }
STATIC void emit_cpy_rot_two(emit_t *emit) { STATIC void emit_cpy_rot_two(emit_t *emit) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("ROT_TWO\n"); printf("ROT_TWO\n");
} }
} }
STATIC void emit_cpy_rot_three(emit_t *emit) { STATIC void emit_cpy_rot_three(emit_t *emit) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("ROT_THREE\n"); printf("ROT_THREE\n");
} }
} }
STATIC void emit_cpy_jump(emit_t *emit, uint label) { STATIC void emit_cpy_jump(emit_t *emit, uint label) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
int dest = emit->label_offsets[label]; int dest = emit->label_offsets[label];
if (dest < emit->byte_code_offset) { if (dest < emit->byte_code_offset) {
printf("JUMP_ABSOLUTE %d\n", emit->label_offsets[label]); printf("JUMP_ABSOLUTE %d\n", emit->label_offsets[label]);
@ -431,35 +431,35 @@ STATIC void emit_cpy_jump(emit_t *emit, uint label) {
STATIC void emit_cpy_pop_jump_if_true(emit_t *emit, uint label) { STATIC void emit_cpy_pop_jump_if_true(emit_t *emit, uint label) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("POP_JUMP_IF_TRUE %d\n", emit->label_offsets[label]); printf("POP_JUMP_IF_TRUE %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_pop_jump_if_false(emit_t *emit, uint label) { STATIC void emit_cpy_pop_jump_if_false(emit_t *emit, uint label) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("POP_JUMP_IF_FALSE %d\n", emit->label_offsets[label]); printf("POP_JUMP_IF_FALSE %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_jump_if_true_or_pop(emit_t *emit, uint label) { STATIC void emit_cpy_jump_if_true_or_pop(emit_t *emit, uint label) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("JUMP_IF_TRUE_OR_POP %d\n", emit->label_offsets[label]); printf("JUMP_IF_TRUE_OR_POP %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_jump_if_false_or_pop(emit_t *emit, uint label) { STATIC void emit_cpy_jump_if_false_or_pop(emit_t *emit, uint label) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("JUMP_IF_FALSE_OR_POP %d\n", emit->label_offsets[label]); printf("JUMP_IF_FALSE_OR_POP %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_break_loop(emit_t *emit, uint label, int except_depth) { STATIC void emit_cpy_break_loop(emit_t *emit, uint label, int except_depth) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BREAK_LOOP\n"); printf("BREAK_LOOP\n");
} }
} }
@ -469,7 +469,7 @@ STATIC void emit_cpy_continue_loop(emit_t *emit, uint label, int except_depth) {
emit_cpy_jump(emit, label); emit_cpy_jump(emit, label);
} else { } else {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("CONTINUE_LOOP %d\n", emit->label_offsets[label]); printf("CONTINUE_LOOP %d\n", emit->label_offsets[label]);
} }
} }
@ -477,49 +477,49 @@ STATIC void emit_cpy_continue_loop(emit_t *emit, uint label, int except_depth) {
STATIC void emit_cpy_setup_with(emit_t *emit, uint label) { STATIC void emit_cpy_setup_with(emit_t *emit, uint label) {
emit_pre(emit, 7, 3); emit_pre(emit, 7, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("SETUP_WITH %d\n", emit->label_offsets[label]); printf("SETUP_WITH %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_with_cleanup(emit_t *emit) { STATIC void emit_cpy_with_cleanup(emit_t *emit) {
emit_pre(emit, -7, 1); emit_pre(emit, -7, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("WITH_CLEANUP\n"); printf("WITH_CLEANUP\n");
} }
} }
STATIC void emit_cpy_setup_except(emit_t *emit, uint label) { STATIC void emit_cpy_setup_except(emit_t *emit, uint label) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("SETUP_EXCEPT %d\n", emit->label_offsets[label]); printf("SETUP_EXCEPT %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_setup_finally(emit_t *emit, uint label) { STATIC void emit_cpy_setup_finally(emit_t *emit, uint label) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("SETUP_FINALLY %d\n", emit->label_offsets[label]); printf("SETUP_FINALLY %d\n", emit->label_offsets[label]);
} }
} }
STATIC void emit_cpy_end_finally(emit_t *emit) { STATIC void emit_cpy_end_finally(emit_t *emit) {
emit_pre(emit, -1, 1); emit_pre(emit, -1, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("END_FINALLY\n"); printf("END_FINALLY\n");
} }
} }
STATIC void emit_cpy_get_iter(emit_t *emit) { STATIC void emit_cpy_get_iter(emit_t *emit) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("GET_ITER\n"); printf("GET_ITER\n");
} }
} }
STATIC void emit_cpy_for_iter(emit_t *emit, uint label) { STATIC void emit_cpy_for_iter(emit_t *emit, uint label) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("FOR_ITER %d\n", emit->label_offsets[label]); printf("FOR_ITER %d\n", emit->label_offsets[label]);
} }
} }
@ -530,21 +530,21 @@ STATIC void emit_cpy_for_iter_end(emit_t *emit) {
STATIC void emit_cpy_pop_block(emit_t *emit) { STATIC void emit_cpy_pop_block(emit_t *emit) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("POP_BLOCK\n"); printf("POP_BLOCK\n");
} }
} }
STATIC void emit_cpy_pop_except(emit_t *emit) { STATIC void emit_cpy_pop_except(emit_t *emit) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("POP_EXCEPT\n"); printf("POP_EXCEPT\n");
} }
} }
STATIC void emit_cpy_unary_op(emit_t *emit, mp_unary_op_t op) { STATIC void emit_cpy_unary_op(emit_t *emit, mp_unary_op_t op) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
switch (op) { switch (op) {
case MP_UNARY_OP_POSITIVE: printf("UNARY_POSITIVE\n"); break; case MP_UNARY_OP_POSITIVE: printf("UNARY_POSITIVE\n"); break;
case MP_UNARY_OP_NEGATIVE: printf("UNARY_NEGATIVE\n"); break; case MP_UNARY_OP_NEGATIVE: printf("UNARY_NEGATIVE\n"); break;
@ -563,7 +563,7 @@ STATIC void emit_cpy_binary_op(emit_t *emit, mp_binary_op_t op) {
// CPython uses a byte code plus an argument for compare ops // CPython uses a byte code plus an argument for compare ops
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
} }
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
switch (op) { switch (op) {
case MP_BINARY_OP_OR: printf("BINARY_OR\n"); break; case MP_BINARY_OP_OR: printf("BINARY_OR\n"); break;
case MP_BINARY_OP_XOR: printf("BINARY_XOR\n"); break; case MP_BINARY_OP_XOR: printf("BINARY_XOR\n"); break;
@ -607,77 +607,77 @@ STATIC void emit_cpy_binary_op(emit_t *emit, mp_binary_op_t op) {
STATIC void emit_cpy_build_tuple(emit_t *emit, int n_args) { STATIC void emit_cpy_build_tuple(emit_t *emit, int n_args) {
emit_pre(emit, 1 - n_args, 3); emit_pre(emit, 1 - n_args, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BUILD_TUPLE %d\n", n_args); printf("BUILD_TUPLE %d\n", n_args);
} }
} }
STATIC void emit_cpy_build_list(emit_t *emit, int n_args) { STATIC void emit_cpy_build_list(emit_t *emit, int n_args) {
emit_pre(emit, 1 - n_args, 3); emit_pre(emit, 1 - n_args, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BUILD_LIST %d\n", n_args); printf("BUILD_LIST %d\n", n_args);
} }
} }
STATIC void emit_cpy_list_append(emit_t *emit, int list_index) { STATIC void emit_cpy_list_append(emit_t *emit, int list_index) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LIST_APPEND %d\n", list_index); printf("LIST_APPEND %d\n", list_index);
} }
} }
STATIC void emit_cpy_build_map(emit_t *emit, int n_args) { STATIC void emit_cpy_build_map(emit_t *emit, int n_args) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BUILD_MAP %d\n", n_args); printf("BUILD_MAP %d\n", n_args);
} }
} }
STATIC void emit_cpy_store_map(emit_t *emit) { STATIC void emit_cpy_store_map(emit_t *emit) {
emit_pre(emit, -2, 1); emit_pre(emit, -2, 1);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("STORE_MAP\n"); printf("STORE_MAP\n");
} }
} }
STATIC void emit_cpy_map_add(emit_t *emit, int map_index) { STATIC void emit_cpy_map_add(emit_t *emit, int map_index) {
emit_pre(emit, -2, 3); emit_pre(emit, -2, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("MAP_ADD %d\n", map_index); printf("MAP_ADD %d\n", map_index);
} }
} }
STATIC void emit_cpy_build_set(emit_t *emit, int n_args) { STATIC void emit_cpy_build_set(emit_t *emit, int n_args) {
emit_pre(emit, 1 - n_args, 3); emit_pre(emit, 1 - n_args, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BUILD_SET %d\n", n_args); printf("BUILD_SET %d\n", n_args);
} }
} }
STATIC void emit_cpy_set_add(emit_t *emit, int set_index) { STATIC void emit_cpy_set_add(emit_t *emit, int set_index) {
emit_pre(emit, -1, 3); emit_pre(emit, -1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("SET_ADD %d\n", set_index); printf("SET_ADD %d\n", set_index);
} }
} }
STATIC void emit_cpy_build_slice(emit_t *emit, int n_args) { STATIC void emit_cpy_build_slice(emit_t *emit, int n_args) {
emit_pre(emit, 1 - n_args, 3); emit_pre(emit, 1 - n_args, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("BUILD_SLICE %d\n", n_args); printf("BUILD_SLICE %d\n", n_args);
} }
} }
STATIC void emit_cpy_unpack_sequence(emit_t *emit, int n_args) { STATIC void emit_cpy_unpack_sequence(emit_t *emit, int n_args) {
emit_pre(emit, -1 + n_args, 3); emit_pre(emit, -1 + n_args, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("UNPACK_SEQUENCE %d\n", n_args); printf("UNPACK_SEQUENCE %d\n", n_args);
} }
} }
STATIC void emit_cpy_unpack_ex(emit_t *emit, int n_left, int n_right) { STATIC void emit_cpy_unpack_ex(emit_t *emit, int n_left, int n_right) {
emit_pre(emit, -1 + n_left + n_right + 1, 3); emit_pre(emit, -1 + n_left + n_right + 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("UNPACK_EX %d\n", n_left | (n_right << 8)); printf("UNPACK_EX %d\n", n_left | (n_right << 8));
} }
} }
@ -691,7 +691,7 @@ STATIC void emit_cpy_call_function(emit_t *emit, int n_positional, int n_keyword
s += 1; s += 1;
} }
emit_pre(emit, -n_positional - 2 * n_keyword - s, 3); emit_pre(emit, -n_positional - 2 * n_keyword - s, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
if (star_flags & MP_EMIT_STAR_FLAG_SINGLE) { if (star_flags & MP_EMIT_STAR_FLAG_SINGLE) {
if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) { if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) {
printf("CALL_FUNCTION_VAR_KW"); printf("CALL_FUNCTION_VAR_KW");
@ -716,26 +716,26 @@ STATIC void emit_cpy_call_method(emit_t *emit, int n_positional, int n_keyword,
STATIC void emit_cpy_return_value(emit_t *emit) { STATIC void emit_cpy_return_value(emit_t *emit) {
emit_pre(emit, -1, 1); emit_pre(emit, -1, 1);
emit->last_emit_was_return_value = true; emit->last_emit_was_return_value = true;
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("RETURN_VALUE\n"); printf("RETURN_VALUE\n");
} }
} }
STATIC void emit_cpy_raise_varargs(emit_t *emit, int n_args) { STATIC void emit_cpy_raise_varargs(emit_t *emit, int n_args) {
emit_pre(emit, -n_args, 3); emit_pre(emit, -n_args, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("RAISE_VARARGS %d\n", n_args); printf("RAISE_VARARGS %d\n", n_args);
} }
} }
STATIC void load_cpy_const_code_and_name(emit_t *emit, qstr qstr) { STATIC void load_cpy_const_code_and_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST code %s\n", qstr_str(qstr)); printf("LOAD_CONST code %s\n", qstr_str(qstr));
} }
// load qualified name // load qualified name
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST '"); printf("LOAD_CONST '");
// code just to work out the qualname (or whatever it is) // code just to work out the qualname (or whatever it is)
{ {
@ -762,7 +762,7 @@ STATIC void load_cpy_const_code_and_name(emit_t *emit, qstr qstr) {
STATIC void emit_cpy_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) { STATIC void emit_cpy_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
load_cpy_const_code_and_name(emit, scope->simple_name); load_cpy_const_code_and_name(emit, scope->simple_name);
emit_pre(emit, -1 - n_pos_defaults - 2 * n_kw_defaults, 3); emit_pre(emit, -1 - n_pos_defaults - 2 * n_kw_defaults, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("MAKE_FUNCTION %d\n", (n_kw_defaults << 8) | n_pos_defaults); printf("MAKE_FUNCTION %d\n", (n_kw_defaults << 8) | n_pos_defaults);
} }
} }
@ -771,48 +771,44 @@ STATIC void emit_cpy_make_closure(emit_t *emit, scope_t *scope, uint n_closed_ov
emit_cpy_build_tuple(emit, n_closed_over); emit_cpy_build_tuple(emit, n_closed_over);
load_cpy_const_code_and_name(emit, scope->simple_name); load_cpy_const_code_and_name(emit, scope->simple_name);
emit_pre(emit, -2 - n_pos_defaults - 2 * n_kw_defaults, 3); emit_pre(emit, -2 - n_pos_defaults - 2 * n_kw_defaults, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("MAKE_CLOSURE %d\n", (n_kw_defaults << 8) | n_pos_defaults); printf("MAKE_CLOSURE %d\n", (n_kw_defaults << 8) | n_pos_defaults);
} }
} }
STATIC void emit_cpy_yield_value(emit_t *emit) { STATIC void emit_cpy_yield_value(emit_t *emit) {
emit_pre(emit, 0, 1); emit_pre(emit, 0, 1);
if (emit->pass == PASS_2) {
emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
} if (emit->pass == MP_PASS_EMIT) {
if (emit->pass == PASS_3) {
printf("YIELD_VALUE\n"); printf("YIELD_VALUE\n");
} }
} }
STATIC void emit_cpy_yield_from(emit_t *emit) { STATIC void emit_cpy_yield_from(emit_t *emit) {
emit_pre(emit, -1, 1); emit_pre(emit, -1, 1);
if (emit->pass == PASS_2) {
emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
} if (emit->pass == MP_PASS_EMIT) {
if (emit->pass == PASS_3) {
printf("YIELD_FROM\n"); printf("YIELD_FROM\n");
} }
} }
STATIC void emit_cpy_load_const_verbatim_str(emit_t *emit, const char *str) { STATIC void emit_cpy_load_const_verbatim_str(emit_t *emit, const char *str) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CONST %s\n", str); printf("LOAD_CONST %s\n", str);
} }
} }
STATIC void emit_cpy_load_closure(emit_t *emit, qstr qstr, int local_num) { STATIC void emit_cpy_load_closure(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1, 3); emit_pre(emit, 1, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("LOAD_CLOSURE %d %s\n", local_num, qstr_str(qstr)); printf("LOAD_CLOSURE %d %s\n", local_num, qstr_str(qstr));
} }
} }
STATIC void emit_cpy_setup_loop(emit_t *emit, uint label) { STATIC void emit_cpy_setup_loop(emit_t *emit, uint label) {
emit_pre(emit, 0, 3); emit_pre(emit, 0, 3);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
printf("SETUP_LOOP %d\n", emit->label_offsets[label]); printf("SETUP_LOOP %d\n", emit->label_offsets[label]);
} }
} }

View File

@ -89,7 +89,7 @@ STATIC void emit_inline_thumb_start_pass(emit_inline_asm_t *emit, pass_kind_t pa
emit->pass = pass; emit->pass = pass;
emit->success = true; emit->success = true;
emit->scope = scope; emit->scope = scope;
asm_thumb_start_pass(emit->as, pass); asm_thumb_start_pass(emit->as, pass == MP_PASS_EMIT ? ASM_THUMB_PASS_EMIT : ASM_THUMB_PASS_COMPUTE);
asm_thumb_entry(emit->as, 0); asm_thumb_entry(emit->as, 0);
} }
@ -97,7 +97,7 @@ STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
asm_thumb_exit(emit->as); asm_thumb_exit(emit->as);
asm_thumb_end_pass(emit->as); asm_thumb_end_pass(emit->as);
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
void *f = asm_thumb_get_code(emit->as); void *f = asm_thumb_get_code(emit->as);
mp_emit_glue_assign_inline_asm_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args); mp_emit_glue_assign_inline_asm_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args);
} }
@ -230,7 +230,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_
} }
} }
// only need to have the labels on the last pass // only need to have the labels on the last pass
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
emit_inline_thumb_error(emit, "label '%s' not defined\n", qstr_str(label_qstr)); emit_inline_thumb_error(emit, "label '%s' not defined\n", qstr_str(label_qstr));
} }
return 0; return 0;

View File

@ -86,6 +86,7 @@
#define REG_TEMP2 (REG_RSI) #define REG_TEMP2 (REG_RSI)
#define ASM_MOV_REG_TO_LOCAL(reg, local_num) asm_x64_mov_r64_to_local(emit->as, (reg), (local_num)) #define ASM_MOV_REG_TO_LOCAL(reg, local_num) asm_x64_mov_r64_to_local(emit->as, (reg), (local_num))
#define ASM_MOV_IMM_TO_REG(imm, reg) asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), (reg)) #define ASM_MOV_IMM_TO_REG(imm, reg) asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), (reg))
#define ASM_MOV_ALIGNED_IMM_TO_REG(imm, reg) asm_x64_mov_i64_to_r64_aligned(emit->as, (imm), (reg))
#define ASM_MOV_IMM_TO_LOCAL_USING(imm, local_num, reg_temp) do { asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), (reg_temp)); asm_x64_mov_r64_to_local(emit->as, (reg_temp), (local_num)); } while (false) #define ASM_MOV_IMM_TO_LOCAL_USING(imm, local_num, reg_temp) do { asm_x64_mov_i64_to_r64_optimised(emit->as, (imm), (reg_temp)); asm_x64_mov_r64_to_local(emit->as, (reg_temp), (local_num)); } while (false)
#define ASM_MOV_LOCAL_TO_REG(local_num, reg) asm_x64_mov_local_to_r64(emit->as, (local_num), (reg)) #define ASM_MOV_LOCAL_TO_REG(local_num, reg) asm_x64_mov_local_to_r64(emit->as, (local_num), (reg))
#define ASM_MOV_REG_TO_REG(reg_src, reg_dest) asm_x64_mov_r64_to_r64(emit->as, (reg_src), (reg_dest)) #define ASM_MOV_REG_TO_REG(reg_src, reg_dest) asm_x64_mov_r64_to_r64(emit->as, (reg_src), (reg_dest))
@ -109,6 +110,7 @@
#define REG_TEMP2 (REG_R2) #define REG_TEMP2 (REG_R2)
#define ASM_MOV_REG_TO_LOCAL(reg, local_num) asm_thumb_mov_local_reg(emit->as, (local_num), (reg)) #define ASM_MOV_REG_TO_LOCAL(reg, local_num) asm_thumb_mov_local_reg(emit->as, (local_num), (reg))
#define ASM_MOV_IMM_TO_REG(imm, reg) asm_thumb_mov_reg_i32_optimised(emit->as, (reg), (imm)) #define ASM_MOV_IMM_TO_REG(imm, reg) asm_thumb_mov_reg_i32_optimised(emit->as, (reg), (imm))
#define ASM_MOV_ALIGNED_IMM_TO_REG(imm, reg) asm_thumb_mov_reg_i32_aligned(emit->as, (reg), (imm))
#define ASM_MOV_IMM_TO_LOCAL_USING(imm, local_num, reg_temp) do { asm_thumb_mov_reg_i32_optimised(emit->as, (reg_temp), (imm)); asm_thumb_mov_local_reg(emit->as, (local_num), (reg_temp)); } while (false) #define ASM_MOV_IMM_TO_LOCAL_USING(imm, local_num, reg_temp) do { asm_thumb_mov_reg_i32_optimised(emit->as, (reg_temp), (imm)); asm_thumb_mov_local_reg(emit->as, (local_num), (reg_temp)); } while (false)
#define ASM_MOV_LOCAL_TO_REG(local_num, reg) asm_thumb_mov_reg_local(emit->as, (reg), (local_num)) #define ASM_MOV_LOCAL_TO_REG(local_num, reg) asm_thumb_mov_reg_local(emit->as, (reg), (local_num))
#define ASM_MOV_REG_TO_REG(reg_src, reg_dest) asm_thumb_mov_reg_reg(emit->as, (reg_dest), (reg_src)) #define ASM_MOV_REG_TO_REG(reg_src, reg_dest) asm_thumb_mov_reg_reg(emit->as, (reg_dest), (reg_src))
@ -146,10 +148,10 @@ struct _emit_t {
bool do_viper_types; bool do_viper_types;
int local_vtype_alloc; uint local_vtype_alloc;
vtype_kind_t *local_vtype; vtype_kind_t *local_vtype;
int stack_info_alloc; uint stack_info_alloc;
stack_info_t *stack_info; stack_info_t *stack_info;
int stack_start; int stack_start;
@ -167,10 +169,7 @@ struct _emit_t {
}; };
emit_t *EXPORT_FUN(new)(uint max_num_labels) { emit_t *EXPORT_FUN(new)(uint max_num_labels) {
emit_t *emit = m_new(emit_t, 1); emit_t *emit = m_new0(emit_t, 1);
emit->do_viper_types = false;
emit->local_vtype = NULL;
emit->stack_info = NULL;
#if N_X64 #if N_X64
emit->as = asm_x64_new(max_num_labels); emit->as = asm_x64_new(max_num_labels);
#elif N_THUMB #elif N_THUMB
@ -185,6 +184,8 @@ void EXPORT_FUN(free)(emit_t *emit) {
#elif N_THUMB #elif N_THUMB
asm_thumb_free(emit->as, false); asm_thumb_free(emit->as, false);
#endif #endif
m_del(vtype_kind_t, emit->local_vtype, emit->local_vtype_alloc);
m_del(stack_info_t, emit->stack_info, emit->stack_info_alloc);
m_del_obj(emit_t, emit); m_del_obj(emit_t, emit);
} }
@ -199,12 +200,16 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
emit->last_emit_was_return_value = false; emit->last_emit_was_return_value = false;
emit->scope = scope; emit->scope = scope;
if (emit->local_vtype == NULL) { // allocate memory for keeping track of the types of locals
emit->local_vtype_alloc = scope->num_locals + 20; // XXX should be maximum over all scopes if (emit->local_vtype_alloc < scope->num_locals) {
emit->local_vtype = m_new(vtype_kind_t, emit->local_vtype_alloc); emit->local_vtype = m_renew(vtype_kind_t, emit->local_vtype, emit->local_vtype_alloc, scope->num_locals);
emit->local_vtype_alloc = scope->num_locals;
} }
// allocate memory for keeping track of the objects on the stack
// XXX don't know stack size on entry, and it should be maximum over all scopes
if (emit->stack_info == NULL) { if (emit->stack_info == NULL) {
emit->stack_info_alloc = scope->stack_size + 50; // XXX don't know stack size on entry, should be maximum over all scopes emit->stack_info_alloc = scope->stack_size + 50;
emit->stack_info = m_new(stack_info_t, emit->stack_info_alloc); emit->stack_info = m_new(stack_info_t, emit->stack_info_alloc);
} }
@ -228,14 +233,14 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
} }
#if N_X64 #if N_X64
asm_x64_start_pass(emit->as, pass); asm_x64_start_pass(emit->as, pass == MP_PASS_EMIT ? ASM_X64_PASS_EMIT : ASM_X64_PASS_COMPUTE);
#elif N_THUMB #elif N_THUMB
asm_thumb_start_pass(emit->as, pass); asm_thumb_start_pass(emit->as, pass == MP_PASS_EMIT ? ASM_THUMB_PASS_EMIT : ASM_THUMB_PASS_COMPUTE);
#endif #endif
// entry to function // entry to function
int num_locals = 0; int num_locals = 0;
if (pass > PASS_1) { if (pass > MP_PASS_SCOPE) {
num_locals = scope->num_locals - REG_LOCAL_NUM; num_locals = scope->num_locals - REG_LOCAL_NUM;
if (num_locals < 0) { if (num_locals < 0) {
num_locals = 0; num_locals = 0;
@ -243,11 +248,6 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
emit->stack_start = num_locals; emit->stack_start = num_locals;
num_locals += scope->stack_size; num_locals += scope->stack_size;
} }
if (pass == PASS_2) {
// XXX big hack to make sure we have some locals in PASS_2
// this is so that on PASS_2 the code emitted in x64 has the right size
num_locals += 2;
}
#if N_X64 #if N_X64
asm_x64_entry(emit->as, num_locals); asm_x64_entry(emit->as, num_locals);
#elif N_THUMB #elif N_THUMB
@ -306,7 +306,7 @@ STATIC void emit_native_end_pass(emit_t *emit) {
printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size); printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
} }
if (emit->pass == PASS_3) { if (emit->pass == MP_PASS_EMIT) {
#if N_X64 #if N_X64
void *f = asm_x64_get_code(emit->as); void *f = asm_x64_get_code(emit->as);
mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_x64_get_code_size(emit->as), emit->scope->num_pos_args); mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_x64_get_code_size(emit->as), emit->scope->num_pos_args);
@ -332,7 +332,7 @@ STATIC void adjust_stack(emit_t *emit, int stack_size_delta) {
DEBUG_printf("adjust stack: stack:%d + delta:%d\n", emit->stack_size, stack_size_delta); DEBUG_printf("adjust stack: stack:%d + delta:%d\n", emit->stack_size, stack_size_delta);
assert((int)emit->stack_size + stack_size_delta >= 0); assert((int)emit->stack_size + stack_size_delta >= 0);
emit->stack_size += stack_size_delta; emit->stack_size += stack_size_delta;
if (emit->pass > PASS_1 && emit->stack_size > emit->scope->stack_size) { if (emit->pass > MP_PASS_SCOPE && emit->stack_size > emit->scope->stack_size) {
emit->scope->stack_size = emit->stack_size; emit->scope->stack_size = emit->stack_size;
} }
} }
@ -572,9 +572,10 @@ STATIC void emit_call_with_2_imm_args(emit_t *emit, mp_fun_kind_t fun_kind, void
#endif #endif
} }
STATIC void emit_call_with_3_imm_args(emit_t *emit, mp_fun_kind_t fun_kind, void *fun, machine_int_t arg_val1, int arg_reg1, machine_int_t arg_val2, int arg_reg2, machine_int_t arg_val3, int arg_reg3) { // the first arg is stored in the code aligned on a machine_uint_t boundary
STATIC void emit_call_with_3_imm_args_and_first_aligned(emit_t *emit, mp_fun_kind_t fun_kind, void *fun, machine_int_t arg_val1, int arg_reg1, machine_int_t arg_val2, int arg_reg2, machine_int_t arg_val3, int arg_reg3) {
need_reg_all(emit); need_reg_all(emit);
ASM_MOV_IMM_TO_REG(arg_val1, arg_reg1); ASM_MOV_ALIGNED_IMM_TO_REG(arg_val1, arg_reg1);
ASM_MOV_IMM_TO_REG(arg_val2, arg_reg2); ASM_MOV_IMM_TO_REG(arg_val2, arg_reg2);
ASM_MOV_IMM_TO_REG(arg_val3, arg_reg3); ASM_MOV_IMM_TO_REG(arg_val3, arg_reg3);
#if N_X64 #if N_X64
@ -1209,9 +1210,7 @@ STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, uint n_pos_d
// call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them
assert(n_pos_defaults == 0 && n_kw_defaults == 0); assert(n_pos_defaults == 0 && n_kw_defaults == 0);
emit_native_pre(emit); emit_native_pre(emit);
assert(0); emit_call_with_3_imm_args_and_first_aligned(emit, MP_F_MAKE_FUNCTION_FROM_RAW_CODE, mp_make_function_from_raw_code, (machine_uint_t)scope->raw_code, REG_ARG_1, (machine_uint_t)MP_OBJ_NULL, REG_ARG_2, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3);
// TODO we need to store the raw_code ptr aligned within the code for the GC
emit_call_with_3_imm_args(emit, MP_F_MAKE_FUNCTION_FROM_RAW_CODE, mp_make_function_from_raw_code, (machine_uint_t)scope->raw_code, REG_ARG_1, (machine_uint_t)MP_OBJ_NULL, REG_ARG_2, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3);
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
} }

View File

@ -56,7 +56,7 @@ STATIC void emit_pass1_dummy(emit_t *emit) {
} }
STATIC void emit_pass1_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { STATIC void emit_pass1_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
assert(pass == PASS_1); assert(pass == MP_PASS_SCOPE);
emit->scope = scope; emit->scope = scope;
} }

View File

@ -1156,12 +1156,12 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_call_function_n_kw_for_native, mp_call_function_n_kw_for_native,
mp_call_method_n_kw, mp_call_method_n_kw,
mp_getiter, mp_getiter,
mp_iternext,
mp_import_name, mp_import_name,
mp_import_from, mp_import_from,
mp_import_all, mp_import_all,
mp_obj_new_slice, mp_obj_new_slice,
mp_unpack_sequence, mp_unpack_sequence,
mp_iternext,
}; };
/* /*