aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/byterun/coq_interp.c183
-rw-r--r--kernel/byterun/coq_memory.h2
-rw-r--r--kernel/byterun/coq_uint63_emul.h135
-rw-r--r--kernel/byterun/coq_uint63_native.h50
-rw-r--r--kernel/nativecode.ml289
-rw-r--r--kernel/nativeconv.ml23
-rw-r--r--kernel/nativelambda.ml180
-rw-r--r--kernel/nativelambda.mli14
-rw-r--r--kernel/nativelib.ml25
-rw-r--r--kernel/nativelib.mli11
10 files changed, 535 insertions, 377 deletions
diff --git a/kernel/byterun/coq_interp.c b/kernel/byterun/coq_interp.c
index d2c88bffcc..2293ae9dfd 100644
--- a/kernel/byterun/coq_interp.c
+++ b/kernel/byterun/coq_interp.c
@@ -193,6 +193,12 @@ if (sp - num_args < coq_stack_threshold) { \
#define AllocCarry(cond) Alloc_small(accu, 1, (cond)? coq_tag_C1 : coq_tag_C0)
#define AllocPair() Alloc_small(accu, 2, coq_tag_pair)
+#define Swap_accu_sp do{ \
+ value swap_accu_sp_tmp__ = accu; \
+ accu = *sp; \
+ *sp = swap_accu_sp_tmp__; \
+ }while(0)
+
/* For signal handling, we hijack some code from the caml runtime */
extern intnat caml_signals_are_pending;
@@ -1213,7 +1219,7 @@ value coq_interprete
/* Adds the integer in the accumulator with
the one ontop of the stack (which is poped)*/
print_instr("ADDINT63");
- accu = uint63_add(accu, *sp++);
+ Uint63_add(accu, *sp++);
Next;
}
@@ -1221,10 +1227,12 @@ value coq_interprete
print_instr("CHECKADDCINT63");
CheckInt2();
/* returns the sum with a carry */
- value s;
- s = uint63_add(accu, *sp++);
- AllocCarry(uint63_lt(s,accu));
- Field(accu, 0) = s;
+ int c;
+ Uint63_add(accu, *sp);
+ Uint63_lt(c, accu, *sp);
+ Swap_accu_sp;
+ AllocCarry(c);
+ Field(accu, 0) = *sp++;
Next;
}
@@ -1232,10 +1240,12 @@ value coq_interprete
print_instr("ADDCARRYCINT63");
CheckInt2();
/* returns the sum plus one with a carry */
- value s;
- s = uint63_addcarry(accu, *sp++);
- AllocCarry(uint63_leq(s, accu));
- Field(accu, 0) = s;
+ int c;
+ Uint63_addcarry(accu, *sp);
+ Uint63_leq(c, accu, *sp);
+ Swap_accu_sp;
+ AllocCarry(c);
+ Field(accu, 0) = *sp++;
Next;
}
@@ -1246,7 +1256,7 @@ value coq_interprete
Instruct (SUBINT63) {
print_instr("SUBINT63");
/* returns the subtraction */
- accu = uint63_sub(accu, *sp++);
+ Uint63_sub(accu, *sp++);
Next;
}
@@ -1254,12 +1264,12 @@ value coq_interprete
print_instr("SUBCINT63");
CheckInt2();
/* returns the subtraction with a carry */
- value b;
- value s;
- b = *sp++;
- s = uint63_sub(accu,b);
- AllocCarry(uint63_lt(accu,b));
- Field(accu, 0) = s;
+ int c;
+ Uint63_lt(c, accu, *sp);
+ Uint63_sub(accu, *sp);
+ Swap_accu_sp;
+ AllocCarry(c);
+ Field(accu, 0) = *sp++;
Next;
}
@@ -1267,12 +1277,12 @@ value coq_interprete
print_instr("SUBCARRYCINT63");
CheckInt2();
/* returns the subtraction minus one with a carry */
- value b;
- value s;
- b = *sp++;
- s = uint63_subcarry(accu,b);
- AllocCarry(uint63_leq(accu,b));
- Field(accu, 0) = s;
+ int c;
+ Uint63_leq(c,accu,*sp);
+ Uint63_subcarry(accu,*sp);
+ Swap_accu_sp;
+ AllocCarry(c);
+ Field(accu, 0) = *sp++;
Next;
}
@@ -1280,7 +1290,7 @@ value coq_interprete
print_instr("MULINT63");
CheckInt2();
/* returns the multiplication */
- accu = uint63_mul(accu,*sp++);
+ Uint63_mul(accu,*sp++);
Next;
}
@@ -1294,9 +1304,11 @@ value coq_interprete
AllocPair(); */
/* Field(accu, 0) = (value)(I64_lsr(p,31)|1) ; */ /*higher part*/
/* Field(accu, 1) = (value)(I64_to_int32(p)|1); */ /*lower part*/
- value x = accu;
+ Uint63_mulc(accu, *sp, sp);
+ *--sp = accu;
AllocPair();
- Field(accu, 1) = uint63_mulc(x, *sp++, &Field(accu, 0));
+ Field(accu, 1) = *sp++;
+ Field(accu, 0) = *sp++;
Next;
}
@@ -1306,13 +1318,13 @@ value coq_interprete
/* spiwack: a priori no need of the NON_STANDARD_DIV_MOD flag
since it probably only concerns negative number.
needs to be checked at this point */
- value divisor;
- divisor = *sp++;
- if (uint63_eq0(divisor)) {
- accu = divisor;
+ int b;
+ Uint63_eq0(b, *sp);
+ if (b) {
+ accu = *sp++;
}
else {
- accu = uint63_div(accu, divisor);
+ Uint63_div(accu, *sp++);
}
Next;
}
@@ -1320,13 +1332,13 @@ value coq_interprete
Instruct(CHECKMODINT63) {
print_instr("CHEKMODINT63");
CheckInt2();
- value divisor;
- divisor = *sp++;
- if (uint63_eq0(divisor)) {
- accu = divisor;
+ int b;
+ Uint63_eq0(b, *sp);
+ if (b) {
+ accu = *sp++;
}
else {
- accu = uint63_mod(accu,divisor);
+ Uint63_mod(accu,*sp++);
}
Next;
}
@@ -1337,19 +1349,24 @@ value coq_interprete
/* spiwack: a priori no need of the NON_STANDARD_DIV_MOD flag
since it probably only concerns negative number.
needs to be checked at this point */
- value divisor;
- divisor = *sp++;
- if (uint63_eq0(divisor)) {
- Alloc_small(accu, 2, 1); /* ( _ , arity, tag ) */
- Field(accu, 0) = divisor;
- Field(accu, 1) = divisor;
+ int b;
+ Uint63_eq0(b, *sp);
+ if (b) {
+ AllocPair();
+ Field(accu, 0) = *sp;
+ Field(accu, 1) = *sp++;
}
else {
- value modulus;
- modulus = accu;
- Alloc_small(accu, 2, 1); /* ( _ , arity, tag ) */
- Field(accu, 0) = uint63_div(modulus,divisor);
- Field(accu, 1) = uint63_mod(modulus,divisor);
+ *--sp = accu;
+ Uint63_div(sp[0],sp[1]);
+ Swap_accu_sp;
+ Uint63_mod(accu,sp[1]);
+ sp[1] = sp[0];
+ Swap_accu_sp;
+ AllocPair();
+ Field(accu, 0) = sp[1];
+ Field(accu, 1) = sp[0];
+ sp += 2;
}
Next;
}
@@ -1376,59 +1393,57 @@ value coq_interprete
Field(accu, 0) = value_of_uint32(I64_to_int32(quo));
Field(accu, 1) = value_of_uint32(I64_to_int32(mod));
} */
- value bigint; /* TODO: fix */
- bigint = *sp++; /* TODO: take accu into account */
- value divisor;
- divisor = *sp++;
- if (uint63_eq0(divisor)) {
- Alloc_small(accu, 2, 1);
- Field(accu, 0) = divisor;
- Field(accu, 1) = divisor;
+ int b;
+ Uint63_eq0(b, sp[1]);
+ if (b) {
+ AllocPair();
+ Field(accu, 0) = sp[1];
+ Field(accu, 1) = sp[1];
}
else {
- value quo, mod;
- mod = uint63_div21(accu, bigint, divisor, &quo);
- Alloc_small(accu, 2, 1);
- Field(accu, 0) = quo;
- Field(accu, 1) = mod;
+ Uint63_div21(accu, sp[0], sp[1], sp);
+ sp[1] = sp[0];
+ Swap_accu_sp;
+ AllocPair();
+ Field(accu, 0) = sp[1];
+ Field(accu, 1) = sp[0];
}
+ sp += 2;
Next;
}
Instruct(CHECKLXORINT63) {
print_instr("CHECKLXORINT63");
CheckInt2();
- accu = uint63_lxor(accu,*sp++);
+ Uint63_lxor(accu,*sp++);
Next;
}
Instruct(CHECKLORINT63) {
print_instr("CHECKLORINT63");
CheckInt2();
- accu = uint63_lor(accu,*sp++);
+ Uint63_lor(accu,*sp++);
Next;
}
Instruct(CHECKLANDINT63) {
print_instr("CHECKLANDINT63");
CheckInt2();
- accu = uint63_land(accu,*sp++);
+ Uint63_land(accu,*sp++);
Next;
}
Instruct(CHECKLSLINT63) {
print_instr("CHECKLSLINT63");
CheckInt2();
- value p = *sp++;
- accu = uint63_lsl(accu,p);
+ Uint63_lsl(accu,*sp++);
Next;
}
Instruct(CHECKLSRINT63) {
print_instr("CHECKLSRINT63");
CheckInt2();
- value p = *sp++;
- accu = uint63_lsr(accu,p);
+ Uint63_lsr(accu,*sp++);
Next;
}
@@ -1436,7 +1451,7 @@ value coq_interprete
print_instr("CHECKLSLINT63CONST1");
if (Is_uint63(accu)) {
pc++;
- accu = uint63_lsl1(accu);
+ Uint63_lsl1(accu);
Next;
} else {
*--sp = uint63_one();
@@ -1450,7 +1465,7 @@ value coq_interprete
print_instr("CHECKLSRINT63CONST1");
if (Is_uint63(accu)) {
pc++;
- accu = uint63_lsr1(accu);
+ Uint63_lsr1(accu);
Next;
} else {
*--sp = uint63_one();
@@ -1463,18 +1478,17 @@ value coq_interprete
Instruct (CHECKADDMULDIVINT63) {
print_instr("CHECKADDMULDIVINT63");
CheckInt3();
- value x;
- value y;
- x = *sp++;
- y = *sp++;
- accu = uint63_addmuldiv(accu,x,y);
+ Uint63_addmuldiv(accu,sp[0],sp[1]);
+ sp += 2;
Next;
}
Instruct (CHECKEQINT63) {
print_instr("CHECKEQINT63");
CheckInt2();
- accu = uint63_eq(accu,*sp++) ? coq_true : coq_false;
+ int b;
+ Uint63_eq(b, accu, *sp++);
+ accu = b ? coq_true : coq_false;
Next;
}
@@ -1484,7 +1498,9 @@ value coq_interprete
}
Instruct (LTINT63) {
print_instr("LTINT63");
- accu = uint63_lt(accu,*sp++) ? coq_true : coq_false;
+ int b;
+ Uint63_lt(b,accu,*sp++);
+ accu = b ? coq_true : coq_false;
Next;
}
@@ -1494,7 +1510,9 @@ value coq_interprete
}
Instruct (LEINT63) {
print_instr("LEINT63");
- accu = uint63_leq(accu,*sp++) ? coq_true : coq_false;
+ int b;
+ Uint63_leq(b,accu,*sp++);
+ accu = b ? coq_true : coq_false;
Next;
}
@@ -1503,25 +1521,30 @@ value coq_interprete
/* assumes Inductive _ : _ := Eq | Lt | Gt */
print_instr("CHECKCOMPAREINT63");
CheckInt2();
- if (uint63_eq(accu,*sp)) {
+ int b;
+ Uint63_eq(b, accu, *sp);
+ if (b) {
accu = coq_Eq;
sp++;
}
- else accu = uint63_lt(accu,*sp++) ? coq_Lt : coq_Gt;
+ else {
+ Uint63_lt(b, accu, *sp++);
+ accu = b ? coq_Lt : coq_Gt;
+ }
Next;
}
Instruct (CHECKHEAD0INT63) {
print_instr("CHECKHEAD0INT63");
CheckInt1();
- accu = uint63_head0(accu);
+ Uint63_head0(accu);
Next;
}
Instruct (CHECKTAIL0INT63) {
print_instr("CHECKTAIL0INT63");
CheckInt1();
- accu = uint63_tail0(accu);
+ Uint63_tail0(accu);
Next;
}
diff --git a/kernel/byterun/coq_memory.h b/kernel/byterun/coq_memory.h
index 9375b15de2..1ea461c5e5 100644
--- a/kernel/byterun/coq_memory.h
+++ b/kernel/byterun/coq_memory.h
@@ -19,7 +19,7 @@
#define Coq_stack_size (4096 * sizeof(value))
-#define Coq_stack_threshold (256 * sizeof(value))
+#define Coq_stack_threshold (256 * sizeof(value)) /* see kernel/cbytegen.ml */
#define Coq_max_stack_size (256 * 1024)
#define TRANSP 0
diff --git a/kernel/byterun/coq_uint63_emul.h b/kernel/byterun/coq_uint63_emul.h
index 5499f124a2..d982f67566 100644
--- a/kernel/byterun/coq_uint63_emul.h
+++ b/kernel/byterun/coq_uint63_emul.h
@@ -15,83 +15,142 @@ value uint63_##name() { \
}
# define DECLARE_UNOP(name) \
-value uint63_##name(value x) { \
+value uint63_##name##_ml(value x) { \
static value* cb = 0; \
CAMLparam1(x); \
if (!cb) cb = caml_named_value("uint63 " #name); \
CAMLreturn(caml_callback(*cb, x)); \
}
-# define DECLARE_PREDICATE(name) \
-value uint63_##name(value x) { \
- static value* cb = 0; \
- CAMLparam1(x); \
- if (!cb) cb = caml_named_value("uint63 " #name); \
- CAMLreturn(Int_val(caml_callback(*cb, x))); \
- }
+# define CALL_UNOP_NOASSIGN(name, x) \
+ value uint63_return_value__; \
+ value uint63_arg_x__ = (x); \
+ Setup_for_gc; \
+ uint63_return_value__ = uint63_##name##_ml(uint63_arg_x__); \
+ Restore_after_gc
+
+# define CALL_UNOP(name, x) do{ \
+ CALL_UNOP_NOASSIGN(name, x); \
+ accu = uint63_return_value__; \
+ }while(0)
+
+# define CALL_PREDICATE(r, name, x) do{ \
+ CALL_UNOP_NOASSIGN(name, x); \
+ (r) = Int_val(uint63_return_value__); \
+ }while(0)
# define DECLARE_BINOP(name) \
-value uint63_##name(value x, value y) { \
+value uint63_##name##_ml(value x, value y) { \
static value* cb = 0; \
CAMLparam2(x, y); \
if (!cb) cb = caml_named_value("uint63 " #name); \
CAMLreturn(caml_callback2(*cb, x, y)); \
}
-# define DECLARE_RELATION(name) \
-value uint63_##name(value x, value y) { \
- static value* cb = 0; \
- CAMLparam2(x, y); \
- if (!cb) cb = caml_named_value("uint63 " #name); \
- CAMLreturn(Int_val(caml_callback2(*cb, x, y))); \
- }
+# define CALL_BINOP_NOASSIGN(name, x, y) \
+ value uint63_return_value__; \
+ value uint63_arg_x__ = (x); \
+ value uint63_arg_y__ = (y); \
+ Setup_for_gc; \
+ uint63_return_value__ = uint63_##name##_ml(uint63_arg_x__, uint63_arg_y__); \
+ Restore_after_gc
+
+# define CALL_BINOP(name, x, y) do{ \
+ CALL_BINOP_NOASSIGN(name, x, y); \
+ accu = uint63_return_value__; \
+ }while(0)
+
+# define CALL_RELATION(r, name, x, y) do{ \
+ CALL_BINOP_NOASSIGN(name, x, y); \
+ (r) = Int_val(uint63_return_value__); \
+ }while(0)
# define DECLARE_TEROP(name) \
-value uint63_##name(value x, value y, value z) { \
+value uint63_##name##_ml(value x, value y, value z) { \
static value* cb = 0; \
CAMLparam3(x, y, z); \
if (!cb) cb = caml_named_value("uint63 " #name); \
CAMLreturn(caml_callback3(*cb, x, y, z)); \
}
+# define CALL_TEROP(name, x, y, z) do{ \
+ value uint63_return_value__; \
+ value uint63_arg_x__ = (x); \
+ value uint63_arg_y__ = (y); \
+ value uint63_arg_z__ = (z); \
+ Setup_for_gc; \
+ uint63_return_value__ = uint63_##name##_ml(uint63_arg_x__, uint63_arg_y__, uint63_arg_z__); \
+ Restore_after_gc; \
+ accu = uint63_return_value__; \
+ }while(0)
DECLARE_NULLOP(one)
DECLARE_BINOP(add)
+#define Uint63_add(x, y) CALL_BINOP(add, x, y)
DECLARE_BINOP(addcarry)
+#define Uint63_addcarry(x, y) CALL_BINOP(addcarry, x, y)
DECLARE_TEROP(addmuldiv)
+#define Uint63_addmuldiv(x, y, z) CALL_TEROP(addmuldiv, x, y, z)
DECLARE_BINOP(div)
-DECLARE_TEROP(div21_ml)
-DECLARE_RELATION(eq)
-DECLARE_PREDICATE(eq0)
+#define Uint63_div(x, y) CALL_BINOP(div, x, y)
+DECLARE_BINOP(eq)
+#define Uint63_eq(r, x, y) CALL_RELATION(r, eq, x, y)
+DECLARE_UNOP(eq0)
+#define Uint63_eq0(r, x) CALL_PREDICATE(r, eq0, x)
DECLARE_UNOP(head0)
+#define Uint63_head0(x) CALL_UNOP(head0, x)
DECLARE_BINOP(land)
-DECLARE_RELATION(leq)
+#define Uint63_land(x, y) CALL_BINOP(land, x, y)
+DECLARE_BINOP(leq)
+#define Uint63_leq(r, x, y) CALL_RELATION(r, leq, x, y)
DECLARE_BINOP(lor)
+#define Uint63_lor(x, y) CALL_BINOP(lor, x, y)
DECLARE_BINOP(lsl)
+#define Uint63_lsl(x, y) CALL_BINOP(lsl, x, y)
DECLARE_UNOP(lsl1)
+#define Uint63_lsl1(x) CALL_UNOP(lsl1, x)
DECLARE_BINOP(lsr)
+#define Uint63_lsr(x, y) CALL_BINOP(lsr, x, y)
DECLARE_UNOP(lsr1)
-DECLARE_RELATION(lt)
+#define Uint63_lsr1(x) CALL_UNOP(lsr1, x)
+DECLARE_BINOP(lt)
+#define Uint63_lt(r, x, y) CALL_RELATION(r, lt, x, y)
DECLARE_BINOP(lxor)
+#define Uint63_lxor(x, y) CALL_BINOP(lxor, x, y)
DECLARE_BINOP(mod)
+#define Uint63_mod(x, y) CALL_BINOP(mod, x, y)
DECLARE_BINOP(mul)
-DECLARE_BINOP(mulc_ml)
+#define Uint63_mul(x, y) CALL_BINOP(mul, x, y)
DECLARE_BINOP(sub)
+#define Uint63_sub(x, y) CALL_BINOP(sub, x, y)
DECLARE_BINOP(subcarry)
+#define Uint63_subcarry(x, y) CALL_BINOP(subcarry, x, y)
DECLARE_UNOP(tail0)
+#define Uint63_tail0(x) CALL_UNOP(tail0, x)
+
+DECLARE_TEROP(div21_ml)
+# define Uint63_div21(x, y, z, q) do{ \
+ value uint63_return_value__; \
+ value uint63_arg_x__ = (x); \
+ value uint63_arg_y__ = (y); \
+ value uint63_arg_z__ = (z); \
+ Setup_for_gc; \
+ uint63_return_value__ = \
+ uint63_div21_ml_ml(uint63_arg_x__, uint63_arg_y__, uint63_arg_z__); \
+ Restore_after_gc; \
+ *q = Field(uint63_return_value__, 0); \
+ accu = Field(uint63_return_value__, 1); \
+ }while(0)
-value uint63_div21(value x, value y, value z, value* q) {
- CAMLparam3(x, y, z);
- CAMLlocal1(qr);
- qr = uint63_div21_ml(x, y, z);
- *q = Field(qr, 0);
- CAMLreturn(Field(qr, 1));
-}
-
-value uint63_mulc(value x, value y, value* h) {
- CAMLparam2(x, y);
- CAMLlocal1(hl);
- hl = uint63_mulc_ml(x, y);
- *h = Field(hl, 0);
- CAMLreturn(Field(hl, 1));
-}
+DECLARE_BINOP(mulc_ml)
+# define Uint63_mulc(x, y, h) do{ \
+ value uint63_return_value__; \
+ value uint63_arg_x__ = (x); \
+ value uint63_arg_y__ = (y); \
+ Setup_for_gc; \
+ uint63_return_value__ = \
+ uint63_mulc_ml_ml(uint63_arg_x__, uint63_arg_y__); \
+ Restore_after_gc; \
+ *(h) = Field(uint63_return_value__, 0); \
+ accu = Field(uint63_return_value__, 1); \
+ }while(0)
diff --git a/kernel/byterun/coq_uint63_native.h b/kernel/byterun/coq_uint63_native.h
index 92f4dc79bc..d431dc1e5c 100644
--- a/kernel/byterun/coq_uint63_native.h
+++ b/kernel/byterun/coq_uint63_native.h
@@ -9,28 +9,43 @@
#define uint63_one() ((value) 3) /* 2*1 + 1 */
#define uint63_eq(x,y) ((x) == (y))
-#define uint63_eq0(x) ((x) == (uint64_t)1)
+#define Uint63_eq(r,x,y) ((r) = uint63_eq(x,y))
+#define Uint63_eq0(r,x) ((r) = ((x) == (uint64_t)1))
#define uint63_lt(x,y) ((uint64_t) (x) < (uint64_t) (y))
+#define Uint63_lt(r,x,y) ((r) = uint63_lt(x,y))
#define uint63_leq(x,y) ((uint64_t) (x) <= (uint64_t) (y))
+#define Uint63_leq(r,x,y) ((r) = uint63_leq(x,y))
-#define uint63_add(x,y) ((value)((uint64_t) (x) + (uint64_t) (y) - 1))
-#define uint63_addcarry(x,y) ((value)((uint64_t) (x) + (uint64_t) (y) + 1))
-#define uint63_sub(x,y) ((value)((uint64_t) (x) - (uint64_t) (y) + 1))
-#define uint63_subcarry(x,y) ((value)((uint64_t) (x) - (uint64_t) (y) - 1))
-#define uint63_mul(x,y) (Val_long(uint63_of_value(x) * uint63_of_value(y)))
-#define uint63_div(x,y) (Val_long(uint63_of_value(x) / uint63_of_value(y)))
-#define uint63_mod(x,y) (Val_long(uint63_of_value(x) % uint63_of_value(y)))
+#define Uint63_add(x,y) (accu = (value)((uint64_t) (x) + (uint64_t) (y) - 1))
+#define Uint63_addcarry(x,y) (accu = (value)((uint64_t) (x) + (uint64_t) (y) + 1))
+#define Uint63_sub(x,y) (accu = (value)((uint64_t) (x) - (uint64_t) (y) + 1))
+#define Uint63_subcarry(x,y) (accu = (value)((uint64_t) (x) - (uint64_t) (y) - 1))
+#define Uint63_mul(x,y) (accu = Val_long(uint63_of_value(x) * uint63_of_value(y)))
+#define Uint63_div(x,y) (accu = Val_long(uint63_of_value(x) / uint63_of_value(y)))
+#define Uint63_mod(x,y) (accu = Val_long(uint63_of_value(x) % uint63_of_value(y)))
-#define uint63_lxor(x,y) ((value)(((uint64_t)(x) ^ (uint64_t)(y)) | 1))
-#define uint63_lor(x,y) ((value)((uint64_t)(x) | (uint64_t)(y)))
-#define uint63_land(x,y) ((value)((uint64_t)(x) & (uint64_t)(y)))
+#define Uint63_lxor(x,y) (accu = (value)(((uint64_t)(x) ^ (uint64_t)(y)) | 1))
+#define Uint63_lor(x,y) (accu = (value)((uint64_t)(x) | (uint64_t)(y)))
+#define Uint63_land(x,y) (accu = (value)((uint64_t)(x) & (uint64_t)(y)))
/* TODO: is + or | better? OCAML uses + */
/* TODO: is - or ^ better? */
-#define uint63_lsl(x,y) ((y) < (uint64_t) 127 ? ((value)((((uint64_t)(x)-1) << (uint63_of_value(y))) | 1)) : uint63_zero)
-#define uint63_lsr(x,y) ((y) < (uint64_t) 127 ? ((value)(((uint64_t)(x) >> (uint63_of_value(y))) | 1)) : uint63_zero)
-#define uint63_lsl1(x) ((value)((((uint64_t)(x)-1) << 1) +1))
-#define uint63_lsr1(x) ((value)(((uint64_t)(x) >> 1) |1))
+#define Uint63_lsl(x,y) do{ \
+ value uint63_lsl_y__ = (y); \
+ if (uint63_lsl_y__ < (uint64_t) 127) \
+ accu = (value)((((uint64_t)(x)-1) << uint63_of_value(uint63_lsl_y__)) | 1); \
+ else \
+ accu = uint63_zero; \
+ }while(0)
+#define Uint63_lsr(x,y) do{ \
+ value uint63_lsl_y__ = (y); \
+ if (uint63_lsl_y__ < (uint64_t) 127) \
+ accu = (value)(((uint64_t)(x) >> uint63_of_value(uint63_lsl_y__)) | 1); \
+ else \
+ accu = uint63_zero; \
+ }while(0)
+#define Uint63_lsl1(x) (accu = (value)((((uint64_t)(x)-1) << 1) +1))
+#define Uint63_lsr1(x) (accu = (value)(((uint64_t)(x) >> 1) |1))
/* addmuldiv(p,x,y) = x * 2^p + y / 2 ^ (63 - p) */
/* (modulo 2^63) for p <= 63 */
@@ -40,6 +55,7 @@ value uint63_addmuldiv(uint64_t p, uint64_t x, uint64_t y) {
r |= ((uint64_t)y >> (63-shiftby)) | 1;
return r;
}
+#define Uint63_addmuldiv(p, x, y) (accu = uint63_addmuldiv(p, x, y))
value uint63_head0(uint64_t x) {
int r = 0;
@@ -51,6 +67,7 @@ value uint63_head0(uint64_t x) {
if (!(x & 0x8000000000000000)) { x <<=1; r += 1; }
return Val_int(r);
}
+#define Uint63_head0(x) (accu = uint63_head0(x))
value uint63_tail0(value x) {
int r = 0;
@@ -63,6 +80,7 @@ value uint63_tail0(value x) {
if (!(x & 0x00000001)) { x >>=1; r += 1; }
return Val_int(r);
}
+#define Uint63_tail0(x) (accu = uint63_tail0(x))
value uint63_mulc(value x, value y, value* h) {
x = (uint64_t)x >> 1;
@@ -86,6 +104,7 @@ value uint63_mulc(value x, value y, value* h) {
*h = Val_int(hr);
return Val_int(lr);
}
+#define Uint63_mulc(x, y, h) (accu = uint63_mulc(x, y, h))
#define lt128(xh,xl,yh,yl) (uint63_lt(xh,yh) || (uint63_eq(xh,yh) && uint63_lt(xl,yl)))
#define le128(xh,xl,yh,yl) (uint63_lt(xh,yh) || (uint63_eq(xh,yh) && uint63_leq(xl,yl)))
@@ -123,3 +142,4 @@ value uint63_div21(value xh, value xl, value y, value* q) {
*q = Val_int(quotient);
return Val_int(reml);
}
+#define Uint63_div21(xh, xl, y, q) (accu = uint63_div21(xh, xl, y, q))
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 94ed288d2d..3f791dfc22 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -51,7 +51,6 @@ let fresh_lname n =
(** Global names **)
type gname =
| Gind of string * inductive (* prefix, inductive name *)
- | Gconstruct of string * constructor (* prefix, constructor name *)
| Gconstant of string * Constant.t (* prefix, constant name *)
| Gproj of string * inductive * int (* prefix, inductive, index (start from 0) *)
| Gcase of Label.t option * int
@@ -67,8 +66,6 @@ let eq_gname gn1 gn2 =
match gn1, gn2 with
| Gind (s1, ind1), Gind (s2, ind2) ->
String.equal s1 s2 && eq_ind ind1 ind2
- | Gconstruct (s1, c1), Gconstruct (s2, c2) ->
- String.equal s1 s2 && eq_constructor c1 c2
| Gconstant (s1, c1), Gconstant (s2, c2) ->
String.equal s1 s2 && Constant.equal c1 c2
| Gproj (s1, ind1, i1), Gproj (s2, ind2, i2) ->
@@ -88,7 +85,7 @@ let eq_gname gn1 gn2 =
| Ginternal s1, Ginternal s2 -> String.equal s1 s2
| Grel i1, Grel i2 -> Int.equal i1 i2
| Gnamed id1, Gnamed id2 -> Id.equal id1 id2
- | (Gind _| Gconstruct _ | Gconstant _ | Gproj _ | Gcase _ | Gpred _
+ | (Gind _| Gconstant _ | Gproj _ | Gcase _ | Gpred _
| Gfixtype _ | Gnorm _ | Gnormtbl _ | Ginternal _ | Grel _ | Gnamed _), _ ->
false
@@ -100,19 +97,17 @@ open Hashset.Combine
let gname_hash gn = match gn with
| Gind (s, ind) ->
combinesmall 1 (combine (String.hash s) (ind_hash ind))
-| Gconstruct (s, c) ->
- combinesmall 2 (combine (String.hash s) (constructor_hash c))
| Gconstant (s, c) ->
- combinesmall 3 (combine (String.hash s) (Constant.hash c))
-| Gcase (l, i) -> combinesmall 4 (combine (Option.hash Label.hash l) (Int.hash i))
-| Gpred (l, i) -> combinesmall 5 (combine (Option.hash Label.hash l) (Int.hash i))
-| Gfixtype (l, i) -> combinesmall 6 (combine (Option.hash Label.hash l) (Int.hash i))
-| Gnorm (l, i) -> combinesmall 7 (combine (Option.hash Label.hash l) (Int.hash i))
-| Gnormtbl (l, i) -> combinesmall 8 (combine (Option.hash Label.hash l) (Int.hash i))
-| Ginternal s -> combinesmall 9 (String.hash s)
-| Grel i -> combinesmall 10 (Int.hash i)
-| Gnamed id -> combinesmall 11 (Id.hash id)
-| Gproj (s, p, i) -> combinesmall 12 (combine (String.hash s) (combine (ind_hash p) i))
+ combinesmall 2 (combine (String.hash s) (Constant.hash c))
+| Gcase (l, i) -> combinesmall 3 (combine (Option.hash Label.hash l) (Int.hash i))
+| Gpred (l, i) -> combinesmall 4 (combine (Option.hash Label.hash l) (Int.hash i))
+| Gfixtype (l, i) -> combinesmall 5 (combine (Option.hash Label.hash l) (Int.hash i))
+| Gnorm (l, i) -> combinesmall 6 (combine (Option.hash Label.hash l) (Int.hash i))
+| Gnormtbl (l, i) -> combinesmall 7 (combine (Option.hash Label.hash l) (Int.hash i))
+| Ginternal s -> combinesmall 8 (String.hash s)
+| Grel i -> combinesmall 9 (Int.hash i)
+| Gnamed id -> combinesmall 10 (Id.hash id)
+| Gproj (s, p, i) -> combinesmall 11 (combine (String.hash s) (combine (ind_hash p) i))
let case_ctr = ref (-1)
@@ -382,8 +377,8 @@ type mllambda =
| MLif of mllambda * mllambda * mllambda
| MLmatch of annot_sw * mllambda * mllambda * mllam_branches
(* argument, prefix, accu branch, branches *)
- | MLconstruct of string * constructor * mllambda array
- (* prefix, constructor name, arguments *)
+ | MLconstruct of string * inductive * int * mllambda array
+ (* prefix, inductive name, tag, arguments *)
| MLint of int
| MLuint of Uint63.t
| MLsetref of string * mllambda
@@ -391,7 +386,11 @@ type mllambda =
| MLarray of mllambda array
| MLisaccu of string * inductive * mllambda
-and mllam_branches = ((constructor * lname option array) list * mllambda) array
+and 'a mllam_pattern =
+ | ConstPattern of int
+ | NonConstPattern of tag * 'a array
+
+and mllam_branches = (lname option mllam_pattern list * mllambda) array
let push_lnames n env lns =
snd (Array.fold_left (fun (i,r) x -> (i+1, LNmap.add x i r)) (n,env) lns)
@@ -444,9 +443,10 @@ let rec eq_mllambda gn1 gn2 n env1 env2 t1 t2 =
eq_mllambda gn1 gn2 n env1 env2 c1 c2 &&
eq_mllambda gn1 gn2 n env1 env2 accu1 accu2 &&
eq_mllam_branches gn1 gn2 n env1 env2 br1 br2
- | MLconstruct (pf1, cs1, args1), MLconstruct (pf2, cs2, args2) ->
+ | MLconstruct (pf1, ind1, tag1, args1), MLconstruct (pf2, ind2, tag2, args2) ->
String.equal pf1 pf2 &&
- eq_constructor cs1 cs2 &&
+ eq_ind ind1 ind2 &&
+ Int.equal tag1 tag2 &&
Array.equal (eq_mllambda gn1 gn2 n env1 env2) args1 args2
| MLint i1, MLint i2 ->
Int.equal i1 i2
@@ -479,15 +479,22 @@ and eq_letrec gn1 gn2 n env1 env2 defs1 defs2 =
(* we require here that patterns have the same order, which may be too strong *)
and eq_mllam_branches gn1 gn2 n env1 env2 br1 br2 =
- let eq_cargs (cs1, args1) (cs2, args2) body1 body2 =
+ let eq_cargs args1 args2 body1 body2 =
Int.equal (Array.length args1) (Array.length args2) &&
- eq_constructor cs1 cs2 &&
let env1 = opush_lnames n env1 args1 in
let env2 = opush_lnames n env2 args2 in
eq_mllambda gn1 gn2 (n + Array.length args1) env1 env2 body1 body2
in
- let eq_branch (ptl1,body1) (ptl2,body2) =
- List.equal (fun pt1 pt2 -> eq_cargs pt1 pt2 body1 body2) ptl1 ptl2
+ let eq_pattern pat1 pat2 body1 body2 =
+ match pat1, pat2 with
+ | ConstPattern tag1, ConstPattern tag2 ->
+ Int.equal tag1 tag2 && eq_mllambda gn1 gn2 n env1 env2 body1 body2
+ | NonConstPattern (tag1,args1), NonConstPattern (tag2,args2) ->
+ Int.equal tag1 tag2 && eq_cargs args1 args2 body1 body2
+ | (ConstPattern _ | NonConstPattern _), _ -> false
+ in
+ let eq_branch (patl1,body1) (patl2,body2) =
+ List.equal (fun pt1 pt2 -> eq_pattern pt1 pt2 body1 body2) patl1 patl2
in
Array.equal eq_branch br1 br2
@@ -523,10 +530,11 @@ let rec hash_mllambda gn n env t =
let hc = hash_mllambda gn n env c in
let haccu = hash_mllambda gn n env accu in
combinesmall 9 (hash_mllam_branches gn n env (combine3 hannot hc haccu) br)
- | MLconstruct (pf, cs, args) ->
+ | MLconstruct (pf, ind, tag, args) ->
let hpf = String.hash pf in
- let hcs = constructor_hash cs in
- combinesmall 10 (hash_mllambda_array gn n env (combine hpf hcs) args)
+ let hcs = ind_hash ind in
+ let htag = Int.hash tag in
+ combinesmall 10 (hash_mllambda_array gn n env (combine3 hpf hcs htag) args)
| MLint i ->
combinesmall 11 i
| MLuint i ->
@@ -556,15 +564,18 @@ and hash_mllambda_array gn n env init arr =
Array.fold_left (fun acc t -> combine (hash_mllambda gn n env t) acc) init arr
and hash_mllam_branches gn n env init br =
- let hash_cargs (cs, args) body =
+ let hash_cargs args body =
let nargs = Array.length args in
- let hcs = constructor_hash cs in
let env = opush_lnames n env args in
let hbody = hash_mllambda gn (n + nargs) env body in
- combine3 nargs hcs hbody
+ combine nargs hbody
+ in
+ let hash_pattern pat body = match pat with
+ | ConstPattern i -> combinesmall 1 (Int.hash i)
+ | NonConstPattern (tag,args) -> combinesmall 2 (combine (Int.hash tag) (hash_cargs args body))
in
let hash_branch acc (ptl,body) =
- List.fold_left (fun acc t -> combine (hash_cargs t body) acc) acc ptl
+ List.fold_left (fun acc t -> combine (hash_pattern t body) acc) acc ptl
in
Array.fold_left hash_branch init br
@@ -594,17 +605,20 @@ let fv_lam l =
| MLmatch(_,a,p,bs) ->
let fv = aux a bind (aux p bind fv) in
let fv_bs (cargs, body) fv =
- let bind =
- List.fold_right (fun (_,args) bind ->
- Array.fold_right
- (fun o bind -> match o with
- | Some l -> LNset.add l bind
- | _ -> bind) args bind)
- cargs bind in
- aux body bind fv in
+ let bind =
+ List.fold_right (fun pat bind ->
+ match pat with
+ | ConstPattern _ -> bind
+ | NonConstPattern(_,args) ->
+ Array.fold_right
+ (fun o bind -> match o with
+ | Some l -> LNset.add l bind
+ | _ -> bind) args bind)
+ cargs bind in
+ aux body bind fv in
Array.fold_right fv_bs bs fv
- (* argument, accu branch, branches *)
- | MLconstruct (_,_,p) ->
+ (* argument, accu branch, branches *)
+ | MLconstruct (_,_,_,p) ->
Array.fold_right (fun a fv -> aux a bind fv) p fv
| MLsetref(_,l) -> aux l bind fv
| MLsequence(l1,l2) -> aux l1 bind (aux l2 bind fv)
@@ -652,8 +666,8 @@ type global =
| Gletcase of
gname * lname array * annot_sw * mllambda * mllambda * mllam_branches
| Gopen of string
- | Gtype of inductive * int array
- (* ind name, arities of constructors *)
+ | Gtype of inductive * (tag * int) array
+ (* ind name, tag and arities of constructors *)
| Gcomment of string
(* Alpha-equivalence on globals *)
@@ -678,7 +692,8 @@ let eq_global g1 g2 =
eq_mllambda gn1 gn2 (Array.length lns1) env1 env2 t1 t2
| Gopen s1, Gopen s2 -> String.equal s1 s2
| Gtype (ind1, arr1), Gtype (ind2, arr2) ->
- eq_ind ind1 ind2 && Array.equal Int.equal arr1 arr2
+ eq_ind ind1 ind2 &&
+ Array.equal (fun (tag1,ar1) (tag2,ar2) -> Int.equal tag1 tag2 && Int.equal ar1 ar2) arr1 arr2
| Gcomment s1, Gcomment s2 -> String.equal s1 s2
| _, _ -> false
@@ -705,7 +720,10 @@ let hash_global g =
combinesmall 4 (combine nlns (hash_mllambda gn nlns env t))
| Gopen s -> combinesmall 5 (String.hash s)
| Gtype (ind, arr) ->
- combinesmall 6 (combine (ind_hash ind) (Array.fold_left combine 0 arr))
+ let hash_aux acc (tag,ar) =
+ combine3 acc (Int.hash tag) (Int.hash ar)
+ in
+ combinesmall 6 (combine (ind_hash ind) (Array.fold_left hash_aux 0 arr))
| Gcomment s -> combinesmall 7 (String.hash s)
let global_stack = ref ([] : global list)
@@ -912,26 +930,33 @@ let get_proj_code i =
[|MLglobal symbols_tbl_name; MLint i|])
type rlist =
- | Rnil
- | Rcons of (constructor * lname option array) list ref * LNset.t * mllambda * rlist'
+ | Rnil
+ | Rcons of lname option mllam_pattern list ref * LNset.t * mllambda * rlist'
and rlist' = rlist ref
-let rm_params fv params =
- Array.map (fun l -> if LNset.mem l fv then Some l else None) params
+let rm_params fv params =
+ Array.map (fun l -> if LNset.mem l fv then Some l else None) params
-let rec insert cargs body rl =
+let rec insert pat body rl =
match !rl with
| Rnil ->
let fv = fv_lam body in
- let (c,params) = cargs in
- let params = rm_params fv params in
- rl:= Rcons(ref [(c,params)], fv, body, ref Rnil)
+ begin match pat with
+ | ConstPattern _ as p ->
+ rl:= Rcons(ref [p], fv, body, ref Rnil)
+ | NonConstPattern (tag,args) ->
+ let args = rm_params fv args in
+ rl:= Rcons(ref [NonConstPattern (tag,args)], fv, body, ref Rnil)
+ end
| Rcons(l,fv,body',rl) ->
- if eq_mllambda body body' then
- let (c,params) = cargs in
- let params = rm_params fv params in
- l := (c,params)::!l
- else insert cargs body rl
+ if eq_mllambda body body' then
+ match pat with
+ | ConstPattern _ as p ->
+ l := p::!l
+ | NonConstPattern (tag,args) ->
+ let args = rm_params fv args in
+ l := NonConstPattern (tag,args)::!l
+ else insert pat body rl
let rec to_list rl =
match !rl with
@@ -940,7 +965,7 @@ let rec to_list rl =
let merge_branches t =
let newt = ref Rnil in
- Array.iter (fun (c,args,body) -> insert (c,args) body newt) t;
+ Array.iter (fun (pat,body) -> insert pat body newt) t;
Array.of_list (to_list newt)
let app_prim p args = MLapp(MLprimitive p, args)
@@ -1097,14 +1122,19 @@ let ml_of_instance instance u =
let a_uid = fresh_lname Anonymous in
let la_uid = MLlocal a_uid in
(* compilation of branches *)
- let ml_br (c,params, body) =
- let lnames, env_c = push_rels env_c params in
- (c, lnames, ml_of_lam env_c l body)
+ let nbconst = Array.length bs.constant_branches in
+ let nbtotal = nbconst + Array.length bs.nonconstant_branches in
+ let br = Array.init nbtotal (fun i -> if i < Array.length bs.constant_branches then
+ (ConstPattern i, ml_of_lam env_c l bs.constant_branches.(i))
+ else
+ let (params, body) = bs.nonconstant_branches.(i-nbconst) in
+ let lnames, env_c = push_rels env_c params in
+ (NonConstPattern (i-nbconst+1,lnames), ml_of_lam env_c l body)
+ )
in
- let bs = Array.map ml_br bs in
let cn = fresh_gcase l in
(* Compilation of accu branch *)
- let pred = MLapp(MLglobal pn, fv_args env_c pfvn pfvr) in
+ let pred = MLapp(MLglobal pn, fv_args env_c pfvn pfvr) in
let (fvn, fvr) = !(env_c.env_named), !(env_c.env_urel) in
let cn_fv = mkMLapp (MLglobal cn) (fv_args env_c fvn fvr) in
(* remark : the call to fv_args does not add free variables in env_c *)
@@ -1117,7 +1147,7 @@ let ml_of_instance instance u =
(* let body = MLlam([|a_uid|], MLmatch(annot, la_uid, accu, bs)) in
let case = generalize_fv env_c body in *)
let cn = push_global_case cn (Array.append (fv_params env_c) [|a_uid|])
- annot la_uid accu (merge_branches bs)
+ annot la_uid accu (merge_branches br)
in
(* Final result *)
let arg = ml_of_lam env l a in
@@ -1277,12 +1307,11 @@ let ml_of_instance instance u =
(lname, paramsi, body) in
MLletrec(Array.mapi mkrec lf, lf_args.(start)) *)
- | Lmakeblock (prefix,(cn,_u),_,args) ->
+ | Lint tag -> MLapp(MLprimitive Mk_int, [|MLint tag|])
+
+ | Lmakeblock (prefix,cn,tag,args) ->
let args = Array.map (ml_of_lam env l) args in
- MLconstruct(prefix,cn,args)
- | Lconstruct (prefix, (cn,u)) ->
- let uargs = ml_of_instance env.env_univ u in
- mkMLapp (MLglobal (Gconstruct (prefix, cn))) uargs
+ MLconstruct(prefix,cn,tag,args)
| Luint i -> MLapp(MLprimitive Mk_uint, [|MLuint i|])
| Lval v ->
let i = push_symbol (SymbValue v) in get_value_code i
@@ -1345,7 +1374,7 @@ let subst s l =
| MLmatch(annot,a,accu,bs) ->
let auxb (cargs,body) = (cargs,aux body) in
MLmatch(annot,a,aux accu, Array.map auxb bs)
- | MLconstruct(prefix,c,args) -> MLconstruct(prefix,c,Array.map aux args)
+ | MLconstruct(prefix,c,tag,args) -> MLconstruct(prefix,c,tag,Array.map aux args)
| MLsetref(s,l1) -> MLsetref(s,aux l1)
| MLsequence(l1,l2) -> MLsequence(aux l1, aux l2)
| MLarray arr -> MLarray (Array.map aux arr)
@@ -1454,8 +1483,8 @@ let optimize gdef l =
| MLmatch(annot,a,accu,bs) ->
let opt_b (cargs,body) = (cargs,optimize s body) in
MLmatch(annot, optimize s a, subst s accu, Array.map opt_b bs)
- | MLconstruct(prefix,c,args) ->
- MLconstruct(prefix,c,Array.map (optimize s) args)
+ | MLconstruct(prefix,c,tag,args) ->
+ MLconstruct(prefix,c,tag,Array.map (optimize s) args)
| MLsetref(r,l) -> MLsetref(r, optimize s l)
| MLsequence(l1,l2) -> MLsequence(optimize s l1, optimize s l2)
| MLarray arr -> MLarray (Array.map (optimize s) arr)
@@ -1528,13 +1557,12 @@ let string_of_kn kn =
let string_of_con c = string_of_kn (Constant.user c)
let string_of_mind mind = string_of_kn (MutInd.user mind)
+let string_of_ind (mind,i) = string_of_kn (MutInd.user mind) ^ "_" ^ string_of_int i
let string_of_gname g =
match g with
| Gind (prefix, (mind, i)) ->
Format.sprintf "%sindaccu_%s_%i" prefix (string_of_mind mind) i
- | Gconstruct (prefix, ((mind, i), j)) ->
- Format.sprintf "%sconstruct_%s_%i_%i" prefix (string_of_mind mind) i (j-1)
| Gconstant (prefix, c) ->
Format.sprintf "%sconst_%s" prefix (string_of_con c)
| Gproj (prefix, (mind, n), i) ->
@@ -1567,10 +1595,13 @@ let pp_ldecls fmt ids =
Format.fprintf fmt " (%a : Nativevalues.t)" pp_lname ids.(i)
done
-let string_of_construct prefix ((mind,i),j) =
- let id = Format.sprintf "Construct_%s_%i_%i" (string_of_mind mind) i (j-1) in
- prefix ^ id
-
+let string_of_construct prefix ~constant ind tag =
+ let base = if constant then "Int" else "Construct" in
+ Format.sprintf "%s%s_%s_%i" prefix base (string_of_ind ind) tag
+
+let string_of_accu_construct prefix ind =
+ Format.sprintf "%sAccu_%s" prefix (string_of_ind ind)
+
let pp_int fmt i =
if i < 0 then Format.fprintf fmt "(%i)" i else Format.fprintf fmt "%i" i
@@ -1596,16 +1627,16 @@ let pp_mllam fmt l =
Format.fprintf fmt "@[(if %a then@\n %a@\nelse@\n %a)@]"
pp_mllam t pp_mllam l1 pp_mllam l2
| MLmatch (annot, c, accu_br, br) ->
- let mind,i = annot.asw_ind in
+ let ind = annot.asw_ind in
let prefix = annot.asw_prefix in
- let accu = Format.sprintf "%sAccu_%s_%i" prefix (string_of_mind mind) i in
- Format.fprintf fmt
- "@[begin match Obj.magic (%a) with@\n| %s _ ->@\n %a@\n%aend@]"
- pp_mllam c accu pp_mllam accu_br (pp_branches prefix) br
-
- | MLconstruct(prefix,c,args) ->
+ let accu = string_of_accu_construct prefix ind in
+ Format.fprintf fmt
+ "@[begin match Obj.magic (%a) with@\n| %s _ ->@\n %a@\n%aend@]"
+ pp_mllam c accu pp_mllam accu_br (pp_branches prefix ind) br
+
+ | MLconstruct(prefix,ind,tag,args) ->
Format.fprintf fmt "@[(Obj.magic (%s%a) : Nativevalues.t)@]"
- (string_of_construct prefix c) pp_cargs args
+ (string_of_construct prefix ~constant:false ind tag) pp_cargs args
| MLint i -> pp_int fmt i
| MLuint i -> Format.fprintf fmt "(%s)" (Uint63.compile i)
| MLsetref (s, body) ->
@@ -1622,8 +1653,8 @@ let pp_mllam fmt l =
pp_mllam fmt arr.(len-1)
end;
Format.fprintf fmt "|]@]"
- | MLisaccu (prefix, (mind, i), c) ->
- let accu = Format.sprintf "%sAccu_%s_%i" prefix (string_of_mind mind) i in
+ | MLisaccu (prefix, ind, c) ->
+ let accu = string_of_accu_construct prefix ind in
Format.fprintf fmt
"@[begin match Obj.magic (%a) with@\n| %s _ ->@\n true@\n| _ ->@\n false@\nend@]"
pp_mllam c accu
@@ -1646,7 +1677,7 @@ let pp_mllam fmt l =
| MLprimitive (Mk_prod | Mk_sort) (* FIXME: why this special case? *)
| MLlam _ | MLletrec _ | MLlet _ | MLapp _ | MLif _ ->
Format.fprintf fmt "(%a)" pp_mllam l
- | MLconstruct(_,_,args) when Array.length args > 0 ->
+ | MLconstruct(_,_,_,args) when Array.length args > 0 ->
Format.fprintf fmt "(%a)" pp_mllam l
| _ -> pp_mllam fmt l
@@ -1685,19 +1716,23 @@ let pp_mllam fmt l =
done in
Format.fprintf fmt "(%a)" aux params
- and pp_branches prefix fmt bs =
+ and pp_branches prefix ind fmt bs =
let pp_branch (cargs,body) =
- let pp_c fmt (cn,args) =
- Format.fprintf fmt "| %s%a "
- (string_of_construct prefix cn) pp_cparams args in
- let rec pp_cargs fmt cargs =
- match cargs with
- | [] -> ()
- | cargs::cargs' ->
- Format.fprintf fmt "%a%a" pp_c cargs pp_cargs cargs' in
- Format.fprintf fmt "%a ->@\n %a@\n"
- pp_cargs cargs pp_mllam body
+ let pp_pat fmt = function
+ | ConstPattern i ->
+ Format.fprintf fmt "| %s "
+ (string_of_construct prefix ~constant:true ind i)
+ | NonConstPattern (tag,args) ->
+ Format.fprintf fmt "| %s%a "
+ (string_of_construct prefix ~constant:false ind tag) pp_cparams args in
+ let rec pp_pats fmt pats =
+ match pats with
+ | [] -> ()
+ | pat::pats ->
+ Format.fprintf fmt "%a%a" pp_pat pat pp_pats pats
in
+ Format.fprintf fmt "%a ->@\n %a@\n" pp_pats cargs pp_mllam body
+ in
Array.iter pp_branch bs
and pp_primitive fmt = function
@@ -1771,19 +1806,24 @@ let pp_global fmt g =
pp_mllam c
| Gopen s ->
Format.fprintf fmt "@[open %s@]@." s
- | Gtype ((mind, i), lar) ->
- let l = string_of_mind mind in
- let rec aux s ar =
- if Int.equal ar 0 then s else aux (s^" * Nativevalues.t") (ar-1) in
- let pp_const_sig i fmt j ar =
- let sig_str = if ar > 0 then aux "of Nativevalues.t" (ar-1) else "" in
- Format.fprintf fmt " | Construct_%s_%i_%i %s@\n" l i j sig_str
- in
- let pp_const_sigs i fmt lar =
- Format.fprintf fmt " | Accu_%s_%i of Nativevalues.t@\n" l i;
- Array.iteri (pp_const_sig i fmt) lar
- in
- Format.fprintf fmt "@[type ind_%s_%i =@\n%a@]@\n@." l i (pp_const_sigs i) lar
+ | Gtype (ind, lar) ->
+ let rec aux s arity =
+ if Int.equal arity 0 then s else aux (s^" * Nativevalues.t") (arity-1) in
+ let pp_const_sig fmt (tag,arity) =
+ if arity > 0 then
+ let sig_str = aux "of Nativevalues.t" (arity-1) in
+ let cstr = string_of_construct "" ~constant:false ind tag in
+ Format.fprintf fmt " | %s %s@\n" cstr sig_str
+ else
+ let sig_str = if arity > 0 then aux "of Nativevalues.t" (arity-1) else "" in
+ let cstr = string_of_construct "" ~constant:true ind tag in
+ Format.fprintf fmt " | %s %s@\n" cstr sig_str
+ in
+ let pp_const_sigs fmt lar =
+ Format.fprintf fmt " | %s of Nativevalues.t@\n" (string_of_accu_construct "" ind);
+ Array.iter (pp_const_sig fmt) lar
+ in
+ Format.fprintf fmt "@[type ind_%s =@\n%a@]@\n@." (string_of_ind ind) pp_const_sigs lar
| Gtblfixtype (g, params, t) ->
Format.fprintf fmt "@[let %a %a =@\n %a@]@\n@." pp_gname g
pp_ldecls params pp_array t
@@ -1920,7 +1960,7 @@ let compile_mind mb mind stack =
(** Generate data for every block *)
let f i stack ob =
let ind = (mind, i) in
- let gtype = Gtype(ind, Array.map snd ob.mind_reloc_tbl) in
+ let gtype = Gtype(ind, ob.mind_reloc_tbl) in
let j = push_symbol (SymbInd ind) in
let name = Gind ("", ind) in
let accu =
@@ -1932,16 +1972,6 @@ let compile_mind mb mind stack =
Glet(name, MLapp (MLprimitive Mk_ind, args))
in
let nparams = mb.mind_nparams in
- let params =
- Array.init nparams (fun i -> {lname = param_name; luid = i}) in
- let add_construct j acc (_,arity) =
- let args = Array.init arity (fun k -> {lname = arg_name; luid = k}) in
- let c = ind, (j+1) in
- Glet(Gconstruct ("", c),
- mkMLlam (Array.append params args)
- (MLconstruct("", c, Array.map (fun id -> MLlocal id) args)))::acc
- in
- let constructors = Array.fold_left_i add_construct [] ob.mind_reloc_tbl in
let add_proj proj_arg acc _pb =
let tbl = ob.mind_reloc_tbl in
(* Building info *)
@@ -1953,7 +1983,8 @@ let compile_mind mb mind stack =
asw_reloc = tbl; asw_finite = true } in
let c_uid = fresh_lname Anonymous in
let cf_uid = fresh_lname Anonymous in
- let _, arity = tbl.(0) in
+ let tag, arity = tbl.(0) in
+ assert (arity > 0);
let ci_uid = fresh_lname Anonymous in
let cargs = Array.init arity
(fun i -> if Int.equal i proj_arg then Some ci_uid else None)
@@ -1961,7 +1992,7 @@ let compile_mind mb mind stack =
let i = push_symbol (SymbProj (ind, proj_arg)) in
let accu = MLapp (MLprimitive Cast_accu, [|MLlocal cf_uid|]) in
let accu_br = MLapp (MLprimitive Mk_proj, [|get_proj_code i;accu|]) in
- let code = MLmatch(asw,MLlocal cf_uid,accu_br,[|[((ind,1),cargs)],MLlocal ci_uid|]) in
+ let code = MLmatch(asw,MLlocal cf_uid,accu_br,[|[NonConstPattern (tag,cargs)],MLlocal ci_uid|]) in
let code = MLlet(cf_uid, mkForceCofix "" ind (MLlocal c_uid), code) in
let gn = Gproj ("", ind, proj_arg) in
Glet (gn, mkMLlam [|c_uid|] code) :: acc
@@ -1972,7 +2003,7 @@ let compile_mind mb mind stack =
let _, _, _, pbs = info.(i) in
Array.fold_left_i add_proj [] pbs
in
- projs @ constructors @ gtype :: accu :: stack
+ projs @ gtype :: accu :: stack
in
Array.fold_left_i f stack mb.mind_packets
diff --git a/kernel/nativeconv.ml b/kernel/nativeconv.ml
index baa290367f..d153f84e9c 100644
--- a/kernel/nativeconv.ml
+++ b/kernel/nativeconv.ml
@@ -8,7 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open CErrors
open Names
open Nativelib
open Reduction
@@ -152,19 +151,15 @@ let native_conv_gen pb sigma env univs t1 t2 =
else
let ml_filename, prefix = get_ml_filename () in
let code, upds = mk_conv_code env sigma prefix t1 t2 in
- match compile ml_filename code ~profile:false with
- | (true, fn) ->
- begin
- if !Flags.debug then Feedback.msg_debug (Pp.str "Running test...");
- let t0 = Sys.time () in
- call_linker ~fatal:true prefix fn (Some upds);
- let t1 = Sys.time () in
- let time_info = Format.sprintf "Evaluation done in %.5f@." (t1 -. t0) in
- if !Flags.debug then Feedback.msg_debug (Pp.str time_info);
- (* TODO change 0 when we can have de Bruijn *)
- fst (conv_val env pb 0 !rt1 !rt2 univs)
- end
- | _ -> anomaly (Pp.str "Compilation failure.")
+ let fn = compile ml_filename code ~profile:false in
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Running test...");
+ let t0 = Sys.time () in
+ call_linker ~fatal:true prefix fn (Some upds);
+ let t1 = Sys.time () in
+ let time_info = Format.sprintf "Evaluation done in %.5f@." (t1 -. t0) in
+ if !Flags.debug then Feedback.msg_debug (Pp.str time_info);
+ (* TODO change 0 when we can have de Bruijn *)
+ fst (conv_val env pb 0 !rt1 !rt2 univs)
(* Wrapper for [native_conv] above *)
let native_conv cv_pb sigma env t1 t2 =
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index ec3a7b893d..62afd9df68 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -39,11 +39,10 @@ type lambda =
| Lif of lambda * lambda * lambda
| Lfix of (int array * (string * inductive) array * int) * fix_decl
| Lcofix of int * fix_decl
- | Lmakeblock of prefix * pconstructor * int * lambda array
- (* prefix, constructor Name.t, constructor tag, arguments *)
- (* A fully applied constructor *)
- | Lconstruct of prefix * pconstructor (* prefix, constructor Name.t *)
- (* A partially applied constructor *)
+ | Lint of int (* a constant constructor *)
+ | Lmakeblock of prefix * inductive * int * lambda array
+ (* prefix, inductive name, constructor tag, arguments *)
+ (* A fully applied non-constant constructor *)
| Luint of Uint63.t
| Lval of Nativevalues.t
| Lsort of Sorts.t
@@ -51,7 +50,10 @@ type lambda =
| Llazy
| Lforce
-and lam_branches = (constructor * Name.t Context.binder_annot array * lambda) array
+and lam_branches =
+ { constant_branches : lambda array;
+ nonconstant_branches : (Name.t Context.binder_annot array * lambda) array;
+ }
and fix_decl = Name.t Context.binder_annot array * lambda array * lambda array
@@ -121,7 +123,7 @@ let get_const_prefix env c =
let map_lam_with_binders g f n lam =
match lam with
| Lrel _ | Lvar _ | Lconst _ | Lproj _ | Lval _ | Lsort _ | Lind _ | Luint _
- | Lconstruct _ | Llazy | Lforce | Lmeta _ -> lam
+ | Llazy | Lforce | Lmeta _ | Lint _ -> lam
| Lprod(dom,codom) ->
let dom' = f n dom in
let codom' = f n codom in
@@ -143,17 +145,26 @@ let map_lam_with_binders g f n lam =
| Lprim(prefix,kn,op,args) ->
let args' = Array.Smart.map (f n) args in
if args == args' then lam else Lprim(prefix,kn,op,args')
- | Lcase(annot,t,a,br) ->
- let t' = f n t in
- let a' = f n a in
- let on_b b =
- let (cn,ids,body) = b in
- let body' =
- if Array.is_empty ids then f n body
- else f (g (Array.length ids) n) body in
- if body == body' then b else (cn,ids,body') in
- let br' = Array.Smart.map on_b br in
- if t == t' && a == a' && br == br' then lam else Lcase(annot,t',a',br')
+ | Lcase(annot,t,a,branches) ->
+ let const = branches.constant_branches in
+ let nonconst = branches.nonconstant_branches in
+ let t' = f n t in
+ let a' = f n a in
+ let const' = Array.Smart.map (f n) const in
+ let on_b b =
+ let (ids,body) = b in
+ let body' = f (g (Array.length ids) n) body in
+ if body == body' then b else (ids,body') in
+ let nonconst' = Array.Smart.map on_b nonconst in
+ let branches' =
+ if const == const' && nonconst == nonconst' then
+ branches
+ else
+ { constant_branches = const';
+ nonconstant_branches = nonconst' }
+ in
+ if t == t' && a == a' && branches == branches' then lam else
+ Lcase(annot,t',a',branches')
| Lif(t,bt,bf) ->
let t' = f n t in
let bt' = f n bt in
@@ -222,7 +233,7 @@ let lam_subst_args subst args =
let can_subst lam =
match lam with
| Lrel _ | Lvar _ | Lconst _ | Lproj _ | Lval _ | Lsort _ | Lind _ | Llam _
- | Lconstruct _ | Lmeta _ | Levar _ -> true
+ | Lmeta _ | Levar _ -> true
| _ -> false
let can_merge_if bt bf =
@@ -320,16 +331,13 @@ and reduce_lapp substf lids body substa largs =
let is_value lc =
match lc with
- | Lval _ -> true
- | Lmakeblock(_,_,_,args) when Array.is_empty args -> true
- | Luint _ -> true
+ | Lval _ | Lint _ | Luint _ -> true
| _ -> false
let get_value lc =
match lc with
| Lval v -> v
- | Lmakeblock(_,_,tag,args) when Array.is_empty args ->
- Nativevalues.mk_int tag
+ | Lint tag -> Nativevalues.mk_int tag
| Luint i -> Nativevalues.mk_uint i
| _ -> raise Not_found
@@ -337,14 +345,30 @@ let make_args start _end =
Array.init (start - _end + 1) (fun i -> Lrel (Anonymous, start - i))
(* Translation of constructors *)
+let expand_constructor prefix ind tag nparams arity =
+ let anon = Context.make_annot Anonymous Sorts.Relevant in (* TODO relevance *)
+ let ids = Array.make (nparams + arity) anon in
+ if Int.equal arity 0 then mkLlam ids (Lint tag)
+ else
+ let args = make_args arity 1 in
+ Llam(ids, Lmakeblock (prefix, ind, tag, args))
-let makeblock env cn u tag args =
- if Array.for_all is_value args && Array.length args > 0 then
+(* [nparams] is the number of parameters still expected *)
+let makeblock env ind tag nparams arity args =
+ let nargs = Array.length args in
+ if nparams > 0 || nargs < arity then
+ let prefix = get_mind_prefix env (fst ind) in
+ mkLapp (expand_constructor prefix ind tag nparams arity) args
+ else
+ (* The constructor is fully applied *)
+ if Int.equal arity 0 then Lint tag
+ else
+ if Array.for_all is_value args then
let args = Array.map get_value args in
Lval (Nativevalues.mk_block tag args)
else
- let prefix = get_mind_prefix env (fst (fst cn)) in
- Lmakeblock(prefix, (cn,u), tag, args)
+ let prefix = get_mind_prefix env (fst ind) in
+ Lmakeblock(prefix, ind, tag, args)
(* Translation of constants *)
@@ -420,8 +444,6 @@ let empty_evars =
{ evars_val = (fun _ -> None);
evars_metas = (fun _ -> assert false) }
-let empty_ids = [||]
-
(** Extract the inductive type over which a fixpoint is decreasing *)
let rec get_fix_struct env i t = match kind (Reduction.whd_all env t) with
| Prod (na, dom, t) ->
@@ -492,43 +514,51 @@ let rec lambda_of_constr cache env sigma c =
let prefix = get_mind_prefix env (fst ind) in
mkLapp (Lproj (prefix, ind, Projection.arg p)) [|lambda_of_constr cache env sigma c|]
- | Case(ci,t,a,branches) ->
- let (mind,i as ind) = ci.ci_ind in
- let mib = lookup_mind mind env in
- let oib = mib.mind_packets.(i) in
- let tbl = oib.mind_reloc_tbl in
- (* Building info *)
- let prefix = get_mind_prefix env mind in
- let annot_sw =
- { asw_ind = ind;
- asw_ci = ci;
- asw_reloc = tbl;
- asw_finite = mib.mind_finite <> CoFinite;
- asw_prefix = prefix}
- in
- (* translation of the argument *)
- let la = lambda_of_constr cache env sigma a in
- (* translation of the type *)
- let lt = lambda_of_constr cache env sigma t in
- (* translation of branches *)
- let mk_branch i b =
- let cn = (ind,i+1) in
- let _, arity = tbl.(i) in
- let b = lambda_of_constr cache env sigma b in
- if Int.equal arity 0 then (cn, empty_ids, b)
- else
- match b with
- | Llam(ids, body) when Int.equal (Array.length ids) arity -> (cn, ids, body)
+ | Case(ci,t,a,branches) ->
+ let (mind,i as ind) = ci.ci_ind in
+ let mib = lookup_mind mind env in
+ let oib = mib.mind_packets.(i) in
+ let tbl = oib.mind_reloc_tbl in
+ (* Building info *)
+ let prefix = get_mind_prefix env mind in
+ let annot_sw =
+ { asw_ind = ind;
+ asw_ci = ci;
+ asw_reloc = tbl;
+ asw_finite = mib.mind_finite <> CoFinite;
+ asw_prefix = prefix}
+ in
+ (* translation of the argument *)
+ let la = lambda_of_constr cache env sigma a in
+ (* translation of the type *)
+ let lt = lambda_of_constr cache env sigma t in
+ (* translation of branches *)
+ let dummy = Lrel(Anonymous,0) in
+ let consts = Array.make oib.mind_nb_constant dummy in
+ let blocks = Array.make oib.mind_nb_args ([||],dummy) in
+ let rtbl = oib.mind_reloc_tbl in
+ for i = 0 to Array.length rtbl - 1 do
+ let tag, arity = rtbl.(i) in
+ let b = lambda_of_constr cache env sigma branches.(i) in
+ if arity = 0 then consts.(tag) <- b
+ else
+ let b =
+ match b with
+ | Llam(ids, body) when Array.length ids = arity -> (ids, body)
| _ ->
- (** TODO relevance *)
- let anon = Context.make_annot Anonymous Sorts.Relevant in
- let ids = Array.make arity anon in
- let args = make_args arity 1 in
- let ll = lam_lift arity b in
- (cn, ids, mkLapp ll args) in
- let bs = Array.mapi mk_branch branches in
- Lcase(annot_sw, lt, la, bs)
-
+ let anon = Context.make_annot Anonymous Sorts.Relevant in (* TODO relevance *)
+ let ids = Array.make arity anon in
+ let args = make_args arity 1 in
+ let ll = lam_lift arity b in
+ (ids, mkLapp ll args)
+ in blocks.(tag-1) <- b
+ done;
+ let branches =
+ { constant_branches = consts;
+ nonconstant_branches = blocks }
+ in
+ Lcase(annot_sw, lt, la, branches)
+
| Fix((pos, i), (names,type_bodies,rec_bodies)) ->
let ltypes = lambda_of_args cache env sigma 0 type_bodies in
let map i t =
@@ -572,17 +602,13 @@ and lambda_of_app cache env sigma f args =
let prefix = get_const_prefix env kn in
mkLapp (Lconst (prefix, (kn,u))) (lambda_of_args cache env sigma 0 args)
end
- | Construct (c,u) ->
- let tag, nparams, arity = Cache.get_construct_info cache env c in
- let expected = nparams + arity in
- let nargs = Array.length args in
- let prefix = get_mind_prefix env (fst (fst c)) in
- if Int.equal nargs expected then
- let args = lambda_of_args cache env sigma nparams args in
- makeblock env c u tag args
- else
- let args = lambda_of_args cache env sigma 0 args in
- mkLapp (Lconstruct (prefix, (c,u))) args
+ | Construct ((ind,_ as c),_) ->
+ let tag, nparams, arity = Cache.get_construct_info cache env c in
+ let nargs = Array.length args in
+ if nparams < nargs then (* got all parameters *)
+ let args = lambda_of_args cache env sigma nparams args in
+ makeblock env ind tag 0 arity args
+ else makeblock env ind tag (nparams - nargs) arity empty_args
| _ ->
let f = lambda_of_constr cache env sigma f in
let args = lambda_of_args cache env sigma 0 args in
diff --git a/kernel/nativelambda.mli b/kernel/nativelambda.mli
index b0de257a27..446df1a1ea 100644
--- a/kernel/nativelambda.mli
+++ b/kernel/nativelambda.mli
@@ -33,11 +33,10 @@ type lambda =
| Lif of lambda * lambda * lambda
| Lfix of (int array * (string * inductive) array * int) * fix_decl
| Lcofix of int * fix_decl
- | Lmakeblock of prefix * pconstructor * int * lambda array
- (* prefix, constructor Name.t, constructor tag, arguments *)
- (* A fully applied constructor *)
- | Lconstruct of prefix * pconstructor (* prefix, constructor Name.t *)
- (* A partially applied constructor *)
+ | Lint of int (* a constant constructor *)
+ | Lmakeblock of prefix * inductive * int * lambda array
+ (* prefix, inductive name, constructor tag, arguments *)
+ (* A fully applied non-constant constructor *)
| Luint of Uint63.t
| Lval of Nativevalues.t
| Lsort of Sorts.t
@@ -45,7 +44,10 @@ type lambda =
| Llazy
| Lforce
-and lam_branches = (constructor * Name.t Context.binder_annot array * lambda) array
+and lam_branches =
+ { constant_branches : lambda array;
+ nonconstant_branches : (Name.t Context.binder_annot array * lambda) array;
+ }
and fix_decl = Name.t Context.binder_annot array * lambda array * lambda array
diff --git a/kernel/nativelib.ml b/kernel/nativelib.ml
index 833e4082f0..43c9676f05 100644
--- a/kernel/nativelib.ml
+++ b/kernel/nativelib.ml
@@ -56,14 +56,15 @@ let write_ml_code fn ?(header=[]) code =
List.iter (pp_global fmt) (header@code);
close_out ch_out
-let warn_native_compiler_failed =
- let print = function
+let error_native_compiler_failed e =
+ let msg = match e with
+ | Inl (Unix.WEXITED 127) -> Pp.(strbrk "The OCaml compiler was not found. Make sure it is installed, together with findlib.")
| Inl (Unix.WEXITED n) -> Pp.(strbrk "Native compiler exited with status" ++ str" " ++ int n)
| Inl (Unix.WSIGNALED n) -> Pp.(strbrk "Native compiler killed by signal" ++ str" " ++ int n)
| Inl (Unix.WSTOPPED n) -> Pp.(strbrk "Native compiler stopped by signal" ++ str" " ++ int n)
| Inr e -> Pp.(strbrk "Native compiler failed with error: " ++ strbrk (Unix.error_message e))
in
- CWarnings.create ~name:"native-compiler-failed" ~category:"native-compiler" print
+ CErrors.user_err msg
let call_compiler ?profile:(profile=false) ml_filename =
let load_path = !get_load_paths () in
@@ -100,15 +101,12 @@ let call_compiler ?profile:(profile=false) ml_filename =
if !Flags.debug then Feedback.msg_debug (Pp.str (Envars.ocamlfind () ^ " " ^ (String.concat " " args)));
try
let res = CUnix.sys_command (Envars.ocamlfind ()) args in
- let res = match res with
- | Unix.WEXITED 0 -> true
- | Unix.WEXITED _n | Unix.WSIGNALED _n | Unix.WSTOPPED _n ->
- warn_native_compiler_failed (Inl res); false
- in
- res, link_filename
+ match res with
+ | Unix.WEXITED 0 -> link_filename
+ | Unix.WEXITED _n | Unix.WSIGNALED _n | Unix.WSTOPPED _n ->
+ error_native_compiler_failed (Inl res)
with Unix.Unix_error (e,_,_) ->
- warn_native_compiler_failed (Inr e);
- false, link_filename
+ error_native_compiler_failed (Inr e)
let compile fn code ~profile:profile =
write_ml_code fn code;
@@ -128,9 +126,8 @@ let compile_library dir code fn =
in
let fn = dirname / basename in
write_ml_code fn ~header code;
- let r = fst (call_compiler fn) in
- if (not !Flags.debug) && Sys.file_exists fn then Sys.remove fn;
- r
+ let _ = call_compiler fn in
+ if (not !Flags.debug) && Sys.file_exists fn then Sys.remove fn
(* call_linker links dynamically the code for constants in environment or a *)
(* conversion test. *)
diff --git a/kernel/nativelib.mli b/kernel/nativelib.mli
index 25adcf224b..e113350368 100644
--- a/kernel/nativelib.mli
+++ b/kernel/nativelib.mli
@@ -21,9 +21,14 @@ val load_obj : (string -> unit) ref
val get_ml_filename : unit -> string * string
-val compile : string -> global list -> profile:bool -> bool * string
-
-val compile_library : Names.DirPath.t -> global list -> string -> bool
+(** [compile file code ~profile] will compile native [code] to [file],
+ and return the name of the object file; this name depends on
+ whether are in byte mode or not; file is expected to be .ml file *)
+val compile : string -> global list -> profile:bool -> string
+
+(** [compile_library lib code file] is similar to [compile file code]
+ but will perform some extra tweaks to handle [code] as a Coq lib. *)
+val compile_library : Names.DirPath.t -> global list -> string -> unit
val call_linker :
?fatal:bool -> string -> string -> code_location_updates option -> unit