summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitnative.c
diff options
context:
space:
mode:
authorDamien <damien.p.george@gmail.com>2013-10-10 11:24:39 +0100
committerDamien <damien.p.george@gmail.com>2013-10-10 11:24:39 +0100
commit7f5dacf34566ba6bbc49ca5a276d01cf4996cc6e (patch)
treefc4a158f1e5a15799e887715a1007d10beea5e2d /py/emitnative.c
parenta397776d6bf1a9d0b07d7138b289cd661c5e1b99 (diff)
downloadmicropython-7f5dacf34566ba6bbc49ca5a276d01cf4996cc6e.tar.gz
micropython-7f5dacf34566ba6bbc49ca5a276d01cf4996cc6e.zip
Implement basic class/object in native code.
Diffstat (limited to 'py/emitnative.c')
-rw-r--r--py/emitnative.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/py/emitnative.c b/py/emitnative.c
index 4c2f941e03..2687e4fba6 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -344,7 +344,7 @@ static void need_reg_single(emit_t *emit, int reg_needed) {
}
}
-static void need_reg_all(emit_t *emit) {
+static void need_reg_all(emit_t *emit, int num_stack_top_that_must_be_value) {
for (int i = 0; i < emit->stack_size; i++) {
stack_info_t *si = &emit->stack_info[i];
if (si->kind == STACK_REG) {
@@ -352,6 +352,14 @@ static void need_reg_all(emit_t *emit) {
ASM_MOV_REG_TO_LOCAL(si->u_reg, emit->stack_start + i);
}
}
+ // must do this after making all registers available because ASM_MOV_IMM_TO_LOCAL uses a temporary register
+ for (int i = 0; i < num_stack_top_that_must_be_value; i++) {
+ stack_info_t *si = &emit->stack_info[emit->stack_size - 1 - i];
+ if (si->kind == STACK_IMM) {
+ si->kind = STACK_VALUE;
+ ASM_MOV_IMM_TO_LOCAL(si->u_imm, emit->stack_start + emit->stack_size - 1 - i);
+ }
+ }
}
static void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest) {
@@ -427,9 +435,10 @@ static void emit_post_push_reg_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, in
// vtype of all n_pop objects is VTYPE_PYOBJ
static void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, int reg_dest, int n_pop) {
- need_reg_all(emit);
+ need_reg_all(emit, n_pop);
for (int i = 0; i < n_pop; i++) {
- assert(emit->stack_info[emit->stack_size + i].vtype == VTYPE_PYOBJ);
+ assert(emit->stack_info[emit->stack_size - 1 - i].kind == STACK_VALUE);
+ assert(emit->stack_info[emit->stack_size - 1 - i].vtype == VTYPE_PYOBJ);
}
ASM_MOV_LOCAL_ADDR_TO_REG(emit->stack_start + emit->stack_size - 1, reg_dest);
adjust_stack(emit, -n_pop);
@@ -437,8 +446,9 @@ static void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, int reg_dest, in
// vtype of all n_push objects is VTYPE_PYOBJ
static void emit_get_stack_pointer_to_reg_for_push(emit_t *emit, int reg_dest, int n_push) {
- need_reg_all(emit);
+ need_reg_all(emit, 0);
for (int i = 0; i < n_push; i++) {
+ emit->stack_info[emit->stack_size + i].kind = STACK_VALUE;
emit->stack_info[emit->stack_size + i].vtype = VTYPE_PYOBJ;
}
ASM_MOV_LOCAL_ADDR_TO_REG(emit->stack_start + emit->stack_size + n_push - 1, reg_dest);
@@ -454,7 +464,7 @@ static void emit_call(emit_t *emit, rt_fun_kind_t fun_kind, void *fun) {
}
static void emit_call_with_imm_arg(emit_t *emit, rt_fun_kind_t fun_kind, void *fun, machine_int_t arg_val, int arg_reg) {
- need_reg_all(emit);
+ need_reg_all(emit, 0);
ASM_MOV_IMM_TO_REG(arg_val, arg_reg);
emit_call(emit, fun_kind, fun);
}
@@ -549,8 +559,13 @@ static void emit_native_load_const_dec(emit_t *emit, qstr qstr) {
}
static void emit_native_load_const_id(emit_t *emit, qstr qstr) {
- // not supported for viper?
- assert(0);
+ emit_pre(emit);
+ if (emit->do_viper_types) {
+ assert(0);
+ } else {
+ emit_call_with_imm_arg(emit, RT_F_LOAD_CONST_STR, rt_load_const_str, qstr, REG_ARG_1); // TODO
+ emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
+ }
}
static void emit_native_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
@@ -669,8 +684,9 @@ static void emit_native_load_method(emit_t *emit, qstr qstr) {
}
static void emit_native_load_build_class(emit_t *emit) {
- // not supported
- assert(0);
+ emit_pre(emit);
+ emit_call(emit, RT_F_LOAD_BUILD_CLASS, rt_load_build_class);
+ emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
}
static void emit_native_store_fast(emit_t *emit, qstr qstr, int local_num) {
@@ -727,8 +743,12 @@ static void emit_native_store_deref(emit_t *emit, qstr qstr) {
}
static void emit_native_store_attr(emit_t *emit, qstr qstr) {
- // not implemented
- assert(0);
+ vtype_kind_t vtype_base, vtype_val;
+ emit_pre_pop_reg_reg(emit, &vtype_base, REG_ARG_1, &vtype_val, REG_ARG_3); // arg1 = base, arg3 = value
+ assert(vtype_base == VTYPE_PYOBJ);
+ assert(vtype_val == VTYPE_PYOBJ);
+ emit_call_with_imm_arg(emit, RT_F_STORE_ATTR, rt_store_attr, qstr, REG_ARG_2); // arg2 = attribute name
+ emit_post(emit);
}
static void emit_native_store_subscr(emit_t *emit) {
@@ -1069,7 +1089,9 @@ static void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor
assert(vtype_arg1 == VTYPE_PYOBJ);
emit_call(emit, RT_F_CALL_METHOD_2, rt_call_method_2);
} else {
- assert(0);
+ emit_pre(emit);
+ emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_positional + 2); // pointer to items in reverse order, including meth and self
+ emit_call_with_imm_arg(emit, RT_F_CALL_METHOD_N, rt_call_method_n, n_positional, REG_ARG_1);
}
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
}