aboutsummaryrefslogtreecommitdiff
path: root/kernel/nativecode.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/nativecode.ml')
-rw-r--r--kernel/nativecode.ml118
1 files changed, 68 insertions, 50 deletions
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index c8cee7db73..ae070e6f8e 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -259,6 +259,7 @@ type primitive =
| Mk_proj
| Is_int
| Is_float
+ | Is_parray
| Cast_accu
| Upd_cofix
| Force_cofix
@@ -285,7 +286,8 @@ type primitive =
| MLmagic
| MLarrayget
| Mk_empty_instance
- | Coq_primitive of CPrimitives.t * (prefix * pconstant) option
+ | MLparray_of_array
+ | Coq_primitive of CPrimitives.t * bool (* check for accu *)
let eq_primitive p1 p2 =
match p1, p2 with
@@ -346,15 +348,15 @@ let primitive_hash = function
| MLsub -> 31
| MLmul -> 32
| MLmagic -> 33
- | Coq_primitive (prim, None) -> combinesmall 34 (CPrimitives.hash prim)
- | Coq_primitive (prim, Some (prefix,(kn,_))) ->
- combinesmall 35 (combine3 (String.hash prefix) (Constant.hash kn) (CPrimitives.hash prim))
- | Mk_proj -> 36
- | MLarrayget -> 37
- | Mk_empty_instance -> 38
- | Mk_float -> 39
- | Is_float -> 40
+ | Coq_primitive (prim, b) -> combinesmall 34 (combine (CPrimitives.hash prim) (Hashtbl.hash b))
+ | Mk_proj -> 35
+ | MLarrayget -> 36
+ | Mk_empty_instance -> 37
+ | Mk_float -> 38
+ | Is_float -> 39
+ | Is_parray -> 41
| MLnot -> 41
+ | MLparray_of_array -> 42
type mllambda =
| MLlocal of lname
@@ -971,11 +973,14 @@ type prim_aux =
let add_check cond targs args =
let aux cond t a =
- match a with
- | PAml(MLint _) -> cond
- | PAml ml ->
+ match t, a with
+ | CPrimitives.(PITT_type (PT_int63, _)), PAml(MLapp(MLprimitive Mk_uint, _)) -> cond
+ | CPrimitives.(PITT_type (PT_array, _)), PAml(MLapp(MLprimitive MLparray_of_array, _)) -> cond
+ | CPrimitives.(PITT_type (PT_array, _)), PAml(MLapp (MLglobal (Ginternal "get_value"),_)) -> cond
+ | CPrimitives.(PITT_type (prim_ty, _)), PAml ml ->
(* FIXME: use explicit equality function *)
- if List.mem (t, ml) cond then cond else (t, ml)::cond
+ let c = (CPrimitives.PTE prim_ty, ml) in
+ if List.mem c cond then cond else c::cond
| _ -> cond
in
Array.fold_left2 aux cond targs args
@@ -985,13 +990,15 @@ let extract_prim ml_of l =
let cond = ref [] in
let type_args p =
let rec aux = function [] | [_] -> [] | h :: t -> h :: aux t in
- Array.of_list (aux (CPrimitives.types p)) in
+ let params, sign = CPrimitives.types p in
+ List.length params, Array.of_list (aux sign) in
let rec aux l =
match l with
| Lprim(prefix,kn,p,args) ->
- let targs = type_args p in
+ let nparams, targs = type_args p in
let args = Array.map aux args in
- cond := add_check !cond targs args;
+ let checked_args = Array.init (Array.length args - nparams) (fun i -> args.(i+nparams)) in
+ cond := add_check !cond targs checked_args;
PAprim(prefix,kn,p,args)
| Lrel _ | Lvar _ | Luint _ | Lval _ | Lconst _ -> PAml (ml_of l)
| _ ->
@@ -1006,31 +1013,48 @@ let cast_to_int v =
| MLint _ -> v
| _ -> MLapp(MLprimitive Val_to_int, [|v|])
-let compile_prim decl cond paux =
+let ml_of_instance instance u =
+ let ml_of_level l =
+ match Univ.Level.var_index l with
+ | Some i ->
+ let univ = MLapp(MLprimitive MLmagic, [|MLlocal (Option.get instance)|]) in
+ mkMLapp (MLprimitive MLarrayget) [|univ; MLint i|]
+ | None -> let i = push_symbol (SymbLevel l) in get_level_code i
+ in
+ let u = Univ.Instance.to_array u in
+ if Array.is_empty u then [||]
+ else let u = Array.map ml_of_level u in
+ [|MLapp (MLprimitive MLmagic, [|MLarray u|])|]
+
+let compile_prim env decl cond paux =
let rec opt_prim_aux paux =
match paux with
| PAprim(_prefix, _kn, op, args) ->
- let args = Array.map opt_prim_aux args in
- app_prim (Coq_primitive(op,None)) args
+ let n = CPrimitives.nparams op in
+ let args = Array.map opt_prim_aux (Array.sub args n (Array.length args - n)) in
+ app_prim (Coq_primitive(op, false)) args
| PAml ml -> ml
and naive_prim_aux paux =
match paux with
- | PAprim(prefix, kn, op, args) ->
- app_prim (Coq_primitive(op, Some (prefix,kn))) (Array.map naive_prim_aux args)
+ | PAprim(prefix, (kn,u), op, args) ->
+ let uarg = ml_of_instance env.env_univ u in
+ let prim_const = mkMLapp (MLglobal (Gconstant(prefix,kn))) uarg in
+ let prim = mkMLapp (MLprimitive(Coq_primitive(op, true))) [|prim_const|] in
+ mkMLapp prim (Array.map naive_prim_aux args)
| PAml ml -> ml
in
let compile_cond cond paux =
match cond with
| [] -> opt_prim_aux paux
- | [CPrimitives.(PITT_type PT_int63), c1] ->
+ | [CPrimitives.(PTE PT_int63), c1] ->
MLif(app_prim Is_int [|c1|], opt_prim_aux paux, naive_prim_aux paux)
| _ ->
- let ci, cf =
+ let ci, co =
let is_int =
- function CPrimitives.(PITT_type PT_int63), _ -> true | _ -> false in
+ function CPrimitives.(PTE PT_int63), _ -> true | _ -> false in
List.partition is_int cond in
let condi =
let cond =
@@ -1038,21 +1062,25 @@ let compile_prim decl cond paux =
(fun ml (_, c) -> app_prim MLland [| ml; cast_to_int c|])
(MLint 0) ci in
app_prim MLmagic [|cond|] in
- let condf = match cf with
+ let condo = match co with
| [] -> MLint 0
- | [_, c1] -> app_prim Is_float [|c1|]
- | (_, c1) :: condf ->
+ | (CPrimitives.PTE ty, c1) :: condo ->
+ let check = match ty with
+ | CPrimitives.PT_float64 -> Is_float
+ | CPrimitives.PT_array -> Is_parray
+ | CPrimitives.PT_int63 -> assert false
+ in
List.fold_left
- (fun ml (_, c) -> app_prim MLand [| ml; app_prim Is_float [|c|]|])
- (app_prim Is_float [|c1|]) condf in
- match ci, cf with
+ (fun ml (_, c) -> app_prim MLand [| ml; app_prim check [|c|]|])
+ (app_prim check [|c1|]) condo in
+ match ci, co with
| [], [] -> opt_prim_aux paux
| _ :: _, [] ->
MLif(condi, naive_prim_aux paux, opt_prim_aux paux)
| [], _ :: _ ->
- MLif(condf, opt_prim_aux paux, naive_prim_aux paux)
+ MLif(condo, opt_prim_aux paux, naive_prim_aux paux)
| _ :: _, _ :: _ ->
- let cond = app_prim MLand [|condf; app_prim MLnot [|condi|]|] in
+ let cond = app_prim MLand [|condo; app_prim MLnot [|condi|]|] in
MLif(cond, opt_prim_aux paux, naive_prim_aux paux) in
let add_decl decl body =
@@ -1065,19 +1093,6 @@ let compile_prim decl cond paux =
else
add_decl decl (compile_cond cond paux)
-let ml_of_instance instance u =
- let ml_of_level l =
- match Univ.Level.var_index l with
- | Some i ->
- let univ = MLapp(MLprimitive MLmagic, [|MLlocal (Option.get instance)|]) in
- mkMLapp (MLprimitive MLarrayget) [|univ; MLint i|]
- | None -> let i = push_symbol (SymbLevel l) in get_level_code i
- in
- let u = Univ.Instance.to_array u in
- if Array.is_empty u then [||]
- else let u = Array.map ml_of_level u in
- [|MLapp (MLprimitive MLmagic, [|MLarray u|])|]
-
let rec ml_of_lam env l t =
match t with
| Lrel(id ,i) -> get_rel env id i
@@ -1118,7 +1133,7 @@ let ml_of_instance instance u =
| Lproj (prefix, ind, i) -> MLglobal(Gproj (prefix, ind, i))
| Lprim _ ->
let decl,cond,paux = extract_prim (ml_of_lam env l) t in
- compile_prim decl cond paux
+ compile_prim env decl cond paux
| Lcase (annot,p,a,bs) ->
(* let predicate_uid fv_pred = compilation of p
let rec case_uid fv a_uid =
@@ -1333,6 +1348,9 @@ let ml_of_instance instance u =
MLconstruct(prefix,cn,tag,args)
| Luint i -> MLapp(MLprimitive Mk_uint, [|MLuint i|])
| Lfloat f -> MLapp(MLprimitive Mk_float, [|MLfloat f|])
+ | Lparray (t,def) ->
+ let def = ml_of_lam env l def in
+ MLapp(MLprimitive MLparray_of_array, [| MLarray (Array.map (ml_of_lam env l) t); def |])
| Lval v ->
let i = push_symbol (SymbValue v) in get_value_code i
| Lsort s ->
@@ -1777,6 +1795,7 @@ let pp_mllam fmt l =
| Mk_proj -> Format.fprintf fmt "mk_proj_accu"
| Is_int -> Format.fprintf fmt "is_int"
| Is_float -> Format.fprintf fmt "is_float"
+ | Is_parray -> Format.fprintf fmt "is_parray"
| Cast_accu -> Format.fprintf fmt "cast_accu"
| Upd_cofix -> Format.fprintf fmt "upd_cofix"
| Force_cofix -> Format.fprintf fmt "force_cofix"
@@ -1803,11 +1822,10 @@ let pp_mllam fmt l =
| MLmagic -> Format.fprintf fmt "Obj.magic"
| MLarrayget -> Format.fprintf fmt "Array.get"
| Mk_empty_instance -> Format.fprintf fmt "Univ.Instance.empty"
- | Coq_primitive (op,None) ->
+ | MLparray_of_array -> Format.fprintf fmt "parray_of_array"
+ | Coq_primitive (op, false) ->
Format.fprintf fmt "no_check_%s" (CPrimitives.to_string op)
- | Coq_primitive (op, Some (prefix,(c,_))) ->
- Format.fprintf fmt "%s %a" (CPrimitives.to_string op)
- pp_mllam (MLglobal (Gconstant (prefix,c)))
+ | Coq_primitive (op, true) -> Format.fprintf fmt "%s" (CPrimitives.to_string op)
in
Format.fprintf fmt "@[%a@]" pp_mllam l