Open kibook opened 9 years ago
This is awesome... a simple test case for this bug is very useful. I will see about taking a look ...
This is interesting in the generated C:
static _KLdouble_integerGVKe K3 = {
&KLdouble_integerGVKeW /* wrapper */,
0x3B9ACA00L,
0xFFFFFFF6L
};
/* Code */
dylan_value Ktest_bugVbugI () {
dylan_value T0;
dylan_value T1;
_KLsimple_object_vectorGVKd_1 T2 = {&KLsimple_object_vectorGVKdW, (dylan_value) 5};
_KLsimple_object_vectorGVKd_1 T3 = {&KLsimple_object_vectorGVKdW, (dylan_value) 5};
T2.vector_element_[0] = &KPtrueVKi;
Kformat_outYformat_outVioMM0I(&K2, &T2);
CONGRUENT_CALL_PROLOG(&Knumber_to_stringYcommon_extensionsVcommon_dylan, 1);
T0 = CONGRUENT_CALL1(&K3);
T3.vector_element_[0] = T0;
T1 = Kformat_outYformat_outVioMM0I(&K2, &T3);
MV_SET_COUNT(0);
return(T1);
}
The code looks the same in a 64 bit OS X build ... but it segfaults there.
The working builds are from HARP, so I suspect this is a bug involving the C backend somehow. Seems like it'll be fun.
The segfault in 64 bit is stack overflow from infinite recursion:
frame #174586: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174587: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174588: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174589: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174590: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174591: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174592: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174593: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174594: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174595: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174596: 0x0000000100311e99 libbig-integers.dylib`Kprocess_integerF275I(buffer_=0x000000010112e460, arg_=<unavailable>) + 169 at double-integer.c:14403
frame #174597: 0x0000000100311b17 libbig-integers.dylib`Knumber_to_stringYcommon_extensionsVcommon_dylanMbig_integersM0I(n_=0x0000000100004268) + 599 at double-integer.c:14361
The corresponding code is:
static dylan_value Kprocess_integerF275I (dylan_value buffer_, dylan_value arg_) {
dylan_value T2_0;
dylan_value T2_1;
dylan_value quotient_;
dylan_value remainder_;
dylan_value T5;
dylan_value T6;
dylan_value T7;
// /opt/deft/sources/lib/big-integers/double-integer.dylan:963
// /opt/deft/sources/lib/big-integers/double-integer.dylan:964
CONGRUENT_CALL_PROLOG(&KtruncateSVgeneric_arithmetic, 2);
T2_0 = CONGRUENT_CALL2(arg_, (dylan_value) 41);
T2_1 = MV_GET_ELT(1);
// /opt/deft/sources/lib/big-integers/double-integer.dylan:964
quotient_ = T2_0;
// /opt/deft/sources/lib/big-integers/double-integer.dylan:964
remainder_ = T2_1;
// /opt/deft/sources/lib/big-integers/double-integer.dylan:965
CONGRUENT_CALL_PROLOG(&KzeroQVKd, 1);
T5 = CONGRUENT_CALL1(quotient_);
// /opt/deft/sources/lib/big-integers/double-integer.dylan:965
if (T5 == &KPfalseVKi) {
// /opt/deft/sources/lib/big-integers/double-integer.dylan:966
Kprocess_integerF275I(buffer_, quotient_); // <---- INFINITE RECURSION HERE
}
// /opt/deft/sources/lib/big-integers/double-integer.dylan:965
// /opt/deft/sources/lib/big-integers/double-integer.dylan:968
CONGRUENT_CALL_PROLOG(&KelementVKd, 3);
T6 = CONGRUENT_CALL3(Dnumber_charactersYbig_integers_internalVbig_integers, remainder_, &KPempty_vectorVKi);
// /opt/deft/sources/lib/big-integers/double-integer.dylan:968
KaddXVKdMM3I(buffer_, T6);
// /opt/deft/sources/lib/big-integers/double-integer.dylan:963
T7 = &KPfalseVKi;
// /opt/deft/sources/lib/big-integers/double-integer.dylan:963
MV_SET_COUNT(0);
return(T7);
}
The corresponding Dylan code to that is:
local method process-integer (arg :: <integer>) => ()
let (quotient, remainder) = truncate/(arg, 10);
unless (zero?(quotient))
process-integer(quotient)
end;
add!(buffer, $number-characters[remainder])
end method process-integer;
Should have mentioned earlier... It is gas imaging that the C shows that the comparison was constant folded to the true value. That makes the source of this error more interesting!
Of interest, K3
is the <double-integer>
that is created for storing the larger value:
(dylan_value) $0 = 0x00005150 {<double-integer>: 4294967286}
(lldb) print K3
(_KLdouble_integerGVKe) $1 = {
wrapper = 0x0012971c {<mm-wrapper>}
PPdouble_integer_low_ = 1000000000
PPdouble_integer_high_ = -10
}
So, why is the high part -10?
Also, small correction to the bug report ... the value printed on OS X is:
#t
-41949672960
Which corresponds to (-10 << 32) + 1000000000
(The initial report had an extra 0
at the end.)
library.dylan
test.dylan
on Windows (32-bit):
on Linux (32-bit)
on OS X (32-bit)