Skip to content

Commit 415eb6f

Browse files
committed
Restructure emit so it goes through a method table.
1 parent 492d082 commit 415eb6f

11 files changed

Lines changed: 842 additions & 450 deletions

File tree

py/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
*.o
2+
py
3+
*.py

py/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CC = gcc
2-
CFLAGS = -Wall -ansi -std=gnu99 -Os #-DNDEBUG
2+
CFLAGS = -Wall -ansi -std=gnu99 -Os -DEMIT_ENABLE_CPY -DEMIT_ENABLE_X64 #-DNDEBUG
33
LDFLAGS =
44

55
SRC = \

py/asmx64.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ asm_x64_t* asm_x64_new() {
113113

114114
void asm_x64_free(asm_x64_t* as, bool free_code) {
115115
if (free_code) {
116-
m_free(as->code_base);
116+
// need to un-mmap
117+
//m_free(as->code_base);
117118
}
118119
/*
119120
if (as->label != NULL) {
@@ -154,6 +155,8 @@ void asm_x64_end_pass(asm_x64_t *as) {
154155
// calculate size of code in bytes
155156
as->code_size = as->code_offset;
156157
as->code_base = m_new(byte, as->code_size);
158+
//uint actual_alloc;
159+
//as->code_base = alloc_mem(as->code_size, &actual_alloc, true);
157160
printf("code_size: %u\n", as->code_size);
158161
}
159162

@@ -611,11 +614,12 @@ void asm_x64_call_i1(asm_x64_t* as, void* func, int i1)
611614
*/
612615

613616
void asm_x64_call_ind(asm_x64_t* as, void *ptr, int temp_r64) {
614-
/*
615617
asm_x64_mov_i64_to_r64_optimised(as, (int64_t)ptr, temp_r64);
616618
asm_x64_write_byte_2(as, OPCODE_CALL_RM32, MODRM_R64(2) | MODRM_RM_REG | MODRM_RM_R64(temp_r64));
617-
*/
618619
// this reduces code size by 2 bytes per call, but doesn't seem to speed it up at all
620+
// doesn't work anymore because calls are 64 bits away
621+
/*
619622
asm_x64_write_byte_1(as, OPCODE_CALL_REL32);
620623
asm_x64_write_word32(as, ptr - (void*)(as->code_base + as->code_offset + 4));
624+
*/
621625
}

py/compile.c

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "emit.h"
1616

1717
// TODO need to mangle __attr names
18+
// TODO add #define to enable/disable CPython compatibility
1819

1920
typedef enum {
2021
PN_none = 0,
@@ -24,8 +25,8 @@ typedef enum {
2425
PN_maximum_number_of,
2526
} pn_kind_t;
2627

27-
#define EMIT(fun, arg...) (emit_##fun(comp->emit, ##arg))
28-
#define EMIT_COMMON(fun, arg...) (emit_common_##fun(comp->pass, comp->scope_cur, ##arg))
28+
#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
29+
#define EMIT_COMMON(fun, arg...) (emit_common_##fun(comp->pass, comp->scope_cur, comp->emit, comp->emit_method_table, ##arg))
2930

3031
typedef struct _compiler_t {
3132
qstr qstr___class__;
@@ -53,7 +54,8 @@ typedef struct _compiler_t {
5354
scope_t *scope_head;
5455
scope_t *scope_cur;
5556

56-
emitter_t *emit;
57+
emit_t *emit;
58+
const emit_method_table_t *emit_method_table;
5759
} compiler_t;
5860

5961
py_parse_node_t fold_constants(py_parse_node_t pn) {
@@ -495,10 +497,10 @@ void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
495497
switch (assign_kind) {
496498
case ASSIGN_STORE:
497499
case ASSIGN_AUG_STORE:
498-
EMIT_COMMON(store_id, comp->emit, arg);
500+
EMIT_COMMON(store_id, arg);
499501
break;
500502
case ASSIGN_AUG_LOAD:
501-
EMIT_COMMON(load_id, comp->qstr___class__, comp->emit, arg);
503+
EMIT_COMMON(load_id, comp->qstr___class__, arg);
502504
break;
503505
}
504506
} else {
@@ -770,18 +772,18 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
770772
}
771773

772774
// store func/class object into name
773-
EMIT_COMMON(store_id, comp->emit, body_name);
775+
EMIT_COMMON(store_id, body_name);
774776
}
775777

776778
void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
777779
qstr fname = compile_funcdef_helper(comp, pns);
778780
// store function object into function name
779-
EMIT_COMMON(store_id, comp->emit, fname);
781+
EMIT_COMMON(store_id, fname);
780782
}
781783

782784
void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
783785
if (PY_PARSE_NODE_IS_ID(pn)) {
784-
EMIT_COMMON(delete_id, comp->emit, PY_PARSE_NODE_LEAF_ARG(pn));
786+
EMIT_COMMON(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
785787
} else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
786788
py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
787789

@@ -986,7 +988,7 @@ void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
986988
EMIT(load_const_tok, PY_TOKEN_KW_NONE);
987989
qstr q1, q2;
988990
do_import_name(comp, pn, &q1, &q2);
989-
EMIT_COMMON(store_id, comp->emit, q1);
991+
EMIT_COMMON(store_id, q1);
990992
}
991993

992994
void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
@@ -1033,43 +1035,47 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
10331035
qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
10341036
EMIT(import_from, id2);
10351037
if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
1036-
EMIT_COMMON(store_id, comp->emit, id2);
1038+
EMIT_COMMON(store_id, id2);
10371039
} else {
1038-
EMIT_COMMON(store_id, comp->emit, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
1040+
EMIT_COMMON(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
10391041
}
10401042
}
10411043
EMIT(pop_top);
10421044
}
10431045
}
10441046

10451047
void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1046-
if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1047-
EMIT_COMMON(declare_global, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1048-
} else {
1049-
pns = (py_parse_node_struct_t*)pns->nodes[0];
1050-
int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1051-
for (int i = 0; i < num_nodes; i++) {
1052-
EMIT_COMMON(declare_global, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1048+
if (comp->pass == PASS_1) {
1049+
if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1050+
scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1051+
} else {
1052+
pns = (py_parse_node_struct_t*)pns->nodes[0];
1053+
int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1054+
for (int i = 0; i < num_nodes; i++) {
1055+
scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1056+
}
10531057
}
10541058
}
10551059
}
10561060

10571061
void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1058-
if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1059-
EMIT_COMMON(declare_nonlocal, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1060-
} else {
1061-
pns = (py_parse_node_struct_t*)pns->nodes[0];
1062-
int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1063-
for (int i = 0; i < num_nodes; i++) {
1064-
EMIT_COMMON(declare_nonlocal, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1062+
if (comp->pass == PASS_1) {
1063+
if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1064+
scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1065+
} else {
1066+
pns = (py_parse_node_struct_t*)pns->nodes[0];
1067+
int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1068+
for (int i = 0; i < num_nodes; i++) {
1069+
scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1070+
}
10651071
}
10661072
}
10671073
}
10681074

10691075
void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
10701076
int l_end = EMIT(label_new);
10711077
c_if_cond(comp, pns->nodes[0], true, l_end);
1072-
EMIT_COMMON(load_id, comp->qstr___class__, comp->emit, comp->qstr_assertion_error);
1078+
EMIT_COMMON(load_id, comp->qstr___class__, comp->qstr_assertion_error);
10731079
if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
10741080
// assertion message
10751081
compile_node(comp, pns->nodes[1]);
@@ -1090,7 +1096,7 @@ void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
10901096
compile_node(comp, pns->nodes[1]); // if block
10911097
//if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
10921098
// jump over elif/else blocks if they exist
1093-
if (!emit_last_emit_was_return_value(comp->emit)) { // simple optimisation to align with CPython
1099+
if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
10941100
EMIT(jump, l_end);
10951101
}
10961102
//}
@@ -1111,7 +1117,7 @@ void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
11111117
c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
11121118

11131119
compile_node(comp, pns_elif2->nodes[1]); // elif block
1114-
if (!emit_last_emit_was_return_value(comp->emit)) { // simple optimisation to align with CPython
1120+
if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
11151121
EMIT(jump, l_end);
11161122
}
11171123
EMIT(label_assign, l_fail);
@@ -1124,7 +1130,7 @@ void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
11241130
c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
11251131

11261132
compile_node(comp, pns_elif->nodes[1]); // elif block
1127-
if (!emit_last_emit_was_return_value(comp->emit)) { // simple optimisation to align with CPython
1133+
if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
11281134
EMIT(jump, l_end);
11291135
}
11301136
EMIT(label_assign, l_fail);
@@ -1153,7 +1159,7 @@ void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
11531159
EMIT(label_assign, continue_label);
11541160
c_if_cond(comp, pns->nodes[0], false, done_label); // condition
11551161
compile_node(comp, pns->nodes[1]); // body
1156-
if (!emit_last_emit_was_return_value(comp->emit)) {
1162+
if (!EMIT(last_emit_was_return_value)) {
11571163
EMIT(jump, continue_label);
11581164
}
11591165
EMIT(label_assign, done_label);
@@ -1194,7 +1200,7 @@ void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
11941200
EMIT(for_iter, pop_label);
11951201
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
11961202
compile_node(comp, pns->nodes[2]); // body
1197-
if (!emit_last_emit_was_return_value(comp->emit)) {
1203+
if (!EMIT(last_emit_was_return_value)) {
11981204
EMIT(jump, for_label);
11991205
}
12001206
EMIT(label_assign, pop_label);
@@ -1263,7 +1269,7 @@ void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except,
12631269
if (qstr_exception_local == 0) {
12641270
EMIT(pop_top);
12651271
} else {
1266-
EMIT_COMMON(store_id, comp->emit, qstr_exception_local);
1272+
EMIT_COMMON(store_id, qstr_exception_local);
12671273
}
12681274

12691275
EMIT(pop_top);
@@ -1282,8 +1288,8 @@ void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except,
12821288
EMIT(load_const_tok, PY_TOKEN_KW_NONE);
12831289
EMIT(label_assign, l3);
12841290
EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1285-
EMIT_COMMON(store_id, comp->emit, qstr_exception_local);
1286-
EMIT_COMMON(delete_id, comp->emit, qstr_exception_local);
1291+
EMIT_COMMON(store_id, qstr_exception_local);
1292+
EMIT_COMMON(delete_id, qstr_exception_local);
12871293
EMIT(end_finally);
12881294
}
12891295
EMIT(jump, l2);
@@ -2038,7 +2044,7 @@ void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns)
20382044
void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
20392045
qstr cname = compile_classdef_helper(comp, pns);
20402046
// store class object into class name
2041-
EMIT_COMMON(store_id, comp->emit, cname);
2047+
EMIT_COMMON(store_id, cname);
20422048
}
20432049

20442050
void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
@@ -2116,7 +2122,7 @@ void compile_node(compiler_t *comp, py_parse_node_t pn) {
21162122
} else if (PY_PARSE_NODE_IS_LEAF(pn)) {
21172123
int arg = PY_PARSE_NODE_LEAF_ARG(pn);
21182124
switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
2119-
case PY_PARSE_NODE_ID: EMIT_COMMON(load_id, comp->qstr___class__, comp->emit, arg); break;
2125+
case PY_PARSE_NODE_ID: EMIT_COMMON(load_id, comp->qstr___class__, arg); break;
21202126
case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
21212127
case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
21222128
case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
@@ -2287,7 +2293,7 @@ void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
22872293
if (kind == PY_PARSE_NODE_STRING) {
22882294
compile_node(comp, pns->nodes[0]); // a doc string
22892295
// store doc string
2290-
EMIT_COMMON(store_id, comp->emit, comp->qstr___doc__);
2296+
EMIT_COMMON(store_id, comp->qstr___doc__);
22912297
}
22922298
}
22932299
}
@@ -2296,7 +2302,7 @@ void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
22962302
void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
22972303
comp->pass = pass;
22982304
comp->scope_cur = scope;
2299-
emit_start_pass(comp->emit, pass, scope);
2305+
EMIT(start_pass, pass, scope);
23002306

23012307
if (comp->pass == PASS_1) {
23022308
scope->stack_size = 0;
@@ -2328,7 +2334,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
23282334

23292335
compile_node(comp, pns->nodes[3]); // 3 is function body
23302336
// emit return if it wasn't the last opcode
2331-
if (!emit_last_emit_was_return_value(comp->emit)) {
2337+
if (!EMIT(last_emit_was_return_value)) {
23322338
EMIT(load_const_tok, PY_TOKEN_KW_NONE);
23332339
EMIT(return_value);
23342340
}
@@ -2373,7 +2379,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
23732379

23742380
int l_end = EMIT(label_new);
23752381
int l_top = EMIT(label_new);
2376-
EMIT_COMMON(load_id, comp->qstr___class__, comp->emit, qstr_arg);
2382+
EMIT_COMMON(load_id, comp->qstr___class__, qstr_arg);
23772383
EMIT(label_assign, l_top);
23782384
EMIT(for_iter, l_end);
23792385
c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
@@ -2404,12 +2410,12 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
24042410
scope->num_params = 1; // __locals__ is the parameter
24052411
}
24062412

2407-
EMIT_COMMON(load_id, comp->qstr___class__, comp->emit, comp->qstr___locals__);
2413+
EMIT_COMMON(load_id, comp->qstr___class__, comp->qstr___locals__);
24082414
EMIT(store_locals);
2409-
EMIT_COMMON(load_id, comp->qstr___class__, comp->emit, comp->qstr___name__);
2410-
EMIT_COMMON(store_id, comp->emit, comp->qstr___module__);
2415+
EMIT_COMMON(load_id, comp->qstr___class__, comp->qstr___name__);
2416+
EMIT_COMMON(store_id, comp->qstr___module__);
24112417
EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
2412-
EMIT_COMMON(store_id, comp->emit, comp->qstr___qualname__);
2418+
EMIT_COMMON(store_id, comp->qstr___qualname__);
24132419

24142420
check_for_doc_string(comp, pns->nodes[2]);
24152421
compile_node(comp, pns->nodes[2]); // 2 is class body
@@ -2424,7 +2430,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
24242430
EMIT(return_value);
24252431
}
24262432

2427-
emit_end_pass(comp->emit);
2433+
EMIT(end_pass);
24282434
}
24292435

24302436
void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
@@ -2489,7 +2495,9 @@ void py_compile(py_parse_node_t pn) {
24892495
comp->scope_head = NULL;
24902496
comp->scope_cur = NULL;
24912497

2492-
comp->emit = emit_new(comp->qstr___class__);
2498+
emit_new_cpython(&comp->emit, &comp->emit_method_table);
2499+
//emit_new_bc(&comp->emit, &comp->emit_method_table);
2500+
//emit_new_x64(&comp->emit, &comp->emit_method_table);
24932501

24942502
pn = fold_constants(pn);
24952503
scope_new_and_link(comp, SCOPE_MODULE, pn);

0 commit comments

Comments
 (0)