Skip to content

Commit 127d1f5

Browse files
committed
fixing inline assembler (compile2.c)
1 parent 61398ab commit 127d1f5

File tree

1 file changed

+60
-46
lines changed

1 file changed

+60
-46
lines changed

py/compile2.c

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,7 +2932,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
29322932
comp->next_label = 1;
29332933

29342934
if (scope->kind != SCOPE_FUNCTION) {
2935-
compile_syntax_error(comp, MP_PARSE_NODE_NULL, "inline assembler must be a function");
2935+
compile_syntax_error(comp, NULL, "inline assembler must be a function");
29362936
return;
29372937
}
29382938

@@ -2941,109 +2941,123 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
29412941
}
29422942

29432943
// get the function definition parse node
2944-
assert(MP_PARSE_NODE_IS_STRUCT(scope->pn));
2945-
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn;
2946-
assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2944+
const byte *p = scope->pn;
2945+
assert(pt_is_any_id(p));
2946+
p = pt_next(p); // skip the function name
29472947

2948-
//qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
2949-
2950-
// parameters are in pns->nodes[1]
2948+
// parameters are in next node
29512949
if (comp->pass == MP_PASS_CODE_SIZE) {
2952-
mp_parse_node_t *pn_params;
2953-
int n_params = mp_parse_node_extract_list(&pns->nodes[1], PN_typedargslist, &pn_params);
2954-
scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params);
2950+
const byte *pp = p;
2951+
const byte *pptop = mp_parse_node_extract_list(&pp, PN_typedargslist);
2952+
scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, pp, pptop);
29552953
if (comp->compile_error != MP_OBJ_NULL) {
29562954
goto inline_asm_error;
29572955
}
29582956
}
29592957

2960-
assert(MP_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2958+
p = pt_next(p); // skip the parameter list
2959+
p = pt_next(p); // skip the return type
29612960

2962-
mp_parse_node_t pn_body = pns->nodes[3]; // body
2963-
mp_parse_node_t *nodes;
2964-
int num = mp_parse_node_extract_list(&pn_body, PN_suite_block_stmts, &nodes);
2961+
// get the list of statements within the body of the function
2962+
const byte *ptop = mp_parse_node_extract_list(&p, PN_suite_block_stmts);
29652963

2966-
for (int i = 0; i < num; i++) {
2967-
assert(MP_PARSE_NODE_IS_STRUCT(nodes[i]));
2968-
mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)nodes[i];
2969-
if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_pass_stmt) {
2964+
for (const byte *p_instr = p; p_instr != ptop; p_instr = pt_next(p_instr)) {
2965+
p = p_instr;
2966+
if (pt_is_rule(p, PN_pass_stmt)) {
29702967
// no instructions
29712968
continue;
2972-
} else if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_expr_stmt) {
2969+
} else if (!pt_is_rule(p, PN_expr_stmt)) {
29732970
// not an instruction; error
29742971
not_an_instruction:
2975-
compile_syntax_error(comp, nodes[i], "expecting an assembler instruction");
2972+
compile_syntax_error(comp, p, "expecting an assembler instruction");
29762973
return;
29772974
}
29782975

29792976
// check structure of parse node
2980-
assert(MP_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2981-
if (!MP_PARSE_NODE_IS_NULL(pns2->nodes[1])) {
2977+
const byte *p_expr_top;
2978+
const byte *p_expr = pt_rule_extract_top(p, &p_expr_top);
2979+
if (!pt_is_rule(p_expr, PN_power)) {
2980+
goto not_an_instruction;
2981+
}
2982+
if (pt_next(p_expr) != p_expr_top) {
29822983
goto not_an_instruction;
29832984
}
2984-
pns2 = (mp_parse_node_struct_t*)pns2->nodes[0];
2985-
if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_power) {
2985+
p_expr = pt_rule_extract_top(p_expr, &p_expr_top);
2986+
if (!pt_is_any_id(p_expr)) {
29862987
goto not_an_instruction;
29872988
}
2988-
if (!MP_PARSE_NODE_IS_ID(pns2->nodes[0])) {
2989+
const byte *p_expr_paren = pt_next(p_expr);
2990+
if (p_expr_paren == p_expr_top || !pt_is_rule(p_expr_paren, PN_trailer_paren)) {
29892991
goto not_an_instruction;
29902992
}
2991-
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)) {
2993+
if (pt_next(p_expr_paren) != p_expr_top) {
29922994
goto not_an_instruction;
29932995
}
2994-
assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[2]));
29952996

29962997
// parse node looks like an instruction
29972998
// get instruction name and args
2998-
qstr op = MP_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2999-
pns2 = (mp_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
3000-
mp_parse_node_t *pn_arg;
3001-
int n_args = mp_parse_node_extract_list(&pns2->nodes[0], PN_arglist, &pn_arg);
2999+
qstr op;
3000+
pt_extract_id(p_expr, &op);
3001+
3002+
const byte *p_args = pt_rule_first(p_expr_paren);
3003+
const byte *p_args_top = mp_parse_node_extract_list(&p_args, PN_arglist);
3004+
uint n_args = pt_num_nodes(p_args, p_args_top);
30023005

30033006
// emit instructions
30043007
if (op == MP_QSTR_label) {
3005-
if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) {
3006-
compile_syntax_error(comp, nodes[i], "'label' requires 1 argument");
3008+
if (!(n_args == 1 && pt_is_any_id(p_args))) {
3009+
compile_syntax_error(comp, p, "'label' requires 1 argument");
30073010
return;
30083011
}
30093012
uint lab = comp_next_label(comp);
30103013
if (pass > MP_PASS_SCOPE) {
3011-
if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) {
3012-
compile_syntax_error(comp, nodes[i], "label redefined");
3014+
qstr id;
3015+
pt_extract_id(p_args, &id);
3016+
if (!EMIT_INLINE_ASM_ARG(label, lab, id)) {
3017+
compile_syntax_error(comp, p, "label redefined");
30133018
return;
30143019
}
30153020
}
30163021
} else if (op == MP_QSTR_align) {
3017-
if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
3018-
compile_syntax_error(comp, nodes[i], "'align' requires 1 argument");
3022+
if (!(n_args == 1 && pt_is_small_int(p_args))) {
3023+
compile_syntax_error(comp, p, "'align' requires 1 argument");
30193024
return;
30203025
}
30213026
if (pass > MP_PASS_SCOPE) {
3022-
EMIT_INLINE_ASM_ARG(align, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]));
3027+
EMIT_INLINE_ASM_ARG(align, pt_small_int_value(p_args));
30233028
}
30243029
} else if (op == MP_QSTR_data) {
3025-
if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
3026-
compile_syntax_error(comp, nodes[i], "'data' requires at least 2 arguments");
3030+
if (!(n_args >= 2 && pt_is_small_int(p_args))) {
3031+
compile_syntax_error(comp, p, "'data' requires at least 2 arguments");
30273032
return;
30283033
}
30293034
if (pass > MP_PASS_SCOPE) {
3030-
mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
3035+
mp_int_t bytesize;
3036+
p_args = pt_get_small_int(p_args, &bytesize);
30313037
for (uint j = 1; j < n_args; j++) {
3032-
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) {
3033-
compile_syntax_error(comp, nodes[i], "'data' requires integer arguments");
3038+
if (!pt_is_small_int(p_args)) {
3039+
compile_syntax_error(comp, p, "'data' requires integer arguments");
30343040
return;
30353041
}
3036-
EMIT_INLINE_ASM_ARG(data, bytesize, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[j]));
3042+
mp_int_t val;
3043+
p_args = pt_get_small_int(p_args, &val);
3044+
EMIT_INLINE_ASM_ARG(data, bytesize, val);
30373045
}
30383046
}
30393047
} else {
30403048
if (pass > MP_PASS_SCOPE) {
3049+
if (n_args > 3) {
3050+
goto not_an_instruction;
3051+
}
3052+
const byte *pn_arg[3];
3053+
pn_arg[0] = p_args;
3054+
pn_arg[1] = pt_next(pn_arg[0]);
3055+
pn_arg[2] = pt_next(pn_arg[1]);
30413056
EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg);
30423057
}
30433058
}
30443059

30453060
if (comp->compile_error != MP_OBJ_NULL) {
3046-
pns = pns2; // this is the parse node that had the error
30473061
goto inline_asm_error;
30483062
}
30493063
}
@@ -3055,7 +3069,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
30553069
if (comp->compile_error != MP_OBJ_NULL) {
30563070
// inline assembler had an error; set line for its exception
30573071
inline_asm_error:
3058-
comp->compile_error_line = pns->source_line;
3072+
compile_error_set_line(comp, p);
30593073
}
30603074
}
30613075
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy