diff options
Diffstat (limited to 'src/runtime/c')
| -rw-r--r-- | src/runtime/c/Makefile.am | 1 | ||||
| -rw-r--r-- | src/runtime/c/pgf/data.h | 20 | ||||
| -rw-r--r-- | src/runtime/c/pgf/evaluator.c | 44 | ||||
| -rw-r--r-- | src/runtime/c/pgf/jit.c | 386 | ||||
| -rw-r--r-- | src/runtime/c/pgf/jit.h | 16 | ||||
| -rw-r--r-- | src/runtime/c/pgf/pgf.h | 32 | ||||
| -rw-r--r-- | src/runtime/c/pgf/reader.c | 72 | ||||
| -rw-r--r-- | src/runtime/c/pgf/reader.h | 51 |
8 files changed, 430 insertions, 192 deletions
diff --git a/src/runtime/c/Makefile.am b/src/runtime/c/Makefile.am index 75bd0a253..c7abd96cb 100644 --- a/src/runtime/c/Makefile.am +++ b/src/runtime/c/Makefile.am @@ -33,7 +33,6 @@ guinclude_HEADERS = \ pgfincludedir=$(includedir)/pgf pgfinclude_HEADERS = \ pgf/expr.h \ - pgf/reader.h \ pgf/linearizer.h \ pgf/parser.h \ pgf/literals.h \ diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index d75b17f85..552856995 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -76,6 +76,7 @@ typedef struct { PgfEquations* defns; // maybe null PgfExprProb ep; void* predicate; + void* function; } PgfAbsFun; extern GU_DECLARE_TYPE(PgfAbsFun, abstract); @@ -102,6 +103,25 @@ typedef struct { PgfAbsFun* abs_lin_fun; } PgfAbstr; +typedef enum { + PGF_INSTR_EVAL, + PGF_INSTR_CASE, + PGF_INSTR_CASE_INT, + PGF_INSTR_CASE_STR, + PGF_INSTR_CASE_FLT, + PGF_INSTR_ALLOC, + PGF_INSTR_PUT_CONSTR, + PGF_INSTR_PUT_CLOSURE, + PGF_INSTR_PUT_INT, + PGF_INSTR_PUT_STR, + PGF_INSTR_PUT_FLT, + PGF_INSTR_SET_VALUE, + PGF_INSTR_SET_VARIABLE, + PGF_INSTR_TAIL_CALL, + PGF_INSTR_FAIL, + PGF_INSTR_RET +} PgfInstruction; + struct PgfPGF { uint16_t major_version; uint16_t minor_version; diff --git a/src/runtime/c/pgf/evaluator.c b/src/runtime/c/pgf/evaluator.c index 7c4598a86..ee2bd8511 100644 --- a/src/runtime/c/pgf/evaluator.c +++ b/src/runtime/c/pgf/evaluator.c @@ -1,17 +1,18 @@ #include "pgf/pgf.h" #include "pgf/data.h" +#include "pgf/evaluator.h" typedef struct PgfEnv PgfEnv; -typedef struct PgfClosure PgfClosure; -typedef struct PgfEvalState PgfEvalState; struct PgfEnv { PgfEnv* next; PgfClosure* closure; }; +typedef PgfClosure* (*PgfFunction)(PgfEvalState* state, PgfClosure* val); + struct PgfClosure { - PgfClosure* (*code)(PgfEvalState* state, PgfClosure* val); + PgfFunction code; }; typedef struct { @@ -28,7 +29,6 @@ typedef struct { typedef struct { PgfClosure header; PgfAbsFun* absfun; - size_t n_args; PgfClosure* args[]; } PgfValue; @@ -52,13 +52,6 @@ typedef struct { PgfLiteral lit; } PgfValueLit; -struct PgfEvalState { - PgfPGF* pgf; - GuPool* pool; - GuExn* err; - GuBuf* stack; -}; - static PgfClosure* pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure) { @@ -66,20 +59,20 @@ pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure) return indir->val; } -static PgfClosure* +PgfClosure* pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure) { PgfValue* val = (PgfValue*) closure; - size_t n_args = val->n_args + gu_buf_length(state->stack); + size_t n_args = gu_seq_length(val->absfun->type->hypos) + + gu_buf_length(state->stack); PgfValue* new_val = gu_new_flex(state->pool, PgfValue, args, n_args); new_val->header.code = pgf_evaluate_value; new_val->absfun = val->absfun; - new_val->n_args = n_args; size_t i = 0; - while (i < val->n_args) { + while (i < gu_seq_length(val->absfun->type->hypos)) { new_val->args[i] = val->args[i]; i++; } @@ -236,15 +229,18 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure) return NULL; } - size_t n_args = gu_buf_length(state->stack); + PgfValue* val; + if (absfun->function != NULL) { + val = (PgfValue*) ((PgfFunction) absfun->function)(state, closure); + } else { + size_t n_args = gu_buf_length(state->stack); - PgfValue* val = - gu_new_flex(state->pool, PgfValue, args, n_args); - val->header.code = pgf_evaluate_value; - val->absfun = absfun; - val->n_args = n_args; - for (size_t i = 0; i < n_args; i++) { - val->args[i] = gu_buf_pop(state->stack, PgfClosure*); + val = gu_new_flex(state->pool, PgfValue, args, n_args); + val->header.code = pgf_evaluate_value; + val->absfun = absfun; + for (size_t i = 0; i < n_args; i++) { + val->args[i] = gu_buf_pop(state->stack, PgfClosure*); + } } PgfIndirection* indir = (PgfIndirection*) closure; @@ -309,7 +305,7 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) PgfValue* val = (PgfValue*) clos; expr = val->absfun->ep.expr; - n_args = val->n_args; + n_args = gu_seq_length(val->absfun->type->hypos); args = val->args; } else if (clos->code == pgf_evaluate_value_gen) { PgfValueGen* val = (PgfValueGen*) clos; diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index 250b5a3a6..ba7788a1a 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -1,23 +1,22 @@ #include <gu/seq.h> #include <gu/file.h> #include <pgf/data.h> -#include <pgf/jit.h> #include <pgf/reasoner.h> +#include <pgf/evaluator.h> +#include <pgf/reader.h> #include "lightning.h" //#define PGF_JIT_DEBUG struct PgfJitState { - GuPool* tmp_pool; - GuPool* pool; jit_state jit; jit_insn *buf; char *save_ip_ptr; GuBuf* patches; }; -#define _jit (state->jit) +#define _jit (rdr->jit_state->jit) typedef struct { PgfCId cid; @@ -27,7 +26,7 @@ typedef struct { // Between two calls to pgf_jit_make_space we are not allowed // to emit more that JIT_CODE_WINDOW bytes. This is not quite // safe but this is how GNU lightning is designed. -#define JIT_CODE_WINDOW 128 +#define JIT_CODE_WINDOW 1280 typedef struct { GuFinalizer fin; @@ -42,7 +41,7 @@ pgf_jit_finalize_page(GuFinalizer* self) } static void -pgf_jit_alloc_page(PgfJitState* state) +pgf_jit_alloc_page(PgfReader* rdr) { void *page; @@ -58,46 +57,63 @@ pgf_jit_alloc_page(PgfJitState* state) gu_fatal("Memory allocation failed"); } - PgfPageFinalizer* fin = gu_new(PgfPageFinalizer, state->pool); + PgfPageFinalizer* fin = + gu_new(PgfPageFinalizer, rdr->opool); fin->fin.fn = pgf_jit_finalize_page; fin->page = page; - gu_pool_finally(state->pool, &fin->fin); + gu_pool_finally(rdr->opool, &fin->fin); - state->buf = page; - jit_set_ip(state->buf); + rdr->jit_state->buf = page; + jit_set_ip(rdr->jit_state->buf); } PgfJitState* -pgf_jit_init(GuPool* tmp_pool, GuPool* pool) +pgf_new_jit(PgfReader* rdr) { - PgfJitState* state = gu_new(PgfJitState, tmp_pool); - state->tmp_pool = tmp_pool; - state->pool = pool; - state->patches = gu_new_buf(PgfCallPatch, tmp_pool); - - pgf_jit_alloc_page(state); - state->save_ip_ptr = jit_get_ip().ptr; - + PgfJitState* state = gu_new(PgfJitState, rdr->tmp_pool); + state->patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool); + state->buf = NULL; + state->save_ip_ptr = NULL; return state; } static void -pgf_jit_make_space(PgfJitState* state) +pgf_jit_make_space(PgfReader* rdr) { - assert (state->save_ip_ptr + JIT_CODE_WINDOW > jit_get_ip().ptr); - size_t page_size = getpagesize(); - if (jit_get_ip().ptr + JIT_CODE_WINDOW > ((char*) state->buf) + page_size) { - jit_flush_code(state->buf, jit_get_ip().ptr); - pgf_jit_alloc_page(state); + if (rdr->jit_state->buf == NULL) { + pgf_jit_alloc_page(rdr); + } else { + assert (rdr->jit_state->save_ip_ptr + JIT_CODE_WINDOW > jit_get_ip().ptr); + + if (jit_get_ip().ptr + JIT_CODE_WINDOW > ((char*) rdr->jit_state->buf) + page_size) { + jit_flush_code(rdr->jit_state->buf, jit_get_ip().ptr); + pgf_jit_alloc_page(rdr); + } } + + rdr->jit_state->save_ip_ptr = jit_get_ip().ptr; +} + +static PgfAbsFun* +pgf_jit_read_absfun(PgfReader* rdr, PgfAbstr* abstr) +{ + gu_in_f64be(rdr->in, rdr->err); // ignore + gu_return_on_exn(rdr->err, NULL); + + PgfCId name = pgf_read_cid(rdr, rdr->tmp_pool); + gu_return_on_exn(rdr->err, NULL); + + PgfAbsFun* absfun = + gu_map_get(abstr->funs, name, PgfAbsFun*); + assert(absfun != NULL); - state->save_ip_ptr = jit_get_ip().ptr; + return absfun; } void -pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, - PgfAbsCat* abscat, GuBuf* functions) +pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, + PgfAbsCat* abscat) { #ifdef PGF_JIT_DEBUG GuPool* tmp_pool = gu_new_pool(); @@ -110,21 +126,24 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, int label = 0; #endif - size_t n_funs = gu_buf_length(functions); - - pgf_jit_make_space(state); + size_t n_funs = pgf_read_len(rdr); + gu_return_on_exn(rdr->err, ); + + pgf_jit_make_space(rdr); abscat->predicate = (PgfPredicate) jit_get_ip().ptr; jit_prolog(2); + PgfAbsFun* absfun = NULL; + PgfAbsFun* next_absfun = NULL; + if (n_funs > 0) { - PgfAbsFun* absfun = - gu_buf_get(functions, PgfAbsFun*, 0); + next_absfun = pgf_jit_read_absfun(rdr, abstr); #ifdef PGF_JIT_DEBUG gu_puts(" TRY_FIRST ", out, err); - gu_string_write(absfun->name, out, err); + gu_string_write(next_absfun->name, out, err); gu_puts("\n", out, err); #endif @@ -135,7 +154,7 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, // compile TRY_FIRST jit_prepare(3); - jit_movi_p(JIT_V0,absfun); + jit_movi_p(JIT_V0,next_absfun); jit_pusharg_p(JIT_V0); jit_pusharg_p(JIT_V2); jit_pusharg_p(JIT_V1); @@ -150,20 +169,15 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, #ifdef PGF_JIT_DEBUG if (n_funs > 0) { - PgfAbsFun* absfun = - gu_buf_get(functions, PgfAbsFun*, 0); - - gu_string_write(absfun->name, out, err); + gu_string_write(next_absfun->name, out, err); gu_puts(":\n", out, err); } #endif for (size_t i = 0; i < n_funs; i++) { - PgfAbsFun* absfun = - gu_buf_get(functions, PgfAbsFun*, i); - - pgf_jit_make_space(state); + pgf_jit_make_space(rdr); + absfun = next_absfun; absfun->predicate = (PgfPredicate) jit_get_ip().ptr; jit_prolog(2); @@ -176,18 +190,17 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, if (n_hypos > 0) { if (i+1 < n_funs) { - PgfAbsFun* absfun = - gu_buf_get(functions, PgfAbsFun*, i+1); + next_absfun = pgf_jit_read_absfun(rdr, abstr); // i+1 #ifdef PGF_JIT_DEBUG gu_puts(" TRY_ELSE ", out, err); - gu_string_write(absfun->name, out, err); + gu_string_write(next_absfun->name, out, err); gu_puts("\n", out, err); #endif // compile TRY_ELSE jit_prepare(3); - jit_movi_p(JIT_V0, absfun); + jit_movi_p(JIT_V0, next_absfun); jit_pusharg_p(JIT_V0); jit_pusharg_p(JIT_V2); jit_pusharg_p(JIT_V1); @@ -200,9 +213,6 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, jit_insn *ref; // call the predicate for the category in hypo->type->cid - PgfAbsCat* arg = - gu_map_get(abscats, hypo->type->cid, PgfAbsCat*); - #ifdef PGF_JIT_DEBUG gu_puts(" CALL ", out, err); gu_string_write(hypo->type->cid, out, err); @@ -219,14 +229,11 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, jit_prepare(2); jit_pusharg_p(JIT_V2); jit_pusharg_p(JIT_V1); - if (arg != NULL) { - jit_finish(arg->predicate); - } else { - PgfCallPatch patch; - patch.cid = hypo->type->cid; - patch.ref = jit_finish(jit_forward()); - gu_buf_push(state->patches, PgfCallPatch, patch); - } + + PgfCallPatch patch; + patch.cid = hypo->type->cid; + patch.ref = jit_finish(jit_forward()); + gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch); #ifdef PGF_JIT_DEBUG gu_puts(" RET\n", out, err); @@ -239,7 +246,7 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, jit_ret(); if (i+1 < n_hypos) { - pgf_jit_make_space(state); + pgf_jit_make_space(rdr); jit_patch_movi(ref,jit_get_label()); @@ -254,18 +261,17 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, } } else { if (i+1 < n_funs) { - PgfAbsFun* absfun = - gu_buf_get(functions, PgfAbsFun*, i+1); + next_absfun = pgf_jit_read_absfun(rdr, abstr); // i+1 #ifdef PGF_JIT_DEBUG gu_puts(" TRY_CONSTANT ", out, err); - gu_string_write(absfun->name, out, err); + gu_string_write(next_absfun->name, out, err); gu_puts("\n", out, err); #endif // compile TRY_CONSTANT jit_prepare(3); - jit_movi_p(JIT_V0, absfun); + jit_movi_p(JIT_V0, next_absfun); jit_pusharg_p(JIT_V0); jit_pusharg_p(JIT_V2); jit_pusharg_p(JIT_V1); @@ -289,13 +295,10 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, // compile RET jit_ret(); } - + #ifdef PGF_JIT_DEBUG if (i+1 < n_funs) { - PgfAbsFun* absfun = - gu_buf_get(functions, PgfAbsFun*, i+1); - - gu_string_write(absfun->name, out, err); + gu_string_write(next_absfun->name, out, err); gu_puts(":\n", out, err); } #endif @@ -307,18 +310,251 @@ pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, } void -pgf_jit_done(PgfJitState* state, PgfAbstr* abstr) +pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, + PgfAbsFun* absfun) { - size_t n_patches = gu_buf_length(state->patches); +#ifdef PGF_JIT_DEBUG + GuPool* tmp_pool = gu_new_pool(); + GuOut* out = gu_file_out(stderr, tmp_pool); + GuExn* err = gu_exn(NULL, type, tmp_pool); + + gu_string_write(absfun->name, out, err); + gu_puts(":\n", out, err); +#endif + + pgf_jit_make_space(rdr); + + absfun->function = jit_get_ip().ptr; + + jit_prolog(2); + + int es_arg = jit_arg_p(); + int closure_arg = jit_arg_p(); + + size_t n_instrs = pgf_read_len(rdr); + gu_return_on_exn(rdr->err, ); + + size_t curr_offset = 0; + size_t curr_label = 0; + + for (size_t i = 0; i < n_instrs; i++) { +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "%04d ", curr_label++); +#endif + + uint8_t opcode = pgf_read_tag(rdr); + switch (opcode) { + case PGF_INSTR_EVAL: { + size_t index = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "EVAL %d\n", index); +#endif + + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_length); + jit_subi_i(JIT_V2, JIT_RET, index+1); + jit_lshi_i(JIT_V2, JIT_V2, 2); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_data); + jit_ldxr_p(JIT_V0, JIT_RET, JIT_V2); + jit_prepare(2); + jit_pusharg_p(JIT_V0); + jit_getarg_p(JIT_V2, es_arg); + jit_pusharg_p(JIT_V2); + jit_ldr_p(JIT_V0, JIT_V0); + jit_callr(JIT_V0); + break; + } + case PGF_INSTR_CASE: { + PgfCId id = pgf_read_cid(rdr, rdr->opool); + int offset = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "CASE %s %04d\n", id, curr_label+offset); +#endif + break; + } + case PGF_INSTR_CASE_INT: { + int n = pgf_read_int(rdr); + int offset = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "CASE_INT %d %04d\n", n, curr_label+offset); +#endif + break; + } + case PGF_INSTR_CASE_STR: { + GuString s = pgf_read_string(rdr); + int offset = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "CASE_STR %s %04d\n", s, curr_label+offset); +#endif + break; + } + case PGF_INSTR_CASE_FLT: { + double d = pgf_read_double(rdr); + int offset = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "CASE_FLT %f %04d\n", d, curr_label+offset); +#endif + break; + } + case PGF_INSTR_ALLOC: { + size_t size = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "ALLOC %d\n", size); +#endif + jit_prepare(2); + jit_movi_ui(JIT_V0, size*sizeof(void*)); + jit_pusharg_ui(JIT_V0); + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_V0); + jit_finish(gu_malloc); + jit_retval_p(JIT_V1); + + curr_offset = 0; + break; + } + case PGF_INSTR_PUT_CONSTR: { + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUT_CONSTR %s\n", id); +#endif + + jit_movi_p(JIT_V0, pgf_evaluate_value); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + + PgfCallPatch patch; + patch.cid = id; + patch.ref = jit_movi_p(JIT_V0, jit_forward()); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + + gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch); + break; + } + case PGF_INSTR_PUT_CLOSURE: { + size_t addr = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUT_CLOSURE %d\n", addr); +#endif + break; + } + case PGF_INSTR_PUT_INT: { + size_t n = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUT_INT %d\n", n); +#endif + break; + } + case PGF_INSTR_PUT_STR: { + size_t addr = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUT_STR %d\n", addr); +#endif + break; + } + case PGF_INSTR_PUT_FLT: { + size_t addr = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUT_FLT %d\n", addr); +#endif + + break; + } + case PGF_INSTR_SET_VALUE: { + size_t offset = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "SET_VALUE %d\n", offset); +#endif + jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + break; + } + case PGF_INSTR_SET_VARIABLE: { + size_t index = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "SET_VARIABLE %d\n", index); +#endif + + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_length); + jit_subi_i(JIT_V2, JIT_RET, index+1); + jit_lshi_i(JIT_V2, JIT_V2, 2); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_data); + jit_ldxr_p(JIT_V0, JIT_RET, JIT_V2); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + break; + } + case PGF_INSTR_TAIL_CALL: { + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "TAIL_CALL %s\n", id); +#endif + break; + } + case PGF_INSTR_FAIL: +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "FAIL\n"); +#endif + break; + case PGF_INSTR_RET: { + size_t count = pgf_read_int(rdr); + +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "RET %d\n", count); +#endif + + jit_prepare(2); + jit_movi_ui(JIT_V0, count); + jit_pusharg_p(JIT_V0); + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_trim_n); + + jit_movr_p(JIT_RET, JIT_V1); + jit_ret(); + break; + } + default: + gu_impossible(); + } + } +} + +void +pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr) +{ + size_t n_patches = gu_buf_length(rdr->jit_state->patches); for (size_t i = 0; i < n_patches; i++) { PgfCallPatch* patch = - gu_buf_index(state->patches, PgfCallPatch, i); + gu_buf_index(rdr->jit_state->patches, PgfCallPatch, i); + PgfAbsCat* arg = gu_map_get(abstr->cats, patch->cid, PgfAbsCat*); - gu_assert(arg != NULL); - - jit_patch_calli(patch->ref,(jit_insn*) arg->predicate); + if (arg != NULL) + jit_patch_calli(patch->ref,(jit_insn*) arg->predicate); + else { + PgfAbsFun* con = + gu_map_get(abstr->funs, patch->cid, PgfAbsFun*); + if (con != NULL) + jit_patch_movi(patch->ref,con); + else { + gu_impossible(); + } + } } - jit_flush_code(state->buf, jit_get_ip().ptr); + jit_flush_code(rdr->jit_state->buf, jit_get_ip().ptr); } diff --git a/src/runtime/c/pgf/jit.h b/src/runtime/c/pgf/jit.h deleted file mode 100644 index 04265547a..000000000 --- a/src/runtime/c/pgf/jit.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PGF_JIT_H_ -#define PGF_JIT_H_ - -typedef struct PgfJitState PgfJitState; - -PgfJitState* -pgf_jit_init(GuPool* tmp_pool, GuPool* pool); - -void -pgf_jit_done(PgfJitState* state, PgfAbstr* abstr); - -void -pgf_jit_predicate(PgfJitState* state, PgfCIdMap* abscats, - PgfAbsCat* abscat, GuBuf* functions); - -#endif diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index bc9fb7d99..16444985f 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -17,44 +17,24 @@ extern GU_DECLARE_TYPE(PgfExn, abstract); extern GU_DECLARE_TYPE(PgfParseError, abstract); extern GU_DECLARE_TYPE(PgfTypeError, abstract); -/// @name PGF Grammar objects -/// @{ - typedef struct PgfPGF PgfPGF; typedef struct PgfConcr PgfConcr; - -/**< A representation of a PGF grammar. - */ - #include <pgf/expr.h> #include <pgf/graphviz.h> -/// An enumeration of #PgfExpr elements. typedef GuEnum PgfExprEnum; PgfPGF* pgf_read(const char* fpath, GuPool* pool, GuExn* err); -/**< Read a grammar from a PGF file. - * - * @param from PGF input stream. - * The stream must be positioned in the beginning of a binary - * PGF representation. After a succesful invocation, the stream is - * still open and positioned at the end of the representation. - * - * @param[out] err_out Raised error. - * If non-\c NULL, \c *err_out should be \c NULL. Then, upon - * failure, \c *err_out is set to point to a newly allocated - * error object, which the caller must free with #g_exn_free - * or #g_exn_propagate. - * - * @return A new PGF object, or \c NULL upon failure. The returned - * object must later be freed with #pgf_free. - * - */ +void +pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err); + +void +pgf_concrete_unload(PgfConcr* concr); GuString pgf_abstract_name(PgfPGF*); @@ -176,8 +156,6 @@ pgf_concr_add_literal(PgfConcr *concr, PgfCId cat, PgfLiteralCallback* callback, GuExn* err); -/// @} - void pgf_print(PgfPGF* pgf, GuOut* out, GuExn* err); diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c index afbd42242..20dfd6e6c 100644 --- a/src/runtime/c/pgf/reader.c +++ b/src/runtime/c/pgf/reader.c @@ -2,7 +2,6 @@ #include "expr.h" #include "literals.h" #include "reader.h" -#include "jit.h" #include <gu/defs.h> #include <gu/map.h> @@ -22,14 +21,6 @@ // PgfReader // -struct PgfReader { - GuIn* in; - GuExn* err; - GuPool* opool; - GuPool* tmp_pool; - PgfJitState* jit_state; -}; - typedef struct PgfReadTagExn PgfReadTagExn; struct PgfReadTagExn { @@ -41,13 +32,13 @@ static GU_DEFINE_TYPE(PgfReadTagExn, abstract, _); static GU_DEFINE_TYPE(PgfReadExn, abstract, _); -static uint8_t +uint8_t pgf_read_tag(PgfReader* rdr) { return gu_in_u8(rdr->in, rdr->err); } -static uint32_t +uint32_t pgf_read_uint(PgfReader* rdr) { uint32_t u = 0; @@ -62,14 +53,14 @@ pgf_read_uint(PgfReader* rdr) return u; } -static int32_t +int32_t pgf_read_int(PgfReader* rdr) { uint32_t u = pgf_read_uint(rdr); return gu_decode_2c32(u, rdr->err); } -static GuLength +size_t pgf_read_len(PgfReader* rdr) { int32_t len = pgf_read_int(rdr); @@ -88,23 +79,29 @@ pgf_read_len(PgfReader* rdr) return 0; } - return (GuLength) len; + return len; } -static PgfCId +PgfCId pgf_read_cid(PgfReader* rdr, GuPool* pool) { size_t len = pgf_read_len(rdr); return gu_string_read_latin1(len, pool, rdr->in, rdr->err); } -static GuString +GuString pgf_read_string(PgfReader* rdr) { GuLength len = pgf_read_len(rdr); return gu_string_read(len, rdr->opool, rdr->in, rdr->err); } +double +pgf_read_double(PgfReader* rdr) +{ + return gu_in_f64be(rdr->in, rdr->err); +} + static void pgf_read_tag_error(PgfReader* rdr) { @@ -149,7 +146,7 @@ pgf_read_literal(PgfReader* rdr) gu_new_variant(PGF_LITERAL_FLT, PgfLiteralFlt, &lit, rdr->opool); - lit_flt->val = gu_in_f64be(rdr->in, rdr->err); + lit_flt->val = pgf_read_double(rdr); break; } default: @@ -417,7 +414,7 @@ pgf_read_patt(PgfReader* rdr) } static PgfAbsFun* -pgf_read_absfun(PgfReader* rdr) +pgf_read_absfun(PgfReader* rdr, PgfAbstr* abstr) { PgfAbsFun* absfun = gu_new(PgfAbsFun, rdr->opool); @@ -444,6 +441,7 @@ pgf_read_absfun(PgfReader* rdr) switch (tag) { case 0: absfun->defns = NULL; + absfun->function = NULL; break; case 1: { GuLength length = pgf_read_len(rdr); @@ -468,6 +466,8 @@ pgf_read_absfun(PgfReader* rdr) data[i] = equ; } + + // pgf_jit_function(rdr, abstr, absfun); break; } default: @@ -475,13 +475,13 @@ pgf_read_absfun(PgfReader* rdr) break; } - absfun->ep.prob = - log(gu_in_f64be(rdr->in, rdr->err)); + absfun->ep.prob = - log(pgf_read_double(rdr)); return absfun; } static PgfCIdMap* -pgf_read_absfuns(PgfReader* rdr) +pgf_read_absfuns(PgfReader* rdr, PgfAbstr* abstr) { GuMapType* map_type = (GuMapType*) GU_TYPE_LIT(GuStringMap, _, @@ -493,7 +493,7 @@ pgf_read_absfuns(PgfReader* rdr) gu_return_on_exn(rdr->err, NULL); for (size_t i = 0; i < len; i++) { - PgfAbsFun* absfun = pgf_read_absfun(rdr); + PgfAbsFun* absfun = pgf_read_absfun(rdr, abstr); gu_return_on_exn(rdr->err, NULL); gu_map_put(absfuns, absfun->name, PgfAbsFun*, absfun); @@ -519,27 +519,9 @@ pgf_read_abscat(PgfReader* rdr, PgfAbstr* abstr, PgfCIdMap* abscats) gu_return_on_exn(rdr->err, NULL); } - GuBuf* functions = gu_new_buf(PgfAbsFun*, rdr->tmp_pool); - - size_t n_functions = pgf_read_len(rdr); - gu_return_on_exn(rdr->err, NULL); - - for (size_t i = 0; i < n_functions; i++) { - gu_in_f64be(rdr->in, rdr->err); // ignore - gu_return_on_exn(rdr->err, NULL); - - PgfCId name = pgf_read_cid(rdr, rdr->tmp_pool); - gu_return_on_exn(rdr->err, NULL); - - PgfAbsFun* absfun = - gu_map_get(abstr->funs, name, PgfAbsFun*); - assert(absfun != NULL); - gu_buf_push(functions, PgfAbsFun*, absfun); - } - - abscat->prob = - log(gu_in_f64be(rdr->in, rdr->err)); + pgf_jit_predicate(rdr, abstr, abscat); - pgf_jit_predicate(rdr->jit_state, abscats, abscat, functions); + abscat->prob = - log(pgf_read_double(rdr)); return abscat; } @@ -552,7 +534,7 @@ pgf_read_abscats(PgfReader* rdr, PgfAbstr* abstr) gu_ptr_type(PgfAbsCat), &gu_null_struct); PgfCIdMap* abscats = gu_map_type_make(map_type, rdr->opool); - + size_t len = pgf_read_len(rdr); gu_return_on_exn(rdr->err, NULL); @@ -575,7 +557,7 @@ pgf_read_abstract(PgfReader* rdr, PgfAbstr* abstract) abstract->aflags = pgf_read_flags(rdr); gu_return_on_exn(rdr->err, ); - abstract->funs = pgf_read_absfuns(rdr); + abstract->funs = pgf_read_absfuns(rdr, abstract); gu_return_on_exn(rdr->err, ); abstract->cats = pgf_read_abscats(rdr, abstract); @@ -1350,7 +1332,7 @@ pgf_new_reader(GuIn* in, GuPool* opool, GuPool* tmp_pool, GuExn* err) rdr->tmp_pool = tmp_pool; rdr->err = err; rdr->in = in; - rdr->jit_state = pgf_jit_init(tmp_pool, rdr->opool); + rdr->jit_state = pgf_new_jit(rdr); return rdr; } @@ -1360,5 +1342,5 @@ pgf_reader_done(PgfReader* rdr, PgfPGF* pgf) if (pgf == NULL) return; - pgf_jit_done(rdr->jit_state, &pgf->abstract); + pgf_jit_done(rdr, &pgf->abstract); } diff --git a/src/runtime/c/pgf/reader.h b/src/runtime/c/pgf/reader.h index 7011eea17..98042c330 100644 --- a/src/runtime/c/pgf/reader.h +++ b/src/runtime/c/pgf/reader.h @@ -5,21 +5,64 @@ #include <gu/mem.h> #include <gu/in.h> -typedef struct PgfReader PgfReader; +// general reader interface + +typedef struct { + GuIn* in; + GuExn* err; + GuPool* opool; + GuPool* tmp_pool; + struct PgfJitState* jit_state; +} PgfReader; PgfReader* pgf_new_reader(GuIn* in, GuPool* opool, GuPool* tmp_pool, GuExn* err); +uint8_t +pgf_read_tag(PgfReader* rdr); + +uint32_t +pgf_read_uint(PgfReader* rdr); + +int32_t +pgf_read_int(PgfReader* rdr); + +GuString +pgf_read_string(PgfReader* rdr); + +double +pgf_read_double(PgfReader* rdr); + +size_t +pgf_read_len(PgfReader* rdr); + +PgfCId +pgf_read_cid(PgfReader* rdr, GuPool* pool); + PgfPGF* pgf_read_pgf(PgfReader* rdr); void -pgf_concrete_load(PgfConcr* concr, GuIn* in, GuExn* err); +pgf_reader_done(PgfReader* rdr, PgfPGF* pgf); + + +// JIT specific interface + +typedef struct PgfJitState PgfJitState; + +PgfJitState* +pgf_new_jit(PgfReader* rdr); void -pgf_concrete_unload(PgfConcr* concr); +pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr, + PgfAbsCat* abscat); void -pgf_reader_done(PgfReader* rdr, PgfPGF* pgf); +pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, + PgfAbsFun* absfun); + +void +pgf_jit_done(PgfReader* state, PgfAbstr* abstr); + #endif // READER_H_ |
