summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/compile.c15
-rw-r--r--py/emitbc.c34
-rw-r--r--py/emitcommon.c4
-rw-r--r--py/emitcpy.c2
-rw-r--r--py/emitglue.c159
-rw-r--r--py/emitglue.h40
-rw-r--r--py/emitinlinethumb.c5
-rw-r--r--py/emitnative.c12
-rw-r--r--py/emitpass1.c2
-rw-r--r--py/runtime.c2
-rw-r--r--py/runtime.h3
-rw-r--r--py/runtime0.h2
-rw-r--r--py/scope.c6
-rw-r--r--py/scope.h4
-rw-r--r--py/vm.c30
15 files changed, 149 insertions, 171 deletions
diff --git a/py/compile.c b/py/compile.c
index f397501f17..7a3d810f9d 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -10,11 +10,11 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
-#include "scope.h"
#include "runtime0.h"
-#include "emit.h"
-#include "emitglue.h"
#include "obj.h"
+#include "emitglue.h"
+#include "scope.h"
+#include "emit.h"
#include "compile.h"
#include "runtime.h"
#include "builtin.h"
@@ -283,7 +283,7 @@ STATIC void compile_decrease_except_level(compiler_t *comp) {
}
STATIC scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) {
- scope_t *scope = scope_new(kind, pn, comp->source_file, mp_emit_glue_get_unique_code_id(), emit_options);
+ scope_t *scope = scope_new(kind, pn, comp->source_file, emit_options);
scope->parent = comp->scope_cur;
scope->next = NULL;
if (comp->scope_head == NULL) {
@@ -3454,7 +3454,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
#endif // !MICROPY_EMIT_CPYTHON
// free the scopes
- uint unique_code_id = module_scope->unique_code_id;
+ mp_raw_code_t *outer_raw_code = module_scope->raw_code;
for (scope_t *s = module_scope; s;) {
scope_t *next = s->next;
scope_free(s);
@@ -3471,12 +3471,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
} else {
#if MICROPY_EMIT_CPYTHON
// can't create code, so just return true
- (void)unique_code_id; // to suppress warning that unique_code_id is unused
+ (void)outer_raw_code; // to suppress warning that outer_raw_code is unused
return mp_const_true;
#else
// return function that executes the outer module
- // we can free the unique_code slot because no-one has reference to this unique_code_id anymore
- return mp_make_function_from_id_and_free(unique_code_id, MP_OBJ_NULL, MP_OBJ_NULL);
+ return mp_make_function_from_raw_code(outer_raw_code, MP_OBJ_NULL, MP_OBJ_NULL);
#endif
}
}
diff --git a/py/emitbc.c b/py/emitbc.c
index d1d59ef4a5..2d71d86855 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -9,10 +9,11 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
+#include "obj.h"
+#include "emitglue.h"
#include "scope.h"
#include "runtime0.h"
#include "emit.h"
-#include "emitglue.h"
#include "bc0.h"
struct _emit_t {
@@ -65,6 +66,10 @@ STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_writ
}
}
+STATIC void emit_align_code_info_to_machine_word(emit_t* emit) {
+ emit->code_info_offset = (emit->code_info_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1));
+}
+
STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
byte* c = emit_get_cur_to_write_code_info(emit, 4);
// TODO variable length encoding for qstr
@@ -98,6 +103,10 @@ STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_writ
}
}
+STATIC void emit_align_byte_code_to_machine_word(emit_t* emit) {
+ emit->byte_code_offset = (emit->byte_code_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1));
+}
+
STATIC void emit_write_byte_code_byte(emit_t* emit, byte b1) {
byte* c = emit_get_cur_to_write_byte_code(emit, 1);
c[0] = b1;
@@ -158,6 +167,14 @@ STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
emit_write_byte_code_uint(emit, num);
}
+// aligns the pointer so it is friendly to GC
+STATIC void emit_write_byte_code_byte_ptr(emit_t* emit, byte b, void *ptr) {
+ emit_write_byte_code_byte(emit, b);
+ emit_align_byte_code_to_machine_word(emit);
+ machine_uint_t *c = (machine_uint_t*)emit_get_cur_to_write_byte_code(emit, sizeof(machine_uint_t));
+ *c = (machine_uint_t)ptr;
+}
+
/* currently unused
STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
emit_write_byte_code_byte(emit, b);
@@ -178,7 +195,7 @@ STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint
} else {
byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3;
}
- byte* c = emit_get_cur_to_write_byte_code(emit, 3);
+ byte *c = emit_get_cur_to_write_byte_code(emit, 3);
c[0] = b1;
c[1] = byte_code_offset;
c[2] = byte_code_offset >> 8;
@@ -269,19 +286,20 @@ STATIC void emit_bc_end_pass(emit_t *emit) {
}
emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info
+ emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned
if (emit->pass == PASS_2) {
// calculate size of code in bytes
emit->code_info_size = emit->code_info_offset;
emit->byte_code_size = emit->byte_code_offset;
- emit->code_base = m_new(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) {
qstr *arg_names = m_new(qstr, emit->scope->num_params);
for (int i = 0; i < emit->scope->num_params; i++) {
arg_names[i] = emit->scope->id_info[i].qstr;
}
- mp_emit_glue_assign_byte_code(emit->scope->unique_code_id, emit->code_base,
+ mp_emit_glue_assign_byte_code(emit->scope->raw_code, emit->code_base,
emit->code_info_size + emit->byte_code_size,
emit->scope->num_params, emit->scope->num_locals,
emit->scope->scope_flags, arg_names);
@@ -733,7 +751,7 @@ STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
emit_bc_pre(emit, 1);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION, scope->raw_code);
} else {
if (n_pos_defaults == 0) {
// load dummy entry for non-existent positional default tuple
@@ -744,14 +762,14 @@ STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defau
emit_bc_load_null(emit);
}
emit_bc_pre(emit, -1);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
}
}
STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
emit_bc_pre(emit, 0);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE, scope->raw_code);
} else {
if (n_pos_defaults == 0) {
// load dummy entry for non-existent positional default tuple
@@ -763,7 +781,7 @@ STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaul
emit_bc_rot_two(emit);
}
emit_bc_pre(emit, -2);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
}
}
diff --git a/py/emitcommon.c b/py/emitcommon.c
index 30f5ace923..454ec9c5e5 100644
--- a/py/emitcommon.c
+++ b/py/emitcommon.c
@@ -7,8 +7,10 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
-#include "scope.h"
#include "runtime0.h"
+#include "obj.h"
+#include "emitglue.h"
+#include "scope.h"
#include "emit.h"
#define EMIT(fun, ...) (emit_method_table->fun(emit, __VA_ARGS__))
diff --git a/py/emitcpy.c b/py/emitcpy.c
index 5866d474e9..010219d12f 100644
--- a/py/emitcpy.c
+++ b/py/emitcpy.c
@@ -9,6 +9,8 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
+#include "obj.h"
+#include "emitglue.h"
#include "scope.h"
#include "runtime0.h"
#include "emit.h"
diff --git a/py/emitglue.c b/py/emitglue.c
index bcc9b2cca1..ce296f4321 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -23,46 +23,11 @@
#define DEBUG_OP_printf(...) (void)0
#endif
-typedef enum {
- MP_CODE_UNUSED,
- MP_CODE_RESERVED,
- MP_CODE_BYTE,
- MP_CODE_NATIVE,
- MP_CODE_INLINE_ASM,
-} mp_code_kind_t;
-
-typedef struct _mp_code_t {
- mp_code_kind_t kind : 8;
- uint scope_flags : 8;
- uint n_args : 16;
- union {
- struct {
- byte *code;
- uint len;
- } u_byte;
- struct {
- mp_fun_t fun;
- } u_native;
- struct {
- void *fun;
- } u_inline_asm;
- };
- qstr *arg_names;
-} mp_code_t;
-
-STATIC machine_uint_t unique_codes_alloc = 0;
-STATIC machine_uint_t unique_codes_total = 0; // always >= unique_codes_alloc
-STATIC mp_code_t *unique_codes = NULL;
-
#ifdef WRITE_CODE
FILE *fp_write_code = NULL;
#endif
void mp_emit_glue_init(void) {
- unique_codes_alloc = 0;
- unique_codes_total = 0;
- unique_codes = NULL;
-
#ifdef WRITE_CODE
fp_write_code = fopen("out-code", "wb");
#endif
@@ -74,50 +39,24 @@ void mp_emit_glue_deinit(void) {
fclose(fp_write_code);
}
#endif
-
- m_del(mp_code_t, unique_codes, unique_codes_alloc);
-}
-
-uint mp_emit_glue_get_unique_code_id(void) {
- // look for an existing unused slot
- for (uint i = 0; i < unique_codes_alloc; i++) {
- if (unique_codes[i].kind == MP_CODE_UNUSED) {
- unique_codes[i].kind = MP_CODE_RESERVED;
- return i;
- }
- }
- // no existing slot
- // return next available id, memory will be allocated later
- return unique_codes_total++;
}
-STATIC void mp_emit_glue_alloc_unique_codes(void) {
- if (unique_codes_total > unique_codes_alloc) {
- DEBUG_printf("allocate more unique codes: " UINT_FMT " -> %u\n", unique_codes_alloc, unique_codes_total);
- // increase size of unique_codes table (all new entries are already reserved)
- unique_codes = m_renew(mp_code_t, unique_codes, unique_codes_alloc, unique_codes_total);
- for (uint i = unique_codes_alloc; i < unique_codes_total; i++) {
- unique_codes[i].kind = MP_CODE_RESERVED;
- }
- unique_codes_alloc = unique_codes_total;
- }
+mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
+ mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1);
+ rc->kind = MP_CODE_RESERVED;
+ return rc;
}
-void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names) {
- mp_emit_glue_alloc_unique_codes();
-
- assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED);
- unique_codes[unique_code_id].kind = MP_CODE_BYTE;
- unique_codes[unique_code_id].scope_flags = scope_flags;
- unique_codes[unique_code_id].n_args = n_args;
- unique_codes[unique_code_id].u_byte.code = code;
- unique_codes[unique_code_id].u_byte.len = len;
- unique_codes[unique_code_id].arg_names = arg_names;
-
- //printf("byte code: %d bytes\n", len);
+void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names) {
+ rc->kind = MP_CODE_BYTE;
+ rc->scope_flags = scope_flags;
+ rc->n_args = n_args;
+ rc->u_byte.code = code;
+ rc->u_byte.len = len;
+ rc->arg_names = arg_names;
#ifdef DEBUG_PRINT
- DEBUG_printf("assign byte code: id=%d code=%p len=%u n_args=%d n_locals=%d\n", unique_code_id, code, len, n_args, n_locals);
+ DEBUG_printf("assign byte code: code=%p len=%u n_args=%d n_locals=%d\n", code, len, n_args, n_locals);
for (int i = 0; i < 128 && i < len; i++) {
if (i > 0 && i % 16 == 0) {
DEBUG_printf("\n");
@@ -131,19 +70,14 @@ void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, in
#endif
}
-void mp_emit_glue_assign_native_code(uint unique_code_id, void *fun, uint len, int n_args) {
- mp_emit_glue_alloc_unique_codes();
-
- assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED);
- unique_codes[unique_code_id].kind = MP_CODE_NATIVE;
- unique_codes[unique_code_id].scope_flags = 0;
- unique_codes[unique_code_id].n_args = n_args;
- unique_codes[unique_code_id].u_native.fun = fun;
-
- //printf("native code: %d bytes\n", len);
+void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) {
+ rc->kind = MP_CODE_NATIVE;
+ rc->scope_flags = 0;
+ rc->n_args = n_args;
+ rc->u_native.fun = fun;
#ifdef DEBUG_PRINT
- DEBUG_printf("assign native code: id=%d fun=%p len=%u n_args=%d\n", unique_code_id, fun, len, n_args);
+ DEBUG_printf("assign native code: fun=%p len=%u n_args=%d\n", fun, len, n_args);
byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code
for (int i = 0; i < 128 && i < len; i++) {
if (i > 0 && i % 16 == 0) {
@@ -162,17 +96,14 @@ void mp_emit_glue_assign_native_code(uint unique_code_id, void *fun, uint len, i
#endif
}
-void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint len, int n_args) {
- mp_emit_glue_alloc_unique_codes();
-
- assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED);
- unique_codes[unique_code_id].kind = MP_CODE_INLINE_ASM;
- unique_codes[unique_code_id].scope_flags = 0;
- unique_codes[unique_code_id].n_args = n_args;
- unique_codes[unique_code_id].u_inline_asm.fun = fun;
+void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) {
+ rc->kind = MP_CODE_INLINE_ASM;
+ rc->scope_flags = 0;
+ rc->n_args = n_args;
+ rc->u_inline_asm.fun = fun;
#ifdef DEBUG_PRINT
- DEBUG_printf("assign inline asm code: id=%d fun=%p len=%u n_args=%d\n", unique_code_id, fun, len, n_args);
+ DEBUG_printf("assign inline asm code: fun=%p len=%u n_args=%d\n", fun, len, n_args);
byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code
for (int i = 0; i < 128 && i < len; i++) {
if (i > 0 && i % 16 == 0) {
@@ -191,12 +122,9 @@ void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint le
#endif
}
-mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) {
- DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id);
- if (unique_code_id >= unique_codes_total) {
- // illegal code id
- return mp_const_none;
- }
+mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args) {
+ DEBUG_OP_printf("make_function_from_raw_code %p\n", rc);
+ assert(rc != NULL);
// def_args must be MP_OBJ_NULL or a tuple
assert(def_args == MP_OBJ_NULL || MP_OBJ_IS_TYPE(def_args, &mp_type_tuple));
@@ -204,49 +132,36 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj
// TODO implement default kw args
assert(def_kw_args == MP_OBJ_NULL);
- // make the function, depending on the code kind
- mp_code_t *c = &unique_codes[unique_code_id];
+ // make the function, depending on the raw code kind
mp_obj_t fun;
- switch (c->kind) {
+ switch (rc->kind) {
case MP_CODE_BYTE:
- fun = mp_obj_new_fun_bc(c->scope_flags, c->arg_names, c->n_args, def_args, c->u_byte.code);
+ fun = mp_obj_new_fun_bc(rc->scope_flags, rc->arg_names, rc->n_args, def_args, rc->u_byte.code);
break;
case MP_CODE_NATIVE:
- fun = mp_make_function_n(c->n_args, c->u_native.fun);
+ fun = mp_make_function_n(rc->n_args, rc->u_native.fun);
break;
case MP_CODE_INLINE_ASM:
- fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun);
+ fun = mp_obj_new_fun_asm(rc->n_args, rc->u_inline_asm.fun);
break;
default:
- // code id was never assigned (this should not happen)
+ // raw code was never set (this should not happen)
assert(0);
return mp_const_none;
}
// check for generator functions and if so wrap in generator object
- if ((c->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
+ if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
fun = mp_obj_new_gen_wrap(fun);
}
return fun;
}
-mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) {
- mp_obj_t f = mp_make_function_from_id(unique_code_id, def_args, def_kw_args);
-
- // in some cases we can free the unique_code slot
- // any dynamically allocated memory is now owned by the fun object
- mp_code_t *c = &unique_codes[unique_code_id];
- memset(c, 0, sizeof *c); // make sure all pointers are zeroed
- c->kind = MP_CODE_UNUSED;
-
- return f;
-}
-
-mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) {
- DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id);
+mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) {
+ DEBUG_OP_printf("make_closure_from_raw_code %p\n", rc);
// make function object
- mp_obj_t ffun = mp_make_function_from_id(unique_code_id, def_args, def_kw_args);
+ mp_obj_t ffun = mp_make_function_from_raw_code(rc, def_args, def_kw_args);
// wrap function in closure object
return mp_obj_new_closure(ffun, closure_tuple);
}
diff --git a/py/emitglue.h b/py/emitglue.h
index 8f69951c21..2f9960bfa1 100644
--- a/py/emitglue.h
+++ b/py/emitglue.h
@@ -1,8 +1,40 @@
// These variables and functions glue the code emitters to the runtime.
+typedef enum {
+ MP_CODE_UNUSED,
+ MP_CODE_RESERVED,
+ MP_CODE_BYTE,
+ MP_CODE_NATIVE,
+ MP_CODE_INLINE_ASM,
+} mp_raw_code_kind_t;
+
+typedef struct _mp_code_t {
+ mp_raw_code_kind_t kind : 8;
+ uint scope_flags : 8;
+ uint n_args : 16;
+ union {
+ struct {
+ byte *code;
+ uint len;
+ } u_byte;
+ struct {
+ mp_fun_t fun;
+ } u_native;
+ struct {
+ void *fun;
+ } u_inline_asm;
+ };
+ qstr *arg_names;
+} mp_raw_code_t;
+
void mp_emit_glue_init(void);
void mp_emit_glue_deinit(void);
-uint mp_emit_glue_get_unique_code_id(void);
-void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names);
-void mp_emit_glue_assign_native_code(uint unique_code_id, void *f, uint len, int n_args);
-void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *f, uint len, int n_args);
+
+mp_raw_code_t *mp_emit_glue_new_raw_code(void);
+
+void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names);
+void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *f, uint len, int n_args);
+void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *f, uint len, int n_args);
+
+mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args);
+mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args);
diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c
index fc881f3d18..812e702af6 100644
--- a/py/emitinlinethumb.c
+++ b/py/emitinlinethumb.c
@@ -9,10 +9,11 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
+#include "obj.h"
+#include "emitglue.h"
#include "scope.h"
#include "runtime0.h"
#include "emit.h"
-#include "emitglue.h"
#include "asmthumb.h"
#if MICROPY_EMIT_INLINE_THUMB
@@ -72,7 +73,7 @@ STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
if (emit->pass == PASS_3) {
void *f = asm_thumb_get_code(emit->as);
- mp_emit_glue_assign_inline_asm_code(emit->scope->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params);
+ mp_emit_glue_assign_inline_asm_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params);
}
return emit->success;
diff --git a/py/emitnative.c b/py/emitnative.c
index b5a3acc231..3046aef4d6 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -27,11 +27,11 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
+#include "obj.h"
+#include "emitglue.h"
#include "scope.h"
#include "runtime0.h"
#include "emit.h"
-#include "emitglue.h"
-#include "obj.h"
#include "runtime.h"
#if 0 // print debugging info
@@ -283,10 +283,10 @@ STATIC void emit_native_end_pass(emit_t *emit) {
if (emit->pass == PASS_3) {
#if N_X64
void *f = asm_x64_get_code(emit->as);
- mp_emit_glue_assign_native_code(emit->scope->unique_code_id, f, asm_x64_get_code_size(emit->as), emit->scope->num_params);
+ mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_x64_get_code_size(emit->as), emit->scope->num_params);
#elif N_THUMB
void *f = asm_thumb_get_code(emit->as);
- mp_emit_glue_assign_native_code(emit->scope->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params);
+ mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params);
#endif
}
}
@@ -1188,7 +1188,9 @@ 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
assert(n_pos_defaults == 0 && n_kw_defaults == 0);
emit_native_pre(emit);
- emit_call_with_3_imm_args(emit, MP_F_MAKE_FUNCTION_FROM_ID, mp_make_function_from_id, scope->unique_code_id, REG_ARG_1, (machine_uint_t)MP_OBJ_NULL, REG_ARG_2, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3);
+ assert(0);
+ // 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);
}
diff --git a/py/emitpass1.c b/py/emitpass1.c
index ad86588e20..01156bfbe6 100644
--- a/py/emitpass1.c
+++ b/py/emitpass1.c
@@ -7,6 +7,8 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
+#include "obj.h"
+#include "emitglue.h"
#include "scope.h"
#include "runtime0.h"
#include "emit.h"
diff --git a/py/runtime.c b/py/runtime.c
index 053367e3f7..51190f233c 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -1143,7 +1143,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_obj_dict_store,
mp_obj_new_set,
mp_obj_set_store,
- mp_make_function_from_id,
+ mp_make_function_from_raw_code,
mp_call_function_n_kw_for_native,
mp_call_method_n_kw,
mp_getiter,
diff --git a/py/runtime.h b/py/runtime.h
index 867d633520..a3c6119838 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -29,12 +29,9 @@ mp_obj_t mp_load_const_dec(qstr qstr);
mp_obj_t mp_load_const_str(qstr qstr);
mp_obj_t mp_load_const_bytes(qstr qstr);
-mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args);
-mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args);
mp_obj_t mp_make_function_n(int n_args, void *fun); // fun must have the correct signature for n_args fixed arguments
mp_obj_t mp_make_function_var(int n_args_min, mp_fun_var_t fun);
mp_obj_t mp_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive
-mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args);
mp_obj_t mp_call_function_0(mp_obj_t fun);
mp_obj_t mp_call_function_1(mp_obj_t fun, mp_obj_t arg);
diff --git a/py/runtime0.h b/py/runtime0.h
index 6ee70aa01d..eef3706794 100644
--- a/py/runtime0.h
+++ b/py/runtime0.h
@@ -86,7 +86,7 @@ typedef enum {
MP_F_STORE_MAP,
MP_F_BUILD_SET,
MP_F_STORE_SET,
- MP_F_MAKE_FUNCTION_FROM_ID,
+ MP_F_MAKE_FUNCTION_FROM_RAW_CODE,
MP_F_CALL_FUNCTION_N_KW_FOR_NATIVE,
MP_F_CALL_METHOD_N_KW,
MP_F_GETITER,
diff --git a/py/scope.c b/py/scope.c
index 51701727e6..391ad5da87 100644
--- a/py/scope.c
+++ b/py/scope.c
@@ -6,10 +6,12 @@
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
+#include "obj.h"
#include "parse.h"
+#include "emitglue.h"
#include "scope.h"
-scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint unique_code_id, uint emit_options) {
+scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint emit_options) {
scope_t *scope = m_new0(scope_t, 1);
scope->kind = kind;
scope->pn = pn;
@@ -41,7 +43,7 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint
default:
assert(0);
}
- scope->unique_code_id = unique_code_id;
+ scope->raw_code = mp_emit_glue_new_raw_code();
scope->emit_options = emit_options;
scope->id_info_alloc = 8;
scope->id_info = m_new(id_info_t, scope->id_info_alloc);
diff --git a/py/scope.h b/py/scope.h
index 07b41fe721..6e0990ea9c 100644
--- a/py/scope.h
+++ b/py/scope.h
@@ -29,7 +29,7 @@ typedef struct _scope_t {
mp_parse_node_t pn;
qstr source_file;
qstr simple_name;
- uint unique_code_id;
+ mp_raw_code_t *raw_code;
uint8_t scope_flags; // see runtime0.h
uint8_t emit_options; // see compile.h
uint16_t num_params;
@@ -41,7 +41,7 @@ typedef struct _scope_t {
id_info_t *id_info;
} scope_t;
-scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint unique_code_id, uint emit_options);
+scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint emit_options);
void scope_free(scope_t *scope);
id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added);
id_info_t *scope_find(scope_t *scope, qstr qstr);
diff --git a/py/vm.c b/py/vm.c
index f62cb2d7b1..be7cf01f00 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -7,6 +7,7 @@
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
+#include "emitglue.h"
#include "runtime.h"
#include "bc0.h"
#include "bc.h"
@@ -29,20 +30,25 @@ typedef enum {
UNWIND_JUMP,
} mp_unwind_reason_t;
-#define DECODE_UINT { \
+#define DECODE_UINT do { \
unum = 0; \
do { \
unum = (unum << 7) + (*ip & 0x7f); \
} while ((*ip++ & 0x80) != 0); \
-}
+} while (0)
#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0)
#define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0)
-#define DECODE_QSTR { \
+#define DECODE_QSTR do { \
qst = 0; \
do { \
qst = (qst << 7) + (*ip & 0x7f); \
} while ((*ip++ & 0x80) != 0); \
-}
+} while (0)
+#define DECODE_PTR do { \
+ ip = (byte*)(((machine_uint_t)ip + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1))); /* align ip */ \
+ unum = *(machine_uint_t*)ip; \
+ ip += sizeof(machine_uint_t); \
+} while (0)
#define PUSH(val) *++sp = (val)
#define POP() (*sp--)
#define TOP() (*sp)
@@ -704,29 +710,29 @@ unwind_jump:
break;
case MP_BC_MAKE_FUNCTION:
- DECODE_UINT;
- PUSH(mp_make_function_from_id(unum, MP_OBJ_NULL, MP_OBJ_NULL));
+ DECODE_PTR;
+ PUSH(mp_make_function_from_raw_code((mp_raw_code_t*)unum, MP_OBJ_NULL, MP_OBJ_NULL));
break;
case MP_BC_MAKE_FUNCTION_DEFARGS:
- DECODE_UINT;
+ DECODE_PTR;
// Stack layout: def_tuple def_dict <- TOS
obj1 = POP();
- SET_TOP(mp_make_function_from_id(unum, TOP(), obj1));
+ SET_TOP(mp_make_function_from_raw_code((mp_raw_code_t*)unum, TOP(), obj1));
break;
case MP_BC_MAKE_CLOSURE:
- DECODE_UINT;
+ DECODE_PTR;
// Stack layout: closure_tuple <- TOS
- SET_TOP(mp_make_closure_from_id(unum, TOP(), MP_OBJ_NULL, MP_OBJ_NULL));
+ SET_TOP(mp_make_closure_from_raw_code((mp_raw_code_t*)unum, TOP(), MP_OBJ_NULL, MP_OBJ_NULL));
break;
case MP_BC_MAKE_CLOSURE_DEFARGS:
- DECODE_UINT;
+ DECODE_PTR;
// Stack layout: def_tuple def_dict closure_tuple <- TOS
obj1 = POP();
obj2 = POP();
- SET_TOP(mp_make_closure_from_id(unum, obj1, TOP(), obj2));
+ SET_TOP(mp_make_closure_from_raw_code((mp_raw_code_t*)unum, obj1, TOP(), obj2));
break;
case MP_BC_CALL_FUNCTION: