py: Factor out code from runtime.c to emitglue.c.
This commit is contained in:
parent
8767d0710e
commit
2326d52d20
@ -13,6 +13,7 @@
|
|||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
#include "emitglue.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -213,7 +214,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) {
|
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, rt_get_unique_code_id(), emit_options);
|
scope_t *scope = scope_new(kind, pn, comp->source_file, mp_emit_glue_get_unique_code_id(), emit_options);
|
||||||
scope->parent = comp->scope_cur;
|
scope->parent = comp->scope_cur;
|
||||||
scope->next = NULL;
|
scope->next = NULL;
|
||||||
if (comp->scope_head == NULL) {
|
if (comp->scope_head == NULL) {
|
||||||
@ -1149,14 +1150,14 @@ void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
|
|
||||||
void compile_break_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
void compile_break_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||||
if (comp->break_label == 0) {
|
if (comp->break_label == 0) {
|
||||||
printf("ERROR: cannot break from here\n");
|
compile_syntax_error(comp, "'break' outside loop");
|
||||||
}
|
}
|
||||||
EMIT_ARG(break_loop, comp->break_label, comp->cur_except_level - comp->break_continue_except_level);
|
EMIT_ARG(break_loop, comp->break_label, comp->cur_except_level - comp->break_continue_except_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_continue_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
void compile_continue_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||||
if (comp->continue_label == 0) {
|
if (comp->continue_label == 0) {
|
||||||
printf("ERROR: cannot continue from here\n");
|
compile_syntax_error(comp, "'continue' outside loop");
|
||||||
}
|
}
|
||||||
EMIT_ARG(continue_loop, comp->continue_label, comp->cur_except_level - comp->break_continue_except_level);
|
EMIT_ARG(continue_loop, comp->continue_label, comp->cur_except_level - comp->break_continue_except_level);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ typedef struct _emit_method_table_t {
|
|||||||
void (*setup_except)(emit_t *emit, int label);
|
void (*setup_except)(emit_t *emit, int label);
|
||||||
void (*setup_finally)(emit_t *emit, int label);
|
void (*setup_finally)(emit_t *emit, int label);
|
||||||
void (*end_finally)(emit_t *emit);
|
void (*end_finally)(emit_t *emit);
|
||||||
void (*get_iter)(emit_t *emit); // tos = getiter(tos)
|
void (*get_iter)(emit_t *emit);
|
||||||
void (*for_iter)(emit_t *emit, int label);
|
void (*for_iter)(emit_t *emit, int label);
|
||||||
void (*for_iter_end)(emit_t *emit);
|
void (*for_iter_end)(emit_t *emit);
|
||||||
void (*pop_block)(emit_t *emit);
|
void (*pop_block)(emit_t *emit);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
#include "emitglue.h"
|
||||||
#include "bc0.h"
|
#include "bc0.h"
|
||||||
|
|
||||||
struct _emit_t {
|
struct _emit_t {
|
||||||
@ -271,9 +272,9 @@ STATIC void emit_bc_end_pass(emit_t *emit) {
|
|||||||
for (int i = 0; i < emit->scope->num_params; i++) {
|
for (int i = 0; i < emit->scope->num_params; i++) {
|
||||||
arg_names[i] = emit->scope->id_info[i].qstr;
|
arg_names[i] = emit->scope->id_info[i].qstr;
|
||||||
}
|
}
|
||||||
rt_assign_byte_code(emit->scope->unique_code_id, emit->code_base,
|
mp_emit_glue_assign_byte_code(emit->scope->unique_code_id, emit->code_base,
|
||||||
emit->code_info_size + emit->byte_code_size,
|
emit->code_info_size + emit->byte_code_size,
|
||||||
emit->scope->num_params, emit->scope->num_locals, emit->scope->stack_size,
|
emit->scope->num_params, emit->scope->num_locals,
|
||||||
emit->scope->scope_flags, arg_names);
|
emit->scope->scope_flags, arg_names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
206
py/emitglue.c
Normal file
206
py/emitglue.c
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
// This code glues the code emitters to the runtime.
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mpconfig.h"
|
||||||
|
#include "qstr.h"
|
||||||
|
#include "obj.h"
|
||||||
|
#include "runtime0.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
#include "emitglue.h"
|
||||||
|
|
||||||
|
#if 0 // print debugging info
|
||||||
|
#define DEBUG_PRINT (1)
|
||||||
|
#define WRITE_CODE (1)
|
||||||
|
#define DEBUG_printf DEBUG_printf
|
||||||
|
#define DEBUG_OP_printf(...) DEBUG_printf(__VA_ARGS__)
|
||||||
|
#else // don't print debugging info
|
||||||
|
#define DEBUG_printf(...) (void)0
|
||||||
|
#define DEBUG_OP_printf(...) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MP_CODE_NONE,
|
||||||
|
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 mp_code_t *unique_codes = NULL;
|
||||||
|
STATIC uint next_unique_code_id;
|
||||||
|
|
||||||
|
void mp_emit_glue_init(void) {
|
||||||
|
next_unique_code_id = 0;
|
||||||
|
unique_codes_alloc = 0;
|
||||||
|
unique_codes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_emit_glue_deinit(void) {
|
||||||
|
m_del(mp_code_t, unique_codes, unique_codes_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint mp_emit_glue_get_unique_code_id(void) {
|
||||||
|
return next_unique_code_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mp_emit_glue_alloc_unique_codes(void) {
|
||||||
|
if (next_unique_code_id > unique_codes_alloc) {
|
||||||
|
DEBUG_printf("allocate more unique codes: " UINT_FMT " -> %u\n", unique_codes_alloc, next_unique_code_id);
|
||||||
|
// increase size of unique_codes table
|
||||||
|
unique_codes = m_renew(mp_code_t, unique_codes, unique_codes_alloc, next_unique_code_id);
|
||||||
|
for (uint i = unique_codes_alloc; i < next_unique_code_id; i++) {
|
||||||
|
unique_codes[i].kind = MP_CODE_NONE;
|
||||||
|
}
|
||||||
|
unique_codes_alloc = next_unique_code_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
for (int i = 0; i < 128 && i < len; i++) {
|
||||||
|
if (i > 0 && i % 16 == 0) {
|
||||||
|
DEBUG_printf("\n");
|
||||||
|
}
|
||||||
|
DEBUG_printf(" %02x", code[i]);
|
||||||
|
}
|
||||||
|
DEBUG_printf("\n");
|
||||||
|
#if MICROPY_DEBUG_PRINTERS
|
||||||
|
mp_byte_code_print(code, len);
|
||||||
|
#endif
|
||||||
|
#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 < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
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) {
|
||||||
|
DEBUG_printf("\n");
|
||||||
|
}
|
||||||
|
DEBUG_printf(" %02x", fun_data[i]);
|
||||||
|
}
|
||||||
|
DEBUG_printf("\n");
|
||||||
|
|
||||||
|
#ifdef WRITE_CODE
|
||||||
|
if (fp_write_code != NULL) {
|
||||||
|
fwrite(fun_data, len, 1, fp_write_code);
|
||||||
|
fflush(fp_write_code);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#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 < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
||||||
|
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;
|
||||||
|
|
||||||
|
#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);
|
||||||
|
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) {
|
||||||
|
DEBUG_printf("\n");
|
||||||
|
}
|
||||||
|
DEBUG_printf(" %02x", fun_data[i]);
|
||||||
|
}
|
||||||
|
DEBUG_printf("\n");
|
||||||
|
|
||||||
|
#ifdef WRITE_CODE
|
||||||
|
if (fp_write_code != NULL) {
|
||||||
|
fwrite(fun_data, len, 1, fp_write_code);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args) {
|
||||||
|
DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id);
|
||||||
|
if (unique_code_id >= next_unique_code_id) {
|
||||||
|
// illegal code id
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make the function, depending on the code kind
|
||||||
|
mp_code_t *c = &unique_codes[unique_code_id];
|
||||||
|
mp_obj_t fun;
|
||||||
|
switch (c->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);
|
||||||
|
break;
|
||||||
|
case MP_CODE_NATIVE:
|
||||||
|
fun = rt_make_function_n(c->n_args, c->u_native.fun);
|
||||||
|
break;
|
||||||
|
case MP_CODE_INLINE_ASM:
|
||||||
|
fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
fun = mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for generator functions and if so wrap in generator object
|
||||||
|
if ((c->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
|
||||||
|
fun = mp_obj_new_gen_wrap(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args) {
|
||||||
|
DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id);
|
||||||
|
// make function object
|
||||||
|
mp_obj_t ffun = rt_make_function_from_id(unique_code_id, def_args);
|
||||||
|
// wrap function in closure object
|
||||||
|
return mp_obj_new_closure(ffun, closure_tuple);
|
||||||
|
}
|
9
py/emitglue.h
Normal file
9
py/emitglue.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// These variables and functions glue the code emitters to the runtime.
|
||||||
|
|
||||||
|
void mp_emit_glue_init(void);
|
||||||
|
void mp_emit_glue_deinit(void);
|
||||||
|
uint mp_emit_glue_get_unique_code_id(void);
|
||||||
|
uint mp_emit_glue_get_unique_code(uint unique_code_id);
|
||||||
|
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);
|
@ -11,6 +11,7 @@
|
|||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
#include "emitglue.h"
|
||||||
#include "asmthumb.h"
|
#include "asmthumb.h"
|
||||||
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_THUMB
|
||||||
@ -51,7 +52,7 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
|
|||||||
|
|
||||||
if (emit->pass == PASS_3) {
|
if (emit->pass == PASS_3) {
|
||||||
void *f = asm_thumb_get_code(emit->as);
|
void *f = asm_thumb_get_code(emit->as);
|
||||||
rt_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->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
#include "emitglue.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
@ -275,10 +276,10 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
|||||||
if (emit->pass == PASS_3) {
|
if (emit->pass == PASS_3) {
|
||||||
#if N_X64
|
#if N_X64
|
||||||
void *f = asm_x64_get_code(emit->as);
|
void *f = asm_x64_get_code(emit->as);
|
||||||
rt_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->unique_code_id, f, asm_x64_get_code_size(emit->as), emit->scope->num_params);
|
||||||
#elif N_THUMB
|
#elif N_THUMB
|
||||||
void *f = asm_thumb_get_code(emit->as);
|
void *f = asm_thumb_get_code(emit->as);
|
||||||
rt_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->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
py/py.mk
1
py/py.mk
@ -35,6 +35,7 @@ PY_O_BASENAME = \
|
|||||||
formatfloat.o \
|
formatfloat.o \
|
||||||
parsenumbase.o \
|
parsenumbase.o \
|
||||||
parsenum.o \
|
parsenum.o \
|
||||||
|
emitglue.o \
|
||||||
runtime.o \
|
runtime.o \
|
||||||
map.o \
|
map.o \
|
||||||
obj.o \
|
obj.o \
|
||||||
|
195
py/runtime.c
195
py/runtime.c
@ -1,11 +1,6 @@
|
|||||||
// in principle, rt_xxx functions are called only by vm/native/viper and make assumptions about args
|
|
||||||
// mp_xxx functions are safer and can be called by anyone
|
|
||||||
// note that rt_assign_xxx are called only from emit*, and maybe we can rename them to reflect this
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
@ -16,6 +11,7 @@
|
|||||||
#include "parsenum.h"
|
#include "parsenum.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
#include "emitglue.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "builtintables.h"
|
#include "builtintables.h"
|
||||||
@ -37,36 +33,6 @@ STATIC mp_map_t *map_locals;
|
|||||||
STATIC mp_map_t *map_globals;
|
STATIC mp_map_t *map_globals;
|
||||||
STATIC mp_map_t map_builtins;
|
STATIC mp_map_t map_builtins;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MP_CODE_NONE,
|
|
||||||
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 uint next_unique_code_id;
|
|
||||||
STATIC machine_uint_t unique_codes_alloc = 0;
|
|
||||||
STATIC mp_code_t *unique_codes = NULL;
|
|
||||||
|
|
||||||
#ifdef WRITE_CODE
|
#ifdef WRITE_CODE
|
||||||
FILE *fp_write_code = NULL;
|
FILE *fp_write_code = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -77,6 +43,8 @@ STATIC void mp_map_add_qstr(mp_map_t *map, qstr qstr, mp_obj_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rt_init(void) {
|
void rt_init(void) {
|
||||||
|
mp_emit_glue_init();
|
||||||
|
|
||||||
// locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
|
// locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
|
||||||
map_locals = map_globals = mp_map_new(1);
|
map_locals = map_globals = mp_map_new(1);
|
||||||
|
|
||||||
@ -101,129 +69,21 @@ void rt_init(void) {
|
|||||||
//sys_path = mp_obj_new_list(0, NULL);
|
//sys_path = mp_obj_new_list(0, NULL);
|
||||||
//rt_store_attr(m_sys, MP_QSTR_path, sys_path);
|
//rt_store_attr(m_sys, MP_QSTR_path, sys_path);
|
||||||
|
|
||||||
// TODO: wastes one mp_code_t structure in mem
|
|
||||||
next_unique_code_id = 1; // 0 indicates "no code"
|
|
||||||
unique_codes_alloc = 0;
|
|
||||||
unique_codes = NULL;
|
|
||||||
|
|
||||||
#ifdef WRITE_CODE
|
#ifdef WRITE_CODE
|
||||||
fp_write_code = fopen("out-code", "wb");
|
fp_write_code = fopen("out-code", "wb");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_deinit(void) {
|
void rt_deinit(void) {
|
||||||
m_del(mp_code_t, unique_codes, unique_codes_alloc);
|
|
||||||
mp_map_free(map_globals);
|
|
||||||
mp_map_deinit(&map_builtins);
|
|
||||||
mp_module_deinit();
|
|
||||||
#ifdef WRITE_CODE
|
#ifdef WRITE_CODE
|
||||||
if (fp_write_code != NULL) {
|
if (fp_write_code != NULL) {
|
||||||
fclose(fp_write_code);
|
fclose(fp_write_code);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
mp_map_free(map_globals);
|
||||||
|
mp_map_deinit(&map_builtins);
|
||||||
uint rt_get_unique_code_id(void) {
|
mp_module_deinit();
|
||||||
return next_unique_code_id++;
|
mp_emit_glue_deinit();
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void alloc_unique_codes(void) {
|
|
||||||
if (next_unique_code_id > unique_codes_alloc) {
|
|
||||||
DEBUG_printf("allocate more unique codes: " UINT_FMT " -> %u\n", unique_codes_alloc, next_unique_code_id);
|
|
||||||
// increase size of unique_codes table
|
|
||||||
unique_codes = m_renew(mp_code_t, unique_codes, unique_codes_alloc, next_unique_code_id);
|
|
||||||
for (uint i = unique_codes_alloc; i < next_unique_code_id; i++) {
|
|
||||||
unique_codes[i].kind = MP_CODE_NONE;
|
|
||||||
}
|
|
||||||
unique_codes_alloc = next_unique_code_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, uint scope_flags, qstr *arg_names) {
|
|
||||||
alloc_unique_codes();
|
|
||||||
|
|
||||||
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
|
||||||
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);
|
|
||||||
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
DEBUG_printf("assign byte code: id=%d code=%p len=%u n_args=%d n_locals=%d n_stack=%d\n", unique_code_id, code, len, n_args, n_locals, n_stack);
|
|
||||||
for (int i = 0; i < 128 && i < len; i++) {
|
|
||||||
if (i > 0 && i % 16 == 0) {
|
|
||||||
DEBUG_printf("\n");
|
|
||||||
}
|
|
||||||
DEBUG_printf(" %02x", code[i]);
|
|
||||||
}
|
|
||||||
DEBUG_printf("\n");
|
|
||||||
#if MICROPY_DEBUG_PRINTERS
|
|
||||||
mp_byte_code_print(code, len);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_assign_native_code(uint unique_code_id, void *fun, uint len, int n_args) {
|
|
||||||
alloc_unique_codes();
|
|
||||||
|
|
||||||
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
|
||||||
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);
|
|
||||||
|
|
||||||
#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);
|
|
||||||
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) {
|
|
||||||
DEBUG_printf("\n");
|
|
||||||
}
|
|
||||||
DEBUG_printf(" %02x", fun_data[i]);
|
|
||||||
}
|
|
||||||
DEBUG_printf("\n");
|
|
||||||
|
|
||||||
#ifdef WRITE_CODE
|
|
||||||
if (fp_write_code != NULL) {
|
|
||||||
fwrite(fun_data, len, 1, fp_write_code);
|
|
||||||
fflush(fp_write_code);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_assign_inline_asm_code(uint unique_code_id, void *fun, uint len, int n_args) {
|
|
||||||
alloc_unique_codes();
|
|
||||||
|
|
||||||
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id && unique_codes[unique_code_id].kind == MP_CODE_NONE);
|
|
||||||
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;
|
|
||||||
|
|
||||||
#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);
|
|
||||||
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) {
|
|
||||||
DEBUG_printf("\n");
|
|
||||||
}
|
|
||||||
DEBUG_printf(" %02x", fun_data[i]);
|
|
||||||
}
|
|
||||||
DEBUG_printf("\n");
|
|
||||||
|
|
||||||
#ifdef WRITE_CODE
|
|
||||||
if (fp_write_code != NULL) {
|
|
||||||
fwrite(fun_data, len, 1, fp_write_code);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int rt_is_true(mp_obj_t arg) {
|
int rt_is_true(mp_obj_t arg) {
|
||||||
@ -646,47 +506,6 @@ generic_binary_op:
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args) {
|
|
||||||
DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id);
|
|
||||||
if (unique_code_id < 1 || unique_code_id >= next_unique_code_id) {
|
|
||||||
// illegal code id
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make the function, depending on the code kind
|
|
||||||
mp_code_t *c = &unique_codes[unique_code_id];
|
|
||||||
mp_obj_t fun;
|
|
||||||
switch (c->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);
|
|
||||||
break;
|
|
||||||
case MP_CODE_NATIVE:
|
|
||||||
fun = rt_make_function_n(c->n_args, c->u_native.fun);
|
|
||||||
break;
|
|
||||||
case MP_CODE_INLINE_ASM:
|
|
||||||
fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
fun = mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for generator functions and if so wrap in generator object
|
|
||||||
if ((c->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
|
|
||||||
fun = mp_obj_new_gen_wrap(fun);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args) {
|
|
||||||
DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id);
|
|
||||||
// make function object
|
|
||||||
mp_obj_t ffun = rt_make_function_from_id(unique_code_id, def_args);
|
|
||||||
// wrap function in closure object
|
|
||||||
return mp_obj_new_closure(ffun, closure_tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t rt_call_function_0(mp_obj_t fun) {
|
mp_obj_t rt_call_function_0(mp_obj_t fun) {
|
||||||
return rt_call_function_n_kw(fun, 0, 0, NULL);
|
return rt_call_function_n_kw(fun, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
void rt_init(void);
|
||||||
|
void rt_deinit(void);
|
||||||
|
|
||||||
void rt_check_nargs(int n_args, machine_uint_t n_args_min, machine_uint_t n_args_max, int n_kw, bool is_kw);
|
void rt_check_nargs(int n_args, machine_uint_t n_args_min, machine_uint_t n_args_max, int n_kw, bool is_kw);
|
||||||
|
|
||||||
int rt_is_true(mp_obj_t arg);
|
int rt_is_true(mp_obj_t arg);
|
||||||
|
@ -93,10 +93,3 @@ typedef enum {
|
|||||||
} rt_fun_kind_t;
|
} rt_fun_kind_t;
|
||||||
|
|
||||||
extern void *const rt_fun_table[RT_F_NUMBER_OF];
|
extern void *const rt_fun_table[RT_F_NUMBER_OF];
|
||||||
|
|
||||||
void rt_init(void);
|
|
||||||
void rt_deinit(void);
|
|
||||||
uint rt_get_unique_code_id(void);
|
|
||||||
void rt_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, uint scope_flags, qstr *arg_names);
|
|
||||||
void rt_assign_native_code(uint unique_code_id, void *f, uint len, int n_args);
|
|
||||||
void rt_assign_inline_asm_code(uint unique_code_id, void *f, uint len, int n_args);
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "parsehelper.h"
|
#include "parsehelper.h"
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
#include "runtime0.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
void do_file(const char *file) {
|
void do_file(const char *file) {
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_file(file);
|
mp_lexer_t *lex = mp_lexer_new_from_file(file);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user