Commit 597f3103 authored by Damien George's avatar Damien George

Update MicroPython glue and skel to handle encode/decode of ASN types.

parent 49bd33f0
......@@ -65,7 +65,6 @@ void micropython_mpy_bind_preamble(FV * fv)
if (hasparam) {
fprintf(mpy_bind_h, "#include \"C_ASN1_Types.h\"\n\n");
fprintf(mpy_bind_c, "#include \"MicroPython_ASN1_Types.h\"\n\n");
}
fprintf(mpy_bind_h,
......@@ -83,6 +82,10 @@ void micropython_mpy_bind_preamble(FV * fv)
fprintf(mpy_bind_c, "#include \"%s_mpy_bindings.h\"\n", fv->name);
fprintf(mpy_bind_c, "#include \"%s.mpy.h\"\n\n", fv->name);
if (hasparam) {
fprintf(mpy_bind_c, "#include \"MicroPython_ASN1_Types.h\"\n\n");
}
if (has_context_param(fv)) {
char *fv_no_underscore =
underscore_to_dash(fv->name, strlen(fv->name));
......@@ -93,6 +96,28 @@ void micropython_mpy_bind_preamble(FV * fv)
free(fv_no_underscore);
}
fprintf(mpy_bind_c,
"typedef struct {\n"
" mp_obj_base_t base;\n"
" size_t len;\n"
" mp_obj_t items[2];\n"
"} mp_obj_tuple_wrap_t;\n\n");
fprintf(mpy_bind_c, "extern mp_obj_type_t mp_type_mutable_attrtuple;\n\n");
fprintf(mpy_bind_c, "static qstr wrap_fields[1] = {MP_QSTR_val};\n\n");
fprintf(mpy_bind_c,
"static mp_obj_t mp_obj_new_wrap(mp_obj_t arg) {\n"
" mp_obj_tuple_wrap_t *o = m_new_obj(mp_obj_tuple_wrap_t);\n"
" o->base.type = &mp_type_mutable_attrtuple;\n"
" o->len = 1;\n"
" o->items[0] = arg;\n"
" o->items[1] = MP_OBJ_FROM_PTR(wrap_fields);\n"
" return MP_OBJ_FROM_PTR(o);\n"
"}\n"
"MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_new_wrap_obj, mp_obj_new_wrap);\n\n");
fprintf(mpy_bind_c, "mp_state_ctx_t *mp_current_ctx;\n"); // TODO there should only be one of these per executable
fprintf(mpy_bind_c, "static mp_state_ctx_t mp_ctx;\n");
fprintf(mpy_bind_c, "static uint64_t mp_heap[4096];\n");
......@@ -114,6 +139,7 @@ void micropython_mpy_bind_preamble(FV * fv)
" gc_init(mp_heap, (uint8_t*)mp_heap + sizeof(mp_heap));\n"
" mp_pystack_init(mp_pystack, (uint8_t*)mp_pystack + sizeof(mp_pystack));\n"
" mp_init();\n"
" mp_taste_types_init();\n"
" mp_exec_mpy(mpy_script_data, mpy_script_len);\n"
);
......@@ -149,7 +175,6 @@ void micropython_add_PI_to_glue(Interface * i)
size_t sig_len = strlen(signature);
char *sep = make_string(",\n%*s", sig_len, "");
char *sep_py = make_string(",\n%*s", strlen(signature_py), "");
size_t n_args = 0;
fprintf(mpy_bind_h, "%s", signature);
......@@ -190,32 +215,73 @@ void micropython_add_PI_to_glue(Interface * i)
" if (nlr_push(&nlr) == 0) {\n"
);
/* Convert the incoming IN parameters into MicroPython objects */
/* Encode the incoming IN data to MicroPython objects */
n_args = 0;
FOREACH (p, Parameter, i->in, {
fprintf(mpy_bind_c,
" args[%u] = mp_obj_new_asn1Scc%s(IN_%s);\n", n_args, p->type, p->name);
" #ifdef MICROPY_TASTE_NEED_DATA_FOR_%s\n"
" mp_obj_asn1Scc%s_t IN_%s_data;\n"
" args[%u] = mp_obj_encode_asn1Scc%s(IN_%s, &IN_%s_data);\n"
" #else\n"
" args[%u] = mp_obj_encode_asn1Scc%s(IN_%s, NULL);\n"
" #endif\n",
p->type,
p->type, p->name,
n_args, p->type, p->name, p->name,
n_args, p->type, p->name);
n_args += 1;
});
size_t n_in_args = n_args;
/* TODO deal with out parameters */
/* Encode the incoming OUT data to MicroPython objects */
FOREACH (p, Parameter, i->out, {
fprintf(mpy_bind_c,
" mp_obj_tuple_wrap_t wrap%u = {{&mp_type_mutable_attrtuple}, 1, {MP_OBJ_NULL, MP_OBJ_FROM_PTR(wrap_fields)}};\n"
" #ifdef MICROPY_TASTE_NEED_DATA_FOR_%s\n"
" mp_obj_asn1Scc%s_t OUT_%s_data;\n"
" wrap%u.items[0] = mp_obj_encode_asn1Scc%s(OUT_%s, &OUT_%s_data);\n"
" #else\n"
" wrap%u.items[0] = mp_obj_encode_asn1Scc%s(OUT_%s, NULL);\n"
" #endif\n"
" args[%u] = &wrap%u;\n",
n_args,
p->type,
p->type, p->name,
n_args, p->type, p->name, p->name,
n_args, p->type, p->name,
n_args, n_args
);
n_args += 1;
});
/* Call the MicroPython function */
fprintf(mpy_bind_c,
" mp_call_function_n_kw(mp_global_%s_PI_%s, %u, 0, args);\n"
" mp_call_function_n_kw(mp_global_%s_PI_%s, %u, 0, args);\n",
i->parent_fv->name, i->name, n_args
);
/* Decode the outgoing OUT MicroPython objects to data */
n_args = n_in_args;
FOREACH (p, Parameter, i->out, {
fprintf(mpy_bind_c,
" mp_obj_decode_asn1Scc%s(wrap%u.items[0], OUT_%s);\n",
p->type, n_args, p->name);
n_args += 1;
});
/* Clean up the exception handling */
fprintf(mpy_bind_c,
" nlr_pop();\n"
" } else {\n"
" mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));\n"
" }\n"
"}\n"
"\n",
i->parent_fv->name, i->name, n_args
"\n"
);
free(signature);
free(signature_py);
free(sep);
free(sep_py);
}
void micropython_add_RI_to_glue(Interface * i)
......@@ -252,24 +318,32 @@ void micropython_add_RI_to_glue(Interface * i)
free(sep);
fprintf(mpy_bind_c,
"STATIC mp_obj_t %s_RI_%s_wrap(size_t n_args, const mp_obj_t *args)\n"
"{\n",
"STATIC mp_obj_t %s_RI_%s_wrap(size_t n_args, const mp_obj_t *args) {\n"
" (void)n_args;\n",
i->parent_fv->name, i->name
);
/* Decode the incoming IN MicroPython objects to data */
n_args = 0;
FOREACH (p, Parameter, i->in, {
fprintf(mpy_bind_c,
" asn1Scc%s asn_IN_%s = mp_obj_get_int(args[%u]);\n",
p->type, p->name, n_args);
" asn1Scc%s asn_IN_%s;\n"
" mp_obj_decode_asn1Scc%s(args[%u], &asn_IN_%s);\n",
p->type, p->name,
p->type, n_args, p->name);
n_args += 1;
});
n_args = 0;
size_t n_in_args = n_args;
/* Create local state for the OUT data */
FOREACH (p, Parameter, i->out, {
fprintf(mpy_bind_c,
" asn1Scc%s asn_OUT_%s;\n",
p->type, p->name);
n_args += 1;
});
/* Call the RI */
fprintf(mpy_bind_c, " %s_RI_%s(", i->parent_fv->name, i->name);
n_args = 0;
FOREACH (p, Parameter, i->in, {
......@@ -282,6 +356,16 @@ void micropython_add_RI_to_glue(Interface * i)
});
fprintf(mpy_bind_c, ");\n");
/* Encode the OUT data to MicroPython objects */
n_args = n_in_args;
FOREACH (p, Parameter, i->out, {
/* TODO verify that the argument objects are of the correct type */
fprintf(mpy_bind_c,
" ((mp_obj_tuple_t*)MP_OBJ_TO_PTR(args[%u]))->items[0] = mp_obj_encode_asn1Scc%s(&asn_OUT_%s, MP_OBJ_TO_PTR(((mp_obj_tuple_t*)MP_OBJ_TO_PTR(args[%u]))->items[0]));\n",
n_args, p->type, p->name, n_args);
n_args += 1;
});
fprintf(mpy_bind_c,
" return mp_const_none;\n"
"}\n"
......@@ -318,9 +402,12 @@ void End_MicroPython_Glue_Backend(FV *fv)
{
// Generate the taste module
fprintf(mpy_bind_c, "MICROPY_TASTE_ASN_CONSTRUCTORS\n");
fprintf(mpy_bind_c,
"STATIC const mp_rom_map_elem_t taste_module_globals_table[] = {\n"
" { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_taste) },\n"
" { MP_ROM_QSTR(MP_QSTR_Ref), MP_ROM_PTR(&mp_obj_new_wrap_obj) },\n"
);
FOREACH(i, Interface, fv->interfaces, {
......@@ -332,6 +419,7 @@ void End_MicroPython_Glue_Backend(FV *fv)
);
}
});
fprintf(mpy_bind_c, "MICROPY_TASTE_ASN_MAP_ENTRIES\n");
fprintf(mpy_bind_c,
"};\n"
......
......@@ -56,13 +56,13 @@ void import_RI_to_MicroPython_skel(Interface * i)
FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s: asn1Scc%s",
comma ? "," : "", p->name, p->type);
comma ? ", " : "", p->name, p->type);
comma = true;
});
FOREACH (p, Parameter, i->out, {
fprintf(user_code_py,"%sOUT_%s: asn1Scc%s",
comma ? "," : "", p->name, p->type);
comma ? ", " : "", p->name, p->type);
comma = true;
});
......@@ -85,7 +85,8 @@ void micropython_skel_preamble(FV * fv)
if (NULL != user_code_py) {
fprintf(user_code_py,
"# User code: This file will not be overwritten by TASTE.\n\n");
fprintf(user_code_py, "import micropython\n\n");
fprintf(user_code_py, "import micropython\n");
fprintf(user_code_py, "from taste import * # import all ASN types\n\n");
FOREACH(i, Interface, fv->interfaces, {
if (i->direction == RI && gen_this_ri(i)) {
......@@ -111,8 +112,10 @@ void micropython_skel_preamble(FV * fv)
fprintf(user_code_py,
" # Write your initialization code here,\n"
" # but do not make any call to a required interface.\n"
" pass\n"
"\n\n");
" # It's recommended to lock the heap once initialisation is done, but\n"
" # note that without the heap some Python operations are not possible.\n"
" micropython.heap_lock()\n"
"\n");
}
}
......@@ -162,33 +165,32 @@ void add_PI_to_MicroPython_skel(Interface * i)
char *signature_py = make_string("def %s_PI_%s(",
i->parent_fv->name,
i->name);
char *sep_py = make_string(",\n%*s", strlen(signature_py), "");
bool comma = false;
fprintf(user_code_py, "%s", signature_py);
#if 0
// This code generates type hints for the parameters, but need to have the identifiers defined as globals first...
#if 1
// This code generates type hints for the parameters
FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s : asn1Scc%s",
comma ? sep_py : "", p->name, p->type);
fprintf(user_code_py, "%sIN_%s: asn1Scc%s",
comma ? ", " : "", p->name, p->type);
comma = true;
});
FOREACH (p, Parameter, i->out, {
fprintf(user_code_py, "%sOUT_%s : asn1Scc%s",
comma ? sep_py : "", p->name, p->type);
fprintf(user_code_py, "%sOUT_%s: asn1Scc%s",
comma ? ", " : "", p->name, p->type);
comma = true;
});
#else
// This code generates the parameter list without type hints.
FOREACH (p, Parameter, i->in, {
fprintf(user_code_py, "%sIN_%s", comma ? sep_py : "", p->name);
fprintf(user_code_py, "%sIN_%s", comma ? ", " : "", p->name);
comma = true;
});
FOREACH (p, Parameter, i->out, {
fprintf(user_code_py, "%sOUT_%s", comma ? sep_py : "", p->name);
fprintf(user_code_py, "%sOUT_%s", comma ? ", " : "", p->name);
comma = true;
});
#endif
......@@ -196,7 +198,6 @@ void add_PI_to_MicroPython_skel(Interface * i)
fprintf(user_code_py, "):\n # Write your code here!\n pass\n\n");
free(signature_py);
free(sep_py);
}
/* Add timer declarations to the C code skeletons */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment