summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2014-08-11 15:53:41 +0000
committerkr.angelov <kr.angelov@gmail.com>2014-08-11 15:53:41 +0000
commitc30e2df228fc42653149752b56e50e77bae03b9f (patch)
tree582a3a4fcac1e65b39968506208a466df3ed486f /src/runtime
parentd3b9652b81e3d43bfb0de9faf4aea578c60e5cc4 (diff)
pattern matching in def rules is now supported
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/c/gu/seq.c6
-rw-r--r--src/runtime/c/gu/seq.h3
-rw-r--r--src/runtime/c/pgf/evaluator.c44
-rw-r--r--src/runtime/c/pgf/jit.c73
-rw-r--r--src/runtime/c/pgf/lightning/i386/core-32.h2
5 files changed, 72 insertions, 56 deletions
diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c
index 2c3d6c3e3..2b99df318 100644
--- a/src/runtime/c/gu/seq.c
+++ b/src/runtime/c/gu/seq.c
@@ -136,6 +136,12 @@ gu_buf_data(GuBuf* buf)
return &buf->seq->data;
}
+void*
+gu_buf_last(GuBuf* buf)
+{
+ return buf->seq->data + buf->elem_size*(buf->seq->len-1);
+}
+
GuSeq*
gu_buf_data_seq(GuBuf* buf)
{
diff --git a/src/runtime/c/gu/seq.h b/src/runtime/c/gu/seq.h
index 5accb0b24..034620140 100644
--- a/src/runtime/c/gu/seq.h
+++ b/src/runtime/c/gu/seq.h
@@ -65,6 +65,9 @@ gu_buf_avail(GuBuf* buf);
void*
gu_buf_data(GuBuf* buf);
+void*
+gu_buf_last(GuBuf* buf);
+
GuSeq*
gu_buf_data_seq(GuBuf* buf);
diff --git a/src/runtime/c/pgf/evaluator.c b/src/runtime/c/pgf/evaluator.c
index ee2bd8511..fca499a98 100644
--- a/src/runtime/c/pgf/evaluator.c
+++ b/src/runtime/c/pgf/evaluator.c
@@ -9,12 +9,6 @@ struct PgfEnv {
PgfClosure* closure;
};
-typedef PgfClosure* (*PgfFunction)(PgfEvalState* state, PgfClosure* val);
-
-struct PgfClosure {
- PgfFunction code;
-};
-
typedef struct {
PgfClosure header;
PgfEnv* env;
@@ -28,12 +22,6 @@ typedef struct {
typedef struct {
PgfClosure header;
- PgfAbsFun* absfun;
- PgfClosure* args[];
-} PgfValue;
-
-typedef struct {
- PgfClosure header;
int level;
size_t n_args;
PgfClosure* args[];
@@ -62,26 +50,7 @@ pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure)
PgfClosure*
pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure)
{
- PgfValue* val = (PgfValue*) closure;
-
- 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;
-
- size_t i = 0;
- while (i < gu_seq_length(val->absfun->type->hypos)) {
- new_val->args[i] = val->args[i];
- i++;
- }
- while (i < n_args) {
- val->args[i] = gu_buf_pop(state->stack, PgfClosure*);
- i++;
- }
-
- return &new_val->header;
+ return closure;
}
static PgfClosure*
@@ -233,7 +202,7 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure)
if (absfun->function != NULL) {
val = (PgfValue*) ((PgfFunction) absfun->function)(state, closure);
} else {
- size_t n_args = gu_buf_length(state->stack);
+ size_t n_args = absfun->arity;
val = gu_new_flex(state->pool, PgfValue, args, n_args);
val->header.code = pgf_evaluate_value;
@@ -290,6 +259,15 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure)
}
}
+void
+pgf_evaluate_save_variables(PgfEvalState* state, PgfValue* val)
+{
+ size_t n_args = val->absfun->arity;
+ for (size_t i = 0; i < n_args; i++) {
+ gu_buf_push(state->stack, PgfClosure*, val->args[i]);
+ }
+}
+
static PgfExpr
pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
{
diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c
index ba7788a1a..20ddd9f68 100644
--- a/src/runtime/c/pgf/jit.c
+++ b/src/runtime/c/pgf/jit.c
@@ -13,7 +13,8 @@ struct PgfJitState {
jit_state jit;
jit_insn *buf;
char *save_ip_ptr;
- GuBuf* patches;
+ GuBuf* call_patches;
+ GuBuf* label_patches;
};
#define _jit (rdr->jit_state->jit)
@@ -23,6 +24,11 @@ typedef struct {
jit_insn *ref;
} PgfCallPatch;
+typedef struct {
+ size_t label;
+ jit_insn *ref;
+} PgfLabelPatch;
+
// 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.
@@ -71,7 +77,8 @@ PgfJitState*
pgf_new_jit(PgfReader* rdr)
{
PgfJitState* state = gu_new(PgfJitState, rdr->tmp_pool);
- state->patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool);
+ state->call_patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool);
+ state->label_patches = gu_new_buf(PgfLabelPatch, rdr->tmp_pool);
state->buf = NULL;
state->save_ip_ptr = NULL;
return state;
@@ -233,7 +240,7 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr,
PgfCallPatch patch;
patch.cid = hypo->type->cid;
patch.ref = jit_finish(jit_forward());
- gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch);
+ gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
#ifdef PGF_JIT_DEBUG
gu_puts(" RET\n", out, err);
@@ -336,8 +343,20 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
size_t curr_offset = 0;
size_t curr_label = 0;
-
+
+ gu_buf_flush(rdr->jit_state->label_patches);
+
for (size_t i = 0; i < n_instrs; i++) {
+ size_t labels_count = gu_buf_length(rdr->jit_state->label_patches);
+ if (labels_count > 0) {
+ PgfLabelPatch* patch =
+ gu_buf_index(rdr->jit_state->label_patches, PgfLabelPatch, labels_count-1);
+ if (patch->label == curr_label) {
+ jit_patch(patch->ref);
+ gu_buf_trim_n(rdr->jit_state->label_patches, 1);
+ }
+ }
+
#ifdef PGF_JIT_DEBUG
gu_printf(out, err, "%04d ", curr_label++);
#endif
@@ -354,19 +373,16 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
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_finish(gu_buf_last);
+ jit_ldxr_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
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);
+ jit_finishr(JIT_V0);
+ jit_retval_p(JIT_V1);
+ jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun));
break;
}
case PGF_INSTR_CASE: {
@@ -375,6 +391,24 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
#ifdef PGF_JIT_DEBUG
gu_printf(out, err, "CASE %s %04d\n", id, curr_label+offset);
#endif
+ jit_insn *jump=
+ jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward());
+
+ PgfLabelPatch label_patch;
+ label_patch.label = curr_label+offset;
+ label_patch.ref = jump;
+ gu_buf_push(rdr->jit_state->label_patches, PgfLabelPatch, label_patch);
+
+ PgfCallPatch call_patch;
+ call_patch.cid = id;
+ call_patch.ref = jump-6;
+ gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, call_patch);
+
+ jit_prepare(2);
+ jit_pusharg_p(JIT_V1);
+ jit_getarg_p(JIT_V2, es_arg);
+ jit_pusharg_p(JIT_V2);
+ jit_finish(pgf_evaluate_save_variables);
break;
}
case PGF_INSTR_CASE_INT: {
@@ -434,7 +468,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
curr_offset++;
- gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch);
+ gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
break;
}
case PGF_INSTR_PUT_CLOSURE: {
@@ -486,13 +520,8 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
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_finish(gu_buf_last);
+ jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
break;
}
@@ -536,10 +565,10 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
void
pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr)
{
- size_t n_patches = gu_buf_length(rdr->jit_state->patches);
+ size_t n_patches = gu_buf_length(rdr->jit_state->call_patches);
for (size_t i = 0; i < n_patches; i++) {
PgfCallPatch* patch =
- gu_buf_index(rdr->jit_state->patches, PgfCallPatch, i);
+ gu_buf_index(rdr->jit_state->call_patches, PgfCallPatch, i);
PgfAbsCat* arg =
gu_map_get(abstr->cats, patch->cid, PgfAbsCat*);
diff --git a/src/runtime/c/pgf/lightning/i386/core-32.h b/src/runtime/c/pgf/lightning/i386/core-32.h
index a94682def..9b1810761 100644
--- a/src/runtime/c/pgf/lightning/i386/core-32.h
+++ b/src/runtime/c/pgf/lightning/i386/core-32.h
@@ -106,7 +106,7 @@ struct jit_local_state {
#define jit_pusharg_i(rs) PUSHLr(rs)
#define jit_finish(sub) (_jitl.finish_ref = jit_calli((sub)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0, _jitl.finish_ref)
-#define jit_finishr(reg) (jit_callr((reg)), )
+#define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))