mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
finally proper stack unwind in the evaluator
This commit is contained in:
@@ -24,7 +24,7 @@ generateByteCode gr arity eqs =
|
|||||||
is = push_is (arity-1) arity []
|
is = push_is (arity-1) arity []
|
||||||
|
|
||||||
compileEquations :: SourceGrammar -> Int -> Int -> [IVal] -> [([(Ident,IVal)],[Patt],Term)] -> Maybe (Int,CodeLabel) -> [[Instr]] -> ([[Instr]],[Instr])
|
compileEquations :: SourceGrammar -> Int -> Int -> [IVal] -> [([(Ident,IVal)],[Patt],Term)] -> Maybe (Int,CodeLabel) -> [[Instr]] -> ([[Instr]],[Instr])
|
||||||
compileEquations gr arity st _ [] fl bs = (bs,[mkFail st fl])
|
compileEquations gr arity st _ [] fl bs = (bs,mkFail arity st fl)
|
||||||
compileEquations gr arity st [] ((vs,[],t):_) fl bs = compileBody gr arity st vs t bs
|
compileEquations gr arity st [] ((vs,[],t):_) fl bs = compileBody gr arity st vs t bs
|
||||||
compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty
|
compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty
|
||||||
where
|
where
|
||||||
@@ -32,7 +32,7 @@ compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty
|
|||||||
[] -> (bs,[FAIL])
|
[] -> (bs,[FAIL])
|
||||||
(cn:cns) -> let (bs1,instrs1) = compileBranch0 fl bs cn
|
(cn:cns) -> let (bs1,instrs1) = compileBranch0 fl bs cn
|
||||||
bs2 = foldl (compileBranch fl) bs1 cns
|
bs2 = foldl (compileBranch fl) bs1 cns
|
||||||
bs3 = [mkFail st fl]:bs2
|
bs3 = mkFail arity st fl : bs2
|
||||||
in (bs3,EVAL (shiftIVal st i) RecCall : instrs1)
|
in (bs3,EVAL (shiftIVal st i) RecCall : instrs1)
|
||||||
whilePP ((vs, PP c ps' : ps, t):eqs) cns = whilePP eqs (Map.insertWith (++) (Q c,length ps') [(vs,ps'++ps,t)] cns)
|
whilePP ((vs, PP c ps' : ps, t):eqs) cns = whilePP eqs (Map.insertWith (++) (Q c,length ps') [(vs,ps'++ps,t)] cns)
|
||||||
whilePP ((vs, PInt n : ps, t):eqs) cns = whilePP eqs (Map.insertWith (++) (EInt n,0) [(vs,ps,t)] cns)
|
whilePP ((vs, PInt n : ps, t):eqs) cns = whilePP eqs (Map.insertWith (++) (EInt n,0) [(vs,ps,t)] cns)
|
||||||
@@ -75,8 +75,12 @@ compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty
|
|||||||
let (bs1,instrs) = compileEquations gr arity (st+n) (push_is (st+n-1) n is) eqs fl ((case_instr t n (length bs1) : instrs) : bs)
|
let (bs1,instrs) = compileEquations gr arity (st+n) (push_is (st+n-1) n is) eqs fl ((case_instr t n (length bs1) : instrs) : bs)
|
||||||
in bs1
|
in bs1
|
||||||
|
|
||||||
mkFail st1 Nothing = FAIL
|
mkFail arity st1 Nothing
|
||||||
mkFail st1 (Just (st0,l)) = DROP (st1-st0) l
|
| arity+1 /= st1 = [DROP (st1-arity), FAIL]
|
||||||
|
| otherwise = [FAIL]
|
||||||
|
mkFail arity st1 (Just (st0,l))
|
||||||
|
| st1 /= st0 = [DROP (st1-st0), JUMP l]
|
||||||
|
| otherwise = [JUMP l]
|
||||||
|
|
||||||
compileBody gr arity st vs e bs =
|
compileBody gr arity st vs e bs =
|
||||||
let (heap,bs1,is) = compileFun gr arity st vs e 0 bs []
|
let (heap,bs1,is) = compileFun gr arity st vs e 0 bs []
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ mkCanon2pgf opts gr am = do
|
|||||||
|
|
||||||
funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef gr arity mdef, 0)) |
|
funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef gr arity mdef, 0)) |
|
||||||
((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs,
|
((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs,
|
||||||
let arity = mkArrity ma ty]
|
let arity = mkArity ma mdef ty]
|
||||||
|
|
||||||
cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) |
|
cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) |
|
||||||
((m,c),AbsCat (Just (L _ cont))) <- adefs]
|
((m,c),AbsCat (Just (L _ cont))) <- adefs]
|
||||||
|
|
||||||
@@ -150,9 +150,10 @@ mkDef gr arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eq
|
|||||||
)
|
)
|
||||||
mkDef gr arity Nothing = Nothing
|
mkDef gr arity Nothing = Nothing
|
||||||
|
|
||||||
mkArrity (Just a) ty = a
|
mkArity (Just a) _ ty = a -- known arity, i.e. defined function
|
||||||
mkArrity Nothing ty = let (ctxt, _, _) = GM.typeForm ty
|
mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom
|
||||||
in length ctxt
|
mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor
|
||||||
|
in length ctxt
|
||||||
|
|
||||||
genCncCats gr am cm cdefs =
|
genCncCats gr am cm cdefs =
|
||||||
let (index,cats) = mkCncCats 0 cdefs
|
let (index,cats) = mkCncCats 0 cdefs
|
||||||
|
|||||||
@@ -136,8 +136,9 @@ typedef enum {
|
|||||||
PGF_INSTR_PUSH = 9,
|
PGF_INSTR_PUSH = 9,
|
||||||
PGF_INSTR_EVAL = 10,
|
PGF_INSTR_EVAL = 10,
|
||||||
PGF_INSTR_DROP = 13,
|
PGF_INSTR_DROP = 13,
|
||||||
PGF_INSTR_FAIL = 14,
|
PGF_INSTR_JUMP = 14,
|
||||||
PGF_INSTR_ADD = 15
|
PGF_INSTR_FAIL = 15,
|
||||||
|
PGF_INSTR_ADD = 16
|
||||||
} PgfInstruction;
|
} PgfInstruction;
|
||||||
|
|
||||||
typedef GuSeq PgfConcrs;
|
typedef GuSeq PgfConcrs;
|
||||||
|
|||||||
@@ -5,6 +5,23 @@
|
|||||||
|
|
||||||
#define PGF_ARGS_DELTA 5
|
#define PGF_ARGS_DELTA 5
|
||||||
|
|
||||||
|
static inline PgfClosure*
|
||||||
|
pgf_mk_pap(PgfEvalState* state, PgfClosure* fun,
|
||||||
|
size_t n_args, PgfClosure** args)
|
||||||
|
{
|
||||||
|
if (n_args > 0) {
|
||||||
|
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
|
||||||
|
val->header.code = state->eval_gates->evaluate_value_pap;
|
||||||
|
val->fun = fun;
|
||||||
|
val->n_args = n_args*sizeof(PgfClosure*);
|
||||||
|
for (size_t i = 0; i < n_args; i++) {
|
||||||
|
val->args[i] = args[i];
|
||||||
|
}
|
||||||
|
return &val->header;
|
||||||
|
}
|
||||||
|
return fun;
|
||||||
|
}
|
||||||
|
|
||||||
PgfClosure*
|
PgfClosure*
|
||||||
pgf_evaluate_expr_thunk(PgfEvalState* state, PgfExprThunk* thunk)
|
pgf_evaluate_expr_thunk(PgfEvalState* state, PgfExprThunk* thunk)
|
||||||
{
|
{
|
||||||
@@ -64,15 +81,11 @@ repeat:;
|
|||||||
PgfExprMeta* emeta = ei.data;
|
PgfExprMeta* emeta = ei.data;
|
||||||
|
|
||||||
PgfValueMeta* val =
|
PgfValueMeta* val =
|
||||||
gu_new_flex(state->pool, PgfValueMeta, args, n_args);
|
gu_new(PgfValueMeta, state->pool);
|
||||||
val->header.code = state->eval_gates->evaluate_value_meta;
|
val->header.code = state->eval_gates->evaluate_meta;
|
||||||
val->id = emeta->id;
|
val->env = env;
|
||||||
val->n_args = n_args*sizeof(PgfClosure*);
|
val->id = emeta->id;
|
||||||
for (size_t i = 0; i < n_args; i++) {
|
res = pgf_mk_pap(state, &val->header, n_args, args);
|
||||||
val->args[i] = args[n_args-i-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
res = &val->header;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGF_EXPR_FUN: {
|
case PGF_EXPR_FUN: {
|
||||||
@@ -83,18 +96,7 @@ repeat:;
|
|||||||
gu_assert(absfun != NULL);
|
gu_assert(absfun != NULL);
|
||||||
|
|
||||||
if (absfun->closure.code != NULL) {
|
if (absfun->closure.code != NULL) {
|
||||||
res = (PgfClosure*) &absfun->closure;
|
res = pgf_mk_pap(state, (PgfClosure*) &absfun->closure, n_args, args);
|
||||||
|
|
||||||
if (n_args > 0) {
|
|
||||||
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
|
|
||||||
val->header.code = state->eval_gates->evaluate_value_pap;
|
|
||||||
val->fun = res;
|
|
||||||
val->n_args = n_args*sizeof(PgfClosure*);
|
|
||||||
for (size_t i = 0; i < n_args; i++) {
|
|
||||||
val->args[i] = args[i];
|
|
||||||
}
|
|
||||||
res = &val->header;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
size_t arity = absfun->arity;
|
size_t arity = absfun->arity;
|
||||||
|
|
||||||
@@ -113,18 +115,7 @@ repeat:;
|
|||||||
PgfExprThunk* lambda = gu_new(PgfExprThunk, state->pool);
|
PgfExprThunk* lambda = gu_new(PgfExprThunk, state->pool);
|
||||||
lambda->header.code = state->eval_gates->evaluate_value_lambda;
|
lambda->header.code = state->eval_gates->evaluate_value_lambda;
|
||||||
lambda->env = NULL;
|
lambda->env = NULL;
|
||||||
res = &lambda->header;
|
res = pgf_mk_pap(state, &lambda->header, n_args, args);
|
||||||
|
|
||||||
if (n_args > 0) {
|
|
||||||
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
|
|
||||||
val->header.code = state->eval_gates->evaluate_value_pap;
|
|
||||||
val->fun = &lambda->header;
|
|
||||||
val->n_args = n_args*sizeof(PgfClosure*);
|
|
||||||
for (size_t i = 0; i < n_args; i++) {
|
|
||||||
val->args[i] = args[i];
|
|
||||||
}
|
|
||||||
res = &val->header;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < arity; i++) {
|
for (size_t i = 0; i < arity; i++) {
|
||||||
PgfExpr new_expr, arg;
|
PgfExpr new_expr, arg;
|
||||||
@@ -180,18 +171,7 @@ repeat:;
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = tmp_env->closure;
|
res = pgf_mk_pap(state, tmp_env->closure, n_args, args);
|
||||||
|
|
||||||
if (n_args > 0) {
|
|
||||||
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
|
|
||||||
val->header.code = state->eval_gates->evaluate_value_pap;
|
|
||||||
val->fun = res;
|
|
||||||
val->n_args = n_args*sizeof(PgfClosure*);
|
|
||||||
for (size_t i = 0; i < n_args; i++) {
|
|
||||||
val->args[i] = args[i];
|
|
||||||
}
|
|
||||||
res = &val->header;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGF_EXPR_TYPED: {
|
case PGF_EXPR_TYPED: {
|
||||||
@@ -245,28 +225,6 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
|||||||
expr = absfun->ep.expr;
|
expr = absfun->ep.expr;
|
||||||
n_args = absfun->arity;
|
n_args = absfun->arity;
|
||||||
args = val->args;
|
args = val->args;
|
||||||
} else if (clos->code == state->eval_gates->evaluate_value_gen) {
|
|
||||||
PgfValueGen* val = (PgfValueGen*) clos;
|
|
||||||
|
|
||||||
PgfExprVar *evar =
|
|
||||||
gu_new_variant(PGF_EXPR_VAR,
|
|
||||||
PgfExprVar,
|
|
||||||
&expr, pool);
|
|
||||||
evar->var = level - val->level - 1;
|
|
||||||
|
|
||||||
n_args = val->n_args/sizeof(PgfClosure*);
|
|
||||||
args = val->args;
|
|
||||||
} else if (clos->code == state->eval_gates->evaluate_value_meta) {
|
|
||||||
PgfValueMeta* val = (PgfValueMeta*) clos;
|
|
||||||
|
|
||||||
PgfExprMeta *emeta =
|
|
||||||
gu_new_variant(PGF_EXPR_META,
|
|
||||||
PgfExprMeta,
|
|
||||||
&expr, pool);
|
|
||||||
emeta->id = val->id;
|
|
||||||
|
|
||||||
n_args = val->n_args / sizeof(PgfClosure*);
|
|
||||||
args = val->args;
|
|
||||||
} else if (clos->code == state->eval_gates->evaluate_value_lit) {
|
} else if (clos->code == state->eval_gates->evaluate_value_lit) {
|
||||||
PgfValueLit* val = (PgfValueLit*) clos;
|
PgfValueLit* val = (PgfValueLit*) clos;
|
||||||
|
|
||||||
@@ -316,18 +274,18 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
|||||||
|
|
||||||
PgfValueGen* gen =
|
PgfValueGen* gen =
|
||||||
gu_new(PgfValueGen, state->pool);
|
gu_new(PgfValueGen, state->pool);
|
||||||
gen->header.code = state->eval_gates->evaluate_value_gen;
|
gen->header.code = state->eval_gates->evaluate_gen;
|
||||||
gen->level = level;
|
gen->level = level;
|
||||||
gen->n_args = 0;
|
|
||||||
|
|
||||||
PgfValuePAP* new_pap = gu_new_flex(state->pool, PgfValuePAP, args, pap->n_args+1);
|
size_t n_args = pap->n_args/sizeof(PgfClosure*);
|
||||||
|
PgfValuePAP* new_pap = gu_new_flex(state->pool, PgfValuePAP, args, n_args+1);
|
||||||
new_pap->header.code = state->eval_gates->evaluate_value_pap;
|
new_pap->header.code = state->eval_gates->evaluate_value_pap;
|
||||||
new_pap->fun = pap->fun;
|
new_pap->fun = pap->fun;
|
||||||
new_pap->n_args = pap->n_args+sizeof(PgfClosure*);
|
new_pap->n_args = pap->n_args+sizeof(PgfClosure*);
|
||||||
for (size_t i = 0; i < pap->n_args/sizeof(PgfClosure*); i++) {
|
new_pap->args[0] = &gen->header;
|
||||||
new_pap->args[i] = pap->args[i];
|
for (size_t i = 0; i < n_args; i++) {
|
||||||
|
new_pap->args[i+1] = pap->args[i];
|
||||||
}
|
}
|
||||||
new_pap->args[pap->n_args] = &gen->header;
|
|
||||||
|
|
||||||
PgfExprAbs *eabs =
|
PgfExprAbs *eabs =
|
||||||
gu_new_variant(PGF_EXPR_ABS,
|
gu_new_variant(PGF_EXPR_ABS,
|
||||||
@@ -336,6 +294,32 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
|||||||
eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
|
eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
|
||||||
eabs->id = gu_format_string(pool, "v%d", level);
|
eabs->id = gu_format_string(pool, "v%d", level);
|
||||||
eabs->body = pgf_value2expr(state, level+1, &new_pap->header, pool);
|
eabs->body = pgf_value2expr(state, level+1, &new_pap->header, pool);
|
||||||
|
} else if (clos->code == state->eval_gates->evaluate_value_const) {
|
||||||
|
PgfValuePAP* val = (PgfValuePAP*) clos;
|
||||||
|
|
||||||
|
if (val->fun->code == state->eval_gates->evaluate_meta) {
|
||||||
|
PgfValueMeta* fun = (PgfValueMeta*) val->fun;
|
||||||
|
|
||||||
|
PgfExprMeta *emeta =
|
||||||
|
gu_new_variant(PGF_EXPR_META,
|
||||||
|
PgfExprMeta,
|
||||||
|
&expr, pool);
|
||||||
|
emeta->id = fun->id;
|
||||||
|
} else if (val->fun->code == state->eval_gates->evaluate_gen) {
|
||||||
|
PgfValueGen* fun = (PgfValueGen*) val->fun;
|
||||||
|
|
||||||
|
PgfExprVar *evar =
|
||||||
|
gu_new_variant(PGF_EXPR_VAR,
|
||||||
|
PgfExprVar,
|
||||||
|
&expr, pool);
|
||||||
|
evar->var = level - fun->level - 1;
|
||||||
|
} else {
|
||||||
|
PgfAbsFun* absfun = gu_container(val->fun, PgfAbsFun, closure);
|
||||||
|
expr = absfun->ep.expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_args = val->n_args/sizeof(PgfClosure*);
|
||||||
|
args = val->args;
|
||||||
} else {
|
} else {
|
||||||
gu_impossible();
|
gu_impossible();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,16 +40,12 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
PgfClosure header;
|
PgfClosure header;
|
||||||
int level;
|
int level;
|
||||||
size_t n_args;
|
|
||||||
PgfClosure* args[];
|
|
||||||
} PgfValueGen;
|
} PgfValueGen;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PgfClosure header;
|
PgfClosure header;
|
||||||
PgfEnv* env;
|
PgfEnv* env;
|
||||||
PgfMetaId id;
|
PgfMetaId id;
|
||||||
size_t n_args;
|
|
||||||
PgfClosure* args[];
|
|
||||||
} PgfValueMeta;
|
} PgfValueMeta;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -68,11 +64,12 @@ struct PgfEvalGates {
|
|||||||
PgfFunction evaluate_expr_thunk;
|
PgfFunction evaluate_expr_thunk;
|
||||||
PgfFunction evaluate_indirection;
|
PgfFunction evaluate_indirection;
|
||||||
PgfFunction evaluate_value;
|
PgfFunction evaluate_value;
|
||||||
PgfFunction evaluate_value_gen;
|
|
||||||
PgfFunction evaluate_value_meta;
|
|
||||||
PgfFunction evaluate_value_lit;
|
PgfFunction evaluate_value_lit;
|
||||||
PgfFunction evaluate_value_pap;
|
PgfFunction evaluate_value_pap;
|
||||||
PgfFunction evaluate_value_lambda;
|
PgfFunction evaluate_value_lambda;
|
||||||
|
PgfFunction evaluate_value_const;
|
||||||
|
PgfFunction evaluate_meta;
|
||||||
|
PgfFunction evaluate_gen;
|
||||||
PgfFunction evaluate_caf;
|
PgfFunction evaluate_caf;
|
||||||
|
|
||||||
PgfFunction update_closure;
|
PgfFunction update_closure;
|
||||||
|
|||||||
@@ -329,8 +329,7 @@ PgfEvalGates*
|
|||||||
pgf_jit_gates(PgfReader* rdr)
|
pgf_jit_gates(PgfReader* rdr)
|
||||||
{
|
{
|
||||||
PgfEvalGates* gates = gu_new(PgfEvalGates, rdr->opool);
|
PgfEvalGates* gates = gu_new(PgfEvalGates, rdr->opool);
|
||||||
jit_insn* next;
|
jit_insn *ref, *next, *ref2;
|
||||||
jit_insn* ref, *ref2;
|
|
||||||
|
|
||||||
pgf_jit_make_space(rdr, JIT_CODE_WINDOW);
|
pgf_jit_make_space(rdr, JIT_CODE_WINDOW);
|
||||||
|
|
||||||
@@ -346,102 +345,6 @@ pgf_jit_gates(PgfReader* rdr)
|
|||||||
jit_ldxi_p(JIT_RET, JIT_VHEAP, offsetof(PgfValue, con));
|
jit_ldxi_p(JIT_RET, JIT_VHEAP, offsetof(PgfValue, con));
|
||||||
jit_bare_ret();
|
jit_bare_ret();
|
||||||
|
|
||||||
pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2);
|
|
||||||
|
|
||||||
gates->evaluate_value_gen = jit_get_ip().ptr;
|
|
||||||
jit_subr_p(JIT_R0, JIT_FP, JIT_SP);
|
|
||||||
jit_subi_p(JIT_R0, JIT_R0, sizeof(void*));
|
|
||||||
ref = jit_bnei_i(jit_forward(), JIT_R0, 0);
|
|
||||||
jit_movr_p(JIT_VHEAP, JIT_VCLOS);
|
|
||||||
jit_bare_ret();
|
|
||||||
jit_patch(ref);
|
|
||||||
jit_pushr_i(JIT_R0);
|
|
||||||
jit_prepare(2);
|
|
||||||
jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValueGen));
|
|
||||||
jit_pusharg_ui(JIT_R0);
|
|
||||||
jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool));
|
|
||||||
jit_pusharg_p(JIT_R0);
|
|
||||||
jit_finish(gu_malloc);
|
|
||||||
jit_retval(JIT_VHEAP);
|
|
||||||
jit_popr_i(JIT_R0);
|
|
||||||
jit_movi_p(JIT_R1, gates->evaluate_value_gen);
|
|
||||||
jit_str_p(JIT_VHEAP, JIT_R1);
|
|
||||||
jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueGen,level));
|
|
||||||
jit_stxi_p(offsetof(PgfValueGen,level), JIT_VHEAP, JIT_R1);
|
|
||||||
jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueGen,n_args));
|
|
||||||
jit_addr_i(JIT_R1, JIT_R1, JIT_R0);
|
|
||||||
jit_stxi_p(offsetof(PgfValueGen,n_args), JIT_VHEAP, JIT_R1);
|
|
||||||
jit_movi_i(JIT_R1, offsetof(PgfValueGen,args));
|
|
||||||
jit_ldxi_i(JIT_R2, JIT_VCLOS, offsetof(PgfValueGen,n_args));
|
|
||||||
jit_addr_i(JIT_R2, JIT_R2, JIT_R1);
|
|
||||||
jit_pushr_i(JIT_R0);
|
|
||||||
next = jit_get_label();
|
|
||||||
ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2);
|
|
||||||
jit_ldxr_i(JIT_R0, JIT_VCLOS, JIT_R1);
|
|
||||||
jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0);
|
|
||||||
jit_addi_i(JIT_R1, JIT_R1, sizeof(void*));
|
|
||||||
jit_jmpi(next);
|
|
||||||
jit_patch(ref);
|
|
||||||
jit_popr_i(JIT_R0);
|
|
||||||
jit_addr_i(JIT_R2, JIT_R2, JIT_R0);
|
|
||||||
jit_popr_p(JIT_VCLOS);
|
|
||||||
next = jit_get_label();
|
|
||||||
ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2);
|
|
||||||
jit_popr_p(JIT_R0);
|
|
||||||
jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0);
|
|
||||||
jit_addi_i(JIT_R1, JIT_R1, sizeof(void*));
|
|
||||||
jit_jmpi(next);
|
|
||||||
jit_patch(ref);
|
|
||||||
jit_jmpr(JIT_VCLOS);
|
|
||||||
|
|
||||||
pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2);
|
|
||||||
|
|
||||||
gates->evaluate_value_meta = jit_get_ip().ptr;
|
|
||||||
jit_subr_p(JIT_R0, JIT_FP, JIT_SP);
|
|
||||||
jit_subi_p(JIT_R0, JIT_R0, sizeof(void*));
|
|
||||||
ref = jit_bnei_i(jit_forward(), JIT_R0, 0);
|
|
||||||
jit_movr_p(JIT_VHEAP, JIT_VCLOS);
|
|
||||||
jit_bare_ret();
|
|
||||||
jit_patch(ref);
|
|
||||||
jit_pushr_i(JIT_R0);
|
|
||||||
jit_prepare(2);
|
|
||||||
jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValueMeta));
|
|
||||||
jit_pusharg_ui(JIT_R0);
|
|
||||||
jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool));
|
|
||||||
jit_pusharg_p(JIT_R0);
|
|
||||||
jit_finish(gu_malloc);
|
|
||||||
jit_retval(JIT_VHEAP);
|
|
||||||
jit_popr_i(JIT_R0);
|
|
||||||
jit_movi_p(JIT_R1, gates->evaluate_value_meta);
|
|
||||||
jit_str_p(JIT_VHEAP, JIT_R1);
|
|
||||||
jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueMeta,id));
|
|
||||||
jit_stxi_p(offsetof(PgfValueMeta,id), JIT_VHEAP, JIT_R1);
|
|
||||||
jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueMeta,n_args));
|
|
||||||
jit_addr_i(JIT_R1, JIT_R1, JIT_R0);
|
|
||||||
jit_stxi_p(offsetof(PgfValueMeta,n_args), JIT_VHEAP, JIT_R1);
|
|
||||||
jit_movi_i(JIT_R1, offsetof(PgfValueMeta,args));
|
|
||||||
jit_ldxi_i(JIT_R2, JIT_VCLOS, offsetof(PgfValueMeta,n_args));
|
|
||||||
jit_addr_i(JIT_R2, JIT_R2, JIT_R1);
|
|
||||||
jit_pushr_i(JIT_R0);
|
|
||||||
next = jit_get_label();
|
|
||||||
ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2);
|
|
||||||
jit_ldxr_i(JIT_R0, JIT_VCLOS, JIT_R1);
|
|
||||||
jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0);
|
|
||||||
jit_addi_i(JIT_R1, JIT_R1, sizeof(PgfClosure*));
|
|
||||||
jit_jmpi(next);
|
|
||||||
jit_patch(ref);
|
|
||||||
jit_popr_i(JIT_R0);
|
|
||||||
jit_addr_i(JIT_R2, JIT_R2, JIT_R0);
|
|
||||||
jit_popr_p(JIT_VCLOS);
|
|
||||||
next = jit_get_label();
|
|
||||||
ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2);
|
|
||||||
jit_popr_p(JIT_R0);
|
|
||||||
jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0);
|
|
||||||
jit_addi_i(JIT_R1, JIT_R1, sizeof(PgfClosure*));
|
|
||||||
jit_jmpi(next);
|
|
||||||
jit_patch(ref);
|
|
||||||
jit_jmpr(JIT_VCLOS);
|
|
||||||
|
|
||||||
pgf_jit_make_space(rdr, JIT_CODE_WINDOW);
|
pgf_jit_make_space(rdr, JIT_CODE_WINDOW);
|
||||||
|
|
||||||
gates->evaluate_value_lit = jit_get_ip().ptr;
|
gates->evaluate_value_lit = jit_get_ip().ptr;
|
||||||
@@ -470,6 +373,7 @@ pgf_jit_gates(PgfReader* rdr)
|
|||||||
jit_getarg_p(JIT_VCLOS, closure_arg);
|
jit_getarg_p(JIT_VCLOS, closure_arg);
|
||||||
jit_ldr_p(JIT_R0, JIT_VCLOS);
|
jit_ldr_p(JIT_R0, JIT_VCLOS);
|
||||||
jit_callr(JIT_R0);
|
jit_callr(JIT_R0);
|
||||||
|
jit_insn* enter_ret = (void*) jit_get_ip().ptr;
|
||||||
jit_movr_p(JIT_RET, JIT_VHEAP);
|
jit_movr_p(JIT_RET, JIT_VHEAP);
|
||||||
jit_ret();
|
jit_ret();
|
||||||
|
|
||||||
@@ -571,6 +475,7 @@ pgf_jit_gates(PgfReader* rdr)
|
|||||||
ref = jit_beqr_p(jit_forward(), JIT_VCLOS, JIT_RET);
|
ref = jit_beqr_p(jit_forward(), JIT_VCLOS, JIT_RET);
|
||||||
jit_pushr_p(JIT_VCLOS);
|
jit_pushr_p(JIT_VCLOS);
|
||||||
jit_pushr_p(JIT_FP);
|
jit_pushr_p(JIT_FP);
|
||||||
|
jit_movr_p(JIT_FP, JIT_SP);
|
||||||
jit_movi_p(JIT_R1, gates->update_closure);
|
jit_movi_p(JIT_R1, gates->update_closure);
|
||||||
jit_pushr_p(JIT_R1);
|
jit_pushr_p(JIT_R1);
|
||||||
jit_retval(JIT_VCLOS);
|
jit_retval(JIT_VCLOS);
|
||||||
@@ -595,31 +500,96 @@ pgf_jit_gates(PgfReader* rdr)
|
|||||||
jit_ldr_p(JIT_R0, JIT_VCLOS);
|
jit_ldr_p(JIT_R0, JIT_VCLOS);
|
||||||
jit_jmpr(JIT_R0);
|
jit_jmpr(JIT_R0);
|
||||||
|
|
||||||
|
pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2);
|
||||||
|
|
||||||
|
gates->evaluate_value_const = jit_get_ip().ptr;
|
||||||
|
jit_jmpi(gates->evaluate_value);
|
||||||
|
|
||||||
|
pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2);
|
||||||
|
|
||||||
gates->mk_const = jit_get_ip().ptr;
|
gates->mk_const = jit_get_ip().ptr;
|
||||||
jit_ldxi_p(JIT_R0, JIT_VCLOS, offsetof(PgfAbsFun,arity)-offsetof(PgfAbsFun,closure));
|
jit_popr_p(JIT_R0);
|
||||||
jit_muli_i(JIT_R0, JIT_R0, sizeof(PgfClosure*));
|
ref2 = jit_bnei_i(jit_forward(), JIT_R0, (int)gates->update_closure);
|
||||||
|
jit_subr_p(JIT_R0, JIT_FP, JIT_SP);
|
||||||
jit_pushr_i(JIT_R0);
|
jit_pushr_i(JIT_R0);
|
||||||
jit_prepare(2);
|
jit_prepare(2);
|
||||||
jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValue));
|
jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValuePAP));
|
||||||
jit_pusharg_ui(JIT_R0);
|
jit_pusharg_ui(JIT_R0);
|
||||||
jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool));
|
jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool));
|
||||||
jit_pusharg_p(JIT_R0);
|
jit_pusharg_p(JIT_R0);
|
||||||
jit_finish(gu_malloc);
|
jit_finish(gu_malloc);
|
||||||
jit_movi_p(JIT_R1, gates->evaluate_value);
|
|
||||||
jit_str_p(JIT_RET, JIT_R1);
|
|
||||||
jit_stxi_p(offsetof(PgfValue,con), JIT_RET, JIT_VCLOS);
|
|
||||||
jit_movr_p(JIT_VHEAP, JIT_RET);
|
|
||||||
jit_popr_i(JIT_R1);
|
jit_popr_i(JIT_R1);
|
||||||
jit_popr_p(JIT_VCLOS);
|
jit_movi_p(JIT_R2, gates->evaluate_value_const);
|
||||||
|
jit_str_p(JIT_RET, JIT_R2);
|
||||||
|
jit_stxi_p(offsetof(PgfValuePAP,fun), JIT_RET, JIT_VCLOS);
|
||||||
|
jit_stxi_p(offsetof(PgfValuePAP,n_args), JIT_RET, JIT_R1);
|
||||||
|
jit_ldxi_p(JIT_VHEAP, JIT_FP, sizeof(void*));
|
||||||
|
jit_movi_p(JIT_R2, gates->evaluate_indirection);
|
||||||
|
jit_str_p(JIT_VHEAP, JIT_R2);
|
||||||
|
jit_stxi_p(offsetof(PgfIndirection, val), JIT_VHEAP, JIT_RET);
|
||||||
|
jit_ldr_p(JIT_R2, JIT_FP);
|
||||||
|
jit_pushr_p(JIT_R2);
|
||||||
|
jit_ldxi_p(JIT_R2, JIT_FP, 2*sizeof(void*));
|
||||||
|
jit_pushr_p(JIT_R2);
|
||||||
|
jit_addi_p(JIT_RET, JIT_RET, offsetof(PgfValuePAP,args)-sizeof(PgfClosure*));
|
||||||
next = jit_get_label();
|
next = jit_get_label();
|
||||||
ref = jit_blei_i(jit_forward(), JIT_R1, 0);
|
ref = jit_blei_i(jit_forward(), JIT_R1, 0);
|
||||||
jit_popr_p(JIT_R2);
|
jit_ldxi_p(JIT_R2, JIT_FP, -sizeof(void*));
|
||||||
jit_stxi_p(offsetof(PgfValue,args), JIT_RET, JIT_R2);
|
jit_stxi_p(2*sizeof(void*), JIT_FP, JIT_R2);
|
||||||
jit_addi_i(JIT_RET, JIT_RET, sizeof(void*));
|
jit_stxr_p(JIT_R1, JIT_RET, JIT_R2);
|
||||||
|
jit_subi_i(JIT_FP, JIT_FP, sizeof(void*));
|
||||||
jit_subi_i(JIT_R1, JIT_R1, sizeof(void*));
|
jit_subi_i(JIT_R1, JIT_R1, sizeof(void*));
|
||||||
jit_jmpi(next);
|
jit_jmpi(next);
|
||||||
jit_patch(ref);
|
jit_patch(ref);
|
||||||
jit_jmpr(JIT_VCLOS);
|
jit_popr_p(JIT_R0);
|
||||||
|
jit_popr_p(JIT_FP);
|
||||||
|
jit_addi_p(JIT_SP, JIT_SP, 3*sizeof(void*));
|
||||||
|
jit_pushr_p(JIT_R0);
|
||||||
|
jit_jmpi(gates->mk_const);
|
||||||
|
jit_patch(ref2);
|
||||||
|
ref2 = jit_bnei_i(jit_forward(), JIT_R0, (int)enter_ret);
|
||||||
|
jit_subr_p(JIT_R0, JIT_FP, JIT_SP);
|
||||||
|
jit_pushr_i(JIT_R0);
|
||||||
|
jit_prepare(2);
|
||||||
|
jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValuePAP));
|
||||||
|
jit_pusharg_ui(JIT_R0);
|
||||||
|
jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool));
|
||||||
|
jit_pusharg_p(JIT_R0);
|
||||||
|
jit_finish(gu_malloc);
|
||||||
|
jit_popr_i(JIT_R1);
|
||||||
|
jit_movr_p(JIT_VHEAP, JIT_RET);
|
||||||
|
jit_movi_p(JIT_R2, gates->evaluate_value_const);
|
||||||
|
jit_str_p(JIT_VHEAP, JIT_R2);
|
||||||
|
jit_stxi_p(offsetof(PgfValuePAP,fun), JIT_VHEAP, JIT_VCLOS);
|
||||||
|
jit_stxi_p(offsetof(PgfValuePAP,n_args), JIT_VHEAP, JIT_R1);
|
||||||
|
next = jit_get_label();
|
||||||
|
ref = jit_blei_i(jit_forward(), JIT_R1, 0);
|
||||||
|
jit_popr_p(JIT_R2);
|
||||||
|
jit_stxi_p(offsetof(PgfValuePAP,args), JIT_RET, JIT_R2);
|
||||||
|
jit_addi_p(JIT_RET, JIT_RET, sizeof(void*));
|
||||||
|
jit_subi_i(JIT_R1, JIT_R1, sizeof(void*));
|
||||||
|
jit_jmpi(next);
|
||||||
|
jit_patch(ref);
|
||||||
|
jit_jmpi(enter_ret);
|
||||||
|
jit_patch(ref2);
|
||||||
|
jit_ldxi_p(JIT_VCLOS, JIT_FP, sizeof(void*));
|
||||||
|
jit_ldr_p(JIT_FP, JIT_FP);
|
||||||
|
jit_ldxi_i(JIT_R0, JIT_VCLOS, offsetof(PgfAbsFun,arity)-offsetof(PgfAbsFun,closure));
|
||||||
|
jit_muli_i(JIT_R0, JIT_R0, sizeof(PgfClosure*));
|
||||||
|
jit_addi_i(JIT_R0, JIT_R0, sizeof(void*));
|
||||||
|
jit_subr_p(JIT_R0, JIT_FP, JIT_R0); // don't use jit_subr_p(JIT_SP, JIT_FP, JIT_R0) since it is dangerous on x86
|
||||||
|
jit_movr_p(JIT_SP, JIT_R0);
|
||||||
|
jit_jmpi(gates->mk_const);
|
||||||
|
|
||||||
|
pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2);
|
||||||
|
|
||||||
|
gates->evaluate_gen = jit_get_ip().ptr;
|
||||||
|
jit_jmpi(gates->mk_const);
|
||||||
|
|
||||||
|
pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2);
|
||||||
|
|
||||||
|
gates->evaluate_meta = jit_get_ip().ptr;
|
||||||
|
jit_jmpi(gates->mk_const);
|
||||||
|
|
||||||
gates->fin.fn = pgf_jit_finalize_cafs;
|
gates->fin.fn = pgf_jit_finalize_cafs;
|
||||||
gates->cafs = NULL;
|
gates->cafs = NULL;
|
||||||
@@ -1134,15 +1104,21 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|||||||
}
|
}
|
||||||
case PGF_INSTR_DROP: {
|
case PGF_INSTR_DROP: {
|
||||||
size_t n = pgf_read_int(rdr);
|
size_t n = pgf_read_int(rdr);
|
||||||
|
|
||||||
|
#ifdef PGF_JIT_DEBUG
|
||||||
|
gu_printf(out, err, "DROP %d\n", n);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_addi_p(JIT_SP, JIT_SP, n*sizeof(PgfClosure*));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PGF_INSTR_JUMP: {
|
||||||
size_t target = pgf_read_int(rdr);
|
size_t target = pgf_read_int(rdr);
|
||||||
|
|
||||||
#ifdef PGF_JIT_DEBUG
|
#ifdef PGF_JIT_DEBUG
|
||||||
gu_printf(out, err, "DROP %d %03d\n", n, target);
|
gu_printf(out, err, "JUMP %03d\n", target);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (n > 0)
|
|
||||||
jit_addi_p(JIT_SP, JIT_SP, n*sizeof(PgfClosure*));
|
|
||||||
|
|
||||||
jit_insn *jump =
|
jit_insn *jump =
|
||||||
jit_jmpi(jit_forward());
|
jit_jmpi(jit_forward());
|
||||||
|
|
||||||
@@ -1151,7 +1127,6 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|||||||
label_patch.ref = jump;
|
label_patch.ref = jump;
|
||||||
label_patch.is_abs = false;
|
label_patch.is_abs = false;
|
||||||
gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, label_patch);
|
gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, label_patch);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGF_INSTR_FAIL:
|
case PGF_INSTR_FAIL:
|
||||||
|
|||||||
@@ -168,9 +168,10 @@ instance Binary Instr where
|
|||||||
put (EVAL (ARG_VAR n) (UpdateCall b c)) = putWord8 49 >> put n >> put (b,c)
|
put (EVAL (ARG_VAR n) (UpdateCall b c)) = putWord8 49 >> put n >> put (b,c)
|
||||||
put (EVAL (FREE_VAR n) (UpdateCall b c)) = putWord8 50 >> put n >> put (b,c)
|
put (EVAL (FREE_VAR n) (UpdateCall b c)) = putWord8 50 >> put n >> put (b,c)
|
||||||
put (EVAL (GLOBAL id) (UpdateCall b c)) = putWord8 51 >> put id >> put (b,c)
|
put (EVAL (GLOBAL id) (UpdateCall b c)) = putWord8 51 >> put id >> put (b,c)
|
||||||
put (DROP n l ) = putWord8 52 >> put (n,l)
|
put (DROP n ) = putWord8 52 >> put n
|
||||||
put (FAIL ) = putWord8 56
|
put (JUMP l ) = putWord8 56 >> put l
|
||||||
put (ADD ) = putWord8 60
|
put (FAIL ) = putWord8 60
|
||||||
|
put (ADD ) = putWord8 64
|
||||||
|
|
||||||
instance Binary Type where
|
instance Binary Type where
|
||||||
put (DTyp hypos cat exps) = put (hypos,cat,exps)
|
put (DTyp hypos cat exps) = put (hypos,cat,exps)
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ data Instr
|
|||||||
| SET_PAD
|
| SET_PAD
|
||||||
| PUSH IVal
|
| PUSH IVal
|
||||||
| EVAL IVal TailInfo
|
| EVAL IVal TailInfo
|
||||||
| DROP {-# UNPACK #-} !Int {-# UNPACK #-} !CodeLabel
|
| DROP {-# UNPACK #-} !Int
|
||||||
|
| JUMP {-# UNPACK #-} !CodeLabel
|
||||||
| FAIL
|
| FAIL
|
||||||
| ADD
|
| ADD
|
||||||
|
|
||||||
@@ -60,7 +61,8 @@ ppInstr (SET v) = text "SET " <+> ppIVal v
|
|||||||
ppInstr (SET_PAD ) = text "SET_PAD"
|
ppInstr (SET_PAD ) = text "SET_PAD"
|
||||||
ppInstr (PUSH v) = text "PUSH " <+> ppIVal v
|
ppInstr (PUSH v) = text "PUSH " <+> ppIVal v
|
||||||
ppInstr (EVAL v ti) = text "EVAL " <+> ppIVal v <+> ppTailInfo ti
|
ppInstr (EVAL v ti) = text "EVAL " <+> ppIVal v <+> ppTailInfo ti
|
||||||
ppInstr (DROP n l ) = text "DROP " <+> int n <+> ppLabel l
|
ppInstr (DROP n ) = text "DROP " <+> int n
|
||||||
|
ppInstr (JUMP l ) = text "JUMP " <+> ppLabel l
|
||||||
ppInstr (FAIL ) = text "FAIL"
|
ppInstr (FAIL ) = text "FAIL"
|
||||||
ppInstr (ADD ) = text "ADD"
|
ppInstr (ADD ) = text "ADD"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user