From e8d1612e8e1c30ccf52c384d145fd854a8535885 Mon Sep 17 00:00:00 2001 From: Phil Dawes Date: Thu, 3 Sep 2009 20:32:39 +0100 Subject: [PATCH] Split data out into separate vm-data struct --- vm/bignum.cpp | 2642 +++++++++++++++++++++--------------------- vm/errors.cpp | 7 - vm/factor.cpp | 156 +++ vm/os-windows-nt.cpp | 31 +- vm/vm-data-dummy.hpp | 116 ++ vm/vm-data.hpp | 105 ++ vm/vm.hpp | 105 +- 7 files changed, 1721 insertions(+), 1441 deletions(-) create mode 100644 vm/vm-data-dummy.hpp create mode 100644 vm/vm-data.hpp diff --git a/vm/bignum.cpp b/vm/bignum.cpp index 4c01b12820..3e754c2ab5 100755 --- a/vm/bignum.cpp +++ b/vm/bignum.cpp @@ -1,36 +1,36 @@ /* :tabSize=2:indentSize=2:noTabs=true: -Copyright (C) 1989-94 Massachusetts Institute of Technology -Portions copyright (C) 2004-2008 Slava Pestov - -This material was developed by the Scheme project at the Massachusetts -Institute of Technology, Department of Electrical Engineering and -Computer Science. Permission to copy and modify this software, to -redistribute either the original software or a modified version, and -to use this software for any purpose is granted, subject to the -following restrictions and understandings. - -1. Any copy made of this software must include this copyright notice -in full. - -2. Users of this software agree to make their best efforts (a) to -return to the MIT Scheme project any improvements or extensions that -they make, so that these may be included in future releases; and (b) -to inform MIT of noteworthy uses of this software. - -3. All materials developed as a consequence of the use of this -software shall duly acknowledge such use, in accordance with the usual -standards of acknowledging credit in academic research. - -4. MIT has made no warrantee or representation that the operation of -this software will be error-free, and MIT is under no obligation to -provide any services, by way of maintenance, update, or otherwise. - -5. In conjunction with products arising from the use of this material, -there shall be no use of the name of the Massachusetts Institute of -Technology nor of any adaptation thereof in any advertising, -promotional, or sales literature without prior written consent from -MIT in each case. */ + Copyright (C) 1989-94 Massachusetts Institute of Technology + Portions copyright (C) 2004-2008 Slava Pestov + + This material was developed by the Scheme project at the Massachusetts + Institute of Technology, Department of Electrical Engineering and + Computer Science. Permission to copy and modify this software, to + redistribute either the original software or a modified version, and + to use this software for any purpose is granted, subject to the + following restrictions and understandings. + + 1. Any copy made of this software must include this copyright notice + in full. + + 2. Users of this software agree to make their best efforts (a) to + return to the MIT Scheme project any improvements or extensions that + they make, so that these may be included in future releases; and (b) + to inform MIT of noteworthy uses of this software. + + 3. All materials developed as a consequence of the use of this + software shall duly acknowledge such use, in accordance with the usual + standards of acknowledging credit in academic research. + + 4. MIT has made no warrantee or representation that the operation of + this software will be error-free, and MIT is under no obligation to + provide any services, by way of maintenance, update, or otherwise. + + 5. In conjunction with products arising from the use of this material, + there shall be no use of the name of the Massachusetts Institute of + Technology nor of any adaptation thereof in any advertising, + promotional, or sales literature without prior written consent from + MIT in each case. */ /* Changes for Scheme 48: * - Converted to ANSI. @@ -63,309 +63,309 @@ namespace factor int factorvm::bignum_equal_p(bignum * x, bignum * y) { - return - ((BIGNUM_ZERO_P (x)) - ? (BIGNUM_ZERO_P (y)) - : ((! (BIGNUM_ZERO_P (y))) - && ((BIGNUM_NEGATIVE_P (x)) - ? (BIGNUM_NEGATIVE_P (y)) - : (! (BIGNUM_NEGATIVE_P (y)))) - && (bignum_equal_p_unsigned (x, y)))); + return + ((BIGNUM_ZERO_P (x)) + ? (BIGNUM_ZERO_P (y)) + : ((! (BIGNUM_ZERO_P (y))) + && ((BIGNUM_NEGATIVE_P (x)) + ? (BIGNUM_NEGATIVE_P (y)) + : (! (BIGNUM_NEGATIVE_P (y)))) + && (bignum_equal_p_unsigned (x, y)))); } enum bignum_comparison factorvm::bignum_compare(bignum * x, bignum * y) { - return - ((BIGNUM_ZERO_P (x)) - ? ((BIGNUM_ZERO_P (y)) - ? bignum_comparison_equal - : (BIGNUM_NEGATIVE_P (y)) - ? bignum_comparison_greater - : bignum_comparison_less) - : (BIGNUM_ZERO_P (y)) - ? ((BIGNUM_NEGATIVE_P (x)) - ? bignum_comparison_less - : bignum_comparison_greater) - : (BIGNUM_NEGATIVE_P (x)) - ? ((BIGNUM_NEGATIVE_P (y)) - ? (bignum_compare_unsigned (y, x)) - : (bignum_comparison_less)) - : ((BIGNUM_NEGATIVE_P (y)) - ? (bignum_comparison_greater) - : (bignum_compare_unsigned (x, y)))); + return + ((BIGNUM_ZERO_P (x)) + ? ((BIGNUM_ZERO_P (y)) + ? bignum_comparison_equal + : (BIGNUM_NEGATIVE_P (y)) + ? bignum_comparison_greater + : bignum_comparison_less) + : (BIGNUM_ZERO_P (y)) + ? ((BIGNUM_NEGATIVE_P (x)) + ? bignum_comparison_less + : bignum_comparison_greater) + : (BIGNUM_NEGATIVE_P (x)) + ? ((BIGNUM_NEGATIVE_P (y)) + ? (bignum_compare_unsigned (y, x)) + : (bignum_comparison_less)) + : ((BIGNUM_NEGATIVE_P (y)) + ? (bignum_comparison_greater) + : (bignum_compare_unsigned (x, y)))); } /* allocates memory */ bignum *factorvm::bignum_add(bignum * x, bignum * y) { - return - ((BIGNUM_ZERO_P (x)) - ? (y) - : (BIGNUM_ZERO_P (y)) - ? (x) - : ((BIGNUM_NEGATIVE_P (x)) - ? ((BIGNUM_NEGATIVE_P (y)) - ? (bignum_add_unsigned (x, y, 1)) - : (bignum_subtract_unsigned (y, x))) - : ((BIGNUM_NEGATIVE_P (y)) - ? (bignum_subtract_unsigned (x, y)) - : (bignum_add_unsigned (x, y, 0))))); + return + ((BIGNUM_ZERO_P (x)) + ? (y) + : (BIGNUM_ZERO_P (y)) + ? (x) + : ((BIGNUM_NEGATIVE_P (x)) + ? ((BIGNUM_NEGATIVE_P (y)) + ? (bignum_add_unsigned (x, y, 1)) + : (bignum_subtract_unsigned (y, x))) + : ((BIGNUM_NEGATIVE_P (y)) + ? (bignum_subtract_unsigned (x, y)) + : (bignum_add_unsigned (x, y, 0))))); } /* allocates memory */ bignum *factorvm::bignum_subtract(bignum * x, bignum * y) { - return - ((BIGNUM_ZERO_P (x)) - ? ((BIGNUM_ZERO_P (y)) - ? (y) - : (bignum_new_sign (y, (! (BIGNUM_NEGATIVE_P (y)))))) - : ((BIGNUM_ZERO_P (y)) - ? (x) - : ((BIGNUM_NEGATIVE_P (x)) - ? ((BIGNUM_NEGATIVE_P (y)) - ? (bignum_subtract_unsigned (y, x)) - : (bignum_add_unsigned (x, y, 1))) - : ((BIGNUM_NEGATIVE_P (y)) - ? (bignum_add_unsigned (x, y, 0)) - : (bignum_subtract_unsigned (x, y)))))); + return + ((BIGNUM_ZERO_P (x)) + ? ((BIGNUM_ZERO_P (y)) + ? (y) + : (bignum_new_sign (y, (! (BIGNUM_NEGATIVE_P (y)))))) + : ((BIGNUM_ZERO_P (y)) + ? (x) + : ((BIGNUM_NEGATIVE_P (x)) + ? ((BIGNUM_NEGATIVE_P (y)) + ? (bignum_subtract_unsigned (y, x)) + : (bignum_add_unsigned (x, y, 1))) + : ((BIGNUM_NEGATIVE_P (y)) + ? (bignum_add_unsigned (x, y, 0)) + : (bignum_subtract_unsigned (x, y)))))); } /* allocates memory */ bignum *factorvm::bignum_multiply(bignum * x, bignum * y) { - bignum_length_type x_length = (BIGNUM_LENGTH (x)); - bignum_length_type y_length = (BIGNUM_LENGTH (y)); - int negative_p = - ((BIGNUM_NEGATIVE_P (x)) - ? (! (BIGNUM_NEGATIVE_P (y))) - : (BIGNUM_NEGATIVE_P (y))); - if (BIGNUM_ZERO_P (x)) - return (x); - if (BIGNUM_ZERO_P (y)) - return (y); - if (x_length == 1) - { - bignum_digit_type digit = (BIGNUM_REF (x, 0)); - if (digit == 1) - return (bignum_maybe_new_sign (y, negative_p)); - if (digit < BIGNUM_RADIX_ROOT) - return (bignum_multiply_unsigned_small_factor (y, digit, negative_p)); - } - if (y_length == 1) - { - bignum_digit_type digit = (BIGNUM_REF (y, 0)); - if (digit == 1) - return (bignum_maybe_new_sign (x, negative_p)); - if (digit < BIGNUM_RADIX_ROOT) - return (bignum_multiply_unsigned_small_factor (x, digit, negative_p)); - } - return (bignum_multiply_unsigned (x, y, negative_p)); + bignum_length_type x_length = (BIGNUM_LENGTH (x)); + bignum_length_type y_length = (BIGNUM_LENGTH (y)); + int negative_p = + ((BIGNUM_NEGATIVE_P (x)) + ? (! (BIGNUM_NEGATIVE_P (y))) + : (BIGNUM_NEGATIVE_P (y))); + if (BIGNUM_ZERO_P (x)) + return (x); + if (BIGNUM_ZERO_P (y)) + return (y); + if (x_length == 1) + { + bignum_digit_type digit = (BIGNUM_REF (x, 0)); + if (digit == 1) + return (bignum_maybe_new_sign (y, negative_p)); + if (digit < BIGNUM_RADIX_ROOT) + return (bignum_multiply_unsigned_small_factor (y, digit, negative_p)); + } + if (y_length == 1) + { + bignum_digit_type digit = (BIGNUM_REF (y, 0)); + if (digit == 1) + return (bignum_maybe_new_sign (x, negative_p)); + if (digit < BIGNUM_RADIX_ROOT) + return (bignum_multiply_unsigned_small_factor (x, digit, negative_p)); + } + return (bignum_multiply_unsigned (x, y, negative_p)); } /* allocates memory */ void factorvm::bignum_divide(bignum * numerator, bignum * denominator, bignum * * quotient, bignum * * remainder) { - if (BIGNUM_ZERO_P (denominator)) - { - divide_by_zero_error(); - return; - } - if (BIGNUM_ZERO_P (numerator)) - { - (*quotient) = numerator; - (*remainder) = numerator; - } - else - { - int r_negative_p = (BIGNUM_NEGATIVE_P (numerator)); - int q_negative_p = - ((BIGNUM_NEGATIVE_P (denominator)) ? (! r_negative_p) : r_negative_p); - switch (bignum_compare_unsigned (numerator, denominator)) - { - case bignum_comparison_equal: - { - (*quotient) = (BIGNUM_ONE (q_negative_p)); - (*remainder) = (BIGNUM_ZERO ()); - break; - } - case bignum_comparison_less: - { - (*quotient) = (BIGNUM_ZERO ()); - (*remainder) = numerator; - break; - } - case bignum_comparison_greater: - { - if ((BIGNUM_LENGTH (denominator)) == 1) - { - bignum_digit_type digit = (BIGNUM_REF (denominator, 0)); - if (digit == 1) - { - (*quotient) = - (bignum_maybe_new_sign (numerator, q_negative_p)); - (*remainder) = (BIGNUM_ZERO ()); - break; - } - else if (digit < BIGNUM_RADIX_ROOT) - { - bignum_divide_unsigned_small_denominator - (numerator, digit, - quotient, remainder, - q_negative_p, r_negative_p); - break; - } - else - { - bignum_divide_unsigned_medium_denominator - (numerator, digit, - quotient, remainder, - q_negative_p, r_negative_p); - break; - } - } - bignum_divide_unsigned_large_denominator - (numerator, denominator, - quotient, remainder, - q_negative_p, r_negative_p); - break; - } - } - } + if (BIGNUM_ZERO_P (denominator)) + { + divide_by_zero_error(); + return; + } + if (BIGNUM_ZERO_P (numerator)) + { + (*quotient) = numerator; + (*remainder) = numerator; + } + else + { + int r_negative_p = (BIGNUM_NEGATIVE_P (numerator)); + int q_negative_p = + ((BIGNUM_NEGATIVE_P (denominator)) ? (! r_negative_p) : r_negative_p); + switch (bignum_compare_unsigned (numerator, denominator)) + { + case bignum_comparison_equal: + { + (*quotient) = (BIGNUM_ONE (q_negative_p)); + (*remainder) = (BIGNUM_ZERO ()); + break; + } + case bignum_comparison_less: + { + (*quotient) = (BIGNUM_ZERO ()); + (*remainder) = numerator; + break; + } + case bignum_comparison_greater: + { + if ((BIGNUM_LENGTH (denominator)) == 1) + { + bignum_digit_type digit = (BIGNUM_REF (denominator, 0)); + if (digit == 1) + { + (*quotient) = + (bignum_maybe_new_sign (numerator, q_negative_p)); + (*remainder) = (BIGNUM_ZERO ()); + break; + } + else if (digit < BIGNUM_RADIX_ROOT) + { + bignum_divide_unsigned_small_denominator + (numerator, digit, + quotient, remainder, + q_negative_p, r_negative_p); + break; + } + else + { + bignum_divide_unsigned_medium_denominator + (numerator, digit, + quotient, remainder, + q_negative_p, r_negative_p); + break; + } + } + bignum_divide_unsigned_large_denominator + (numerator, denominator, + quotient, remainder, + q_negative_p, r_negative_p); + break; + } + } + } } /* allocates memory */ bignum *factorvm::bignum_quotient(bignum * numerator, bignum * denominator) { - if (BIGNUM_ZERO_P (denominator)) - { - divide_by_zero_error(); - return (BIGNUM_OUT_OF_BAND); - } - if (BIGNUM_ZERO_P (numerator)) - return numerator; - { - int q_negative_p = - ((BIGNUM_NEGATIVE_P (denominator)) - ? (! (BIGNUM_NEGATIVE_P (numerator))) - : (BIGNUM_NEGATIVE_P (numerator))); - switch (bignum_compare_unsigned (numerator, denominator)) - { - case bignum_comparison_equal: - return (BIGNUM_ONE (q_negative_p)); - case bignum_comparison_less: - return (BIGNUM_ZERO ()); - case bignum_comparison_greater: - default: /* to appease gcc -Wall */ - { - bignum * quotient; - if ((BIGNUM_LENGTH (denominator)) == 1) - { - bignum_digit_type digit = (BIGNUM_REF (denominator, 0)); - if (digit == 1) - return (bignum_maybe_new_sign (numerator, q_negative_p)); - if (digit < BIGNUM_RADIX_ROOT) - bignum_divide_unsigned_small_denominator - (numerator, digit, - ("ient), ((bignum * *) 0), - q_negative_p, 0); - else - bignum_divide_unsigned_medium_denominator - (numerator, digit, - ("ient), ((bignum * *) 0), - q_negative_p, 0); - } - else - bignum_divide_unsigned_large_denominator - (numerator, denominator, - ("ient), ((bignum * *) 0), - q_negative_p, 0); - return (quotient); - } - } - } + if (BIGNUM_ZERO_P (denominator)) + { + divide_by_zero_error(); + return (BIGNUM_OUT_OF_BAND); + } + if (BIGNUM_ZERO_P (numerator)) + return numerator; + { + int q_negative_p = + ((BIGNUM_NEGATIVE_P (denominator)) + ? (! (BIGNUM_NEGATIVE_P (numerator))) + : (BIGNUM_NEGATIVE_P (numerator))); + switch (bignum_compare_unsigned (numerator, denominator)) + { + case bignum_comparison_equal: + return (BIGNUM_ONE (q_negative_p)); + case bignum_comparison_less: + return (BIGNUM_ZERO ()); + case bignum_comparison_greater: + default: /* to appease gcc -Wall */ + { + bignum * quotient; + if ((BIGNUM_LENGTH (denominator)) == 1) + { + bignum_digit_type digit = (BIGNUM_REF (denominator, 0)); + if (digit == 1) + return (bignum_maybe_new_sign (numerator, q_negative_p)); + if (digit < BIGNUM_RADIX_ROOT) + bignum_divide_unsigned_small_denominator + (numerator, digit, + ("ient), ((bignum * *) 0), + q_negative_p, 0); + else + bignum_divide_unsigned_medium_denominator + (numerator, digit, + ("ient), ((bignum * *) 0), + q_negative_p, 0); + } + else + bignum_divide_unsigned_large_denominator + (numerator, denominator, + ("ient), ((bignum * *) 0), + q_negative_p, 0); + return (quotient); + } + } + } } /* allocates memory */ bignum *factorvm::bignum_remainder(bignum * numerator, bignum * denominator) { - if (BIGNUM_ZERO_P (denominator)) - { - divide_by_zero_error(); - return (BIGNUM_OUT_OF_BAND); - } - if (BIGNUM_ZERO_P (numerator)) - return numerator; - switch (bignum_compare_unsigned (numerator, denominator)) - { - case bignum_comparison_equal: - return (BIGNUM_ZERO ()); - case bignum_comparison_less: - return numerator; - case bignum_comparison_greater: - default: /* to appease gcc -Wall */ - { - bignum * remainder; - if ((BIGNUM_LENGTH (denominator)) == 1) - { - bignum_digit_type digit = (BIGNUM_REF (denominator, 0)); - if (digit == 1) - return (BIGNUM_ZERO ()); - if (digit < BIGNUM_RADIX_ROOT) - return - (bignum_remainder_unsigned_small_denominator - (numerator, digit, (BIGNUM_NEGATIVE_P (numerator)))); - bignum_divide_unsigned_medium_denominator - (numerator, digit, - ((bignum * *) 0), (&remainder), - 0, (BIGNUM_NEGATIVE_P (numerator))); - } - else - bignum_divide_unsigned_large_denominator - (numerator, denominator, - ((bignum * *) 0), (&remainder), - 0, (BIGNUM_NEGATIVE_P (numerator))); - return (remainder); - } - } + if (BIGNUM_ZERO_P (denominator)) + { + divide_by_zero_error(); + return (BIGNUM_OUT_OF_BAND); + } + if (BIGNUM_ZERO_P (numerator)) + return numerator; + switch (bignum_compare_unsigned (numerator, denominator)) + { + case bignum_comparison_equal: + return (BIGNUM_ZERO ()); + case bignum_comparison_less: + return numerator; + case bignum_comparison_greater: + default: /* to appease gcc -Wall */ + { + bignum * remainder; + if ((BIGNUM_LENGTH (denominator)) == 1) + { + bignum_digit_type digit = (BIGNUM_REF (denominator, 0)); + if (digit == 1) + return (BIGNUM_ZERO ()); + if (digit < BIGNUM_RADIX_ROOT) + return + (bignum_remainder_unsigned_small_denominator + (numerator, digit, (BIGNUM_NEGATIVE_P (numerator)))); + bignum_divide_unsigned_medium_denominator + (numerator, digit, + ((bignum * *) 0), (&remainder), + 0, (BIGNUM_NEGATIVE_P (numerator))); + } + else + bignum_divide_unsigned_large_denominator + (numerator, denominator, + ((bignum * *) 0), (&remainder), + 0, (BIGNUM_NEGATIVE_P (numerator))); + return (remainder); + } + } } -#define FOO_TO_BIGNUM(name,type,utype) \ - bignum * factorvm::name##_to_bignum(type n) \ - { \ - int negative_p; \ - bignum_digit_type result_digits [BIGNUM_DIGITS_FOR(type)]; \ - bignum_digit_type * end_digits = result_digits; \ - /* Special cases win when these small constants are cached. */ \ - if (n == 0) return (BIGNUM_ZERO ()); \ - if (n == 1) return (BIGNUM_ONE (0)); \ - if (n < (type)0 && n == (type)-1) return (BIGNUM_ONE (1)); \ - { \ - utype accumulator = ((negative_p = (n < (type)0)) ? (-n) : n); \ - do \ - { \ - (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK); \ - accumulator >>= BIGNUM_DIGIT_LENGTH; \ - } \ - while (accumulator != 0); \ - } \ - { \ - bignum * result = \ - (allot_bignum ((end_digits - result_digits), negative_p)); \ - bignum_digit_type * scan_digits = result_digits; \ - bignum_digit_type * scan_result = (BIGNUM_START_PTR (result)); \ - while (scan_digits < end_digits) \ - (*scan_result++) = (*scan_digits++); \ - return (result); \ - } \ - } +#define FOO_TO_BIGNUM(name,type,utype) \ +bignum * factorvm::name##_to_bignum(type n) \ +{ \ + int negative_p; \ + bignum_digit_type result_digits [BIGNUM_DIGITS_FOR(type)]; \ + bignum_digit_type * end_digits = result_digits; \ + /* Special cases win when these small constants are cached. */ \ + if (n == 0) return (BIGNUM_ZERO ()); \ + if (n == 1) return (BIGNUM_ONE (0)); \ + if (n < (type)0 && n == (type)-1) return (BIGNUM_ONE (1)); \ + { \ + utype accumulator = ((negative_p = (n < (type)0)) ? (-n) : n); \ + do \ + { \ + (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK); \ + accumulator >>= BIGNUM_DIGIT_LENGTH; \ + } \ + while (accumulator != 0); \ + } \ + { \ + bignum * result = \ + (allot_bignum ((end_digits - result_digits), negative_p)); \ + bignum_digit_type * scan_digits = result_digits; \ + bignum_digit_type * scan_result = (BIGNUM_START_PTR (result)); \ + while (scan_digits < end_digits) \ + (*scan_result++) = (*scan_digits++); \ + return (result); \ + } \ +} /* all below allocate memory */ FOO_TO_BIGNUM(cell,cell,cell) @@ -373,20 +373,20 @@ FOO_TO_BIGNUM(fixnum,fixnum,cell) FOO_TO_BIGNUM(long_long,s64,u64) FOO_TO_BIGNUM(ulong_long,u64,u64) -#define BIGNUM_TO_FOO(name,type,utype) \ -type factorvm::bignum_to_##name(bignum * bignum) \ - { \ - if (BIGNUM_ZERO_P (bignum)) \ - return (0); \ - { \ - utype accumulator = 0; \ - bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); \ - bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); \ - while (start < scan) \ - accumulator = ((accumulator << BIGNUM_DIGIT_LENGTH) + (*--scan)); \ - return ((BIGNUM_NEGATIVE_P (bignum)) ? (-((type)accumulator)) : accumulator); \ - } \ - } +#define BIGNUM_TO_FOO(name,type,utype) \ + type factorvm::bignum_to_##name(bignum * bignum) \ + { \ + if (BIGNUM_ZERO_P (bignum)) \ + return (0); \ + { \ + utype accumulator = 0; \ + bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); \ + bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); \ + while (start < scan) \ + accumulator = ((accumulator << BIGNUM_DIGIT_LENGTH) + (*--scan)); \ + return ((BIGNUM_NEGATIVE_P (bignum)) ? (-((type)accumulator)) : accumulator); \ + } \ + } /* all of the below allocate memory */ BIGNUM_TO_FOO(cell,cell,cell); @@ -396,25 +396,25 @@ BIGNUM_TO_FOO(ulong_long,u64,u64) double factorvm::bignum_to_double(bignum * bignum) { - if (BIGNUM_ZERO_P (bignum)) - return (0); - { - double accumulator = 0; - bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); - bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); - while (start < scan) - accumulator = ((accumulator * BIGNUM_RADIX) + (*--scan)); - return ((BIGNUM_NEGATIVE_P (bignum)) ? (-accumulator) : accumulator); - } + if (BIGNUM_ZERO_P (bignum)) + return (0); + { + double accumulator = 0; + bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); + bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); + while (start < scan) + accumulator = ((accumulator * BIGNUM_RADIX) + (*--scan)); + return ((BIGNUM_NEGATIVE_P (bignum)) ? (-accumulator) : accumulator); + } } -#define DTB_WRITE_DIGIT(factor) \ -{ \ - significand *= (factor); \ - digit = ((bignum_digit_type) significand); \ - (*--scan) = digit; \ - significand -= ((double) digit); \ +#define DTB_WRITE_DIGIT(factor) \ +{ \ + significand *= (factor); \ + digit = ((bignum_digit_type) significand); \ + (*--scan) = digit; \ + significand -= ((double) digit); \ } /* allocates memory */ @@ -422,33 +422,33 @@ double factorvm::bignum_to_double(bignum * bignum) bignum *factorvm::double_to_bignum(double x) { - if (x == inf || x == -inf || x != x) return (BIGNUM_ZERO ()); - int exponent; - double significand = (frexp (x, (&exponent))); - if (exponent <= 0) return (BIGNUM_ZERO ()); - if (exponent == 1) return (BIGNUM_ONE (x < 0)); - if (significand < 0) significand = (-significand); - { - bignum_length_type length = (BIGNUM_BITS_TO_DIGITS (exponent)); - bignum * result = (allot_bignum (length, (x < 0))); - bignum_digit_type * start = (BIGNUM_START_PTR (result)); - bignum_digit_type * scan = (start + length); - bignum_digit_type digit; - int odd_bits = (exponent % BIGNUM_DIGIT_LENGTH); - if (odd_bits > 0) - DTB_WRITE_DIGIT ((fixnum)1 << odd_bits); - while (start < scan) - { - if (significand == 0) - { - while (start < scan) - (*--scan) = 0; - break; - } - DTB_WRITE_DIGIT (BIGNUM_RADIX); - } - return (result); - } + if (x == inf || x == -inf || x != x) return (BIGNUM_ZERO ()); + int exponent; + double significand = (frexp (x, (&exponent))); + if (exponent <= 0) return (BIGNUM_ZERO ()); + if (exponent == 1) return (BIGNUM_ONE (x < 0)); + if (significand < 0) significand = (-significand); + { + bignum_length_type length = (BIGNUM_BITS_TO_DIGITS (exponent)); + bignum * result = (allot_bignum (length, (x < 0))); + bignum_digit_type * start = (BIGNUM_START_PTR (result)); + bignum_digit_type * scan = (start + length); + bignum_digit_type digit; + int odd_bits = (exponent % BIGNUM_DIGIT_LENGTH); + if (odd_bits > 0) + DTB_WRITE_DIGIT ((fixnum)1 << odd_bits); + while (start < scan) + { + if (significand == 0) + { + while (start < scan) + (*--scan) = 0; + break; + } + DTB_WRITE_DIGIT (BIGNUM_RADIX); + } + return (result); + } } @@ -458,45 +458,45 @@ bignum *factorvm::double_to_bignum(double x) int factorvm::bignum_equal_p_unsigned(bignum * x, bignum * y) { - bignum_length_type length = (BIGNUM_LENGTH (x)); - if (length != (BIGNUM_LENGTH (y))) - return (0); - else - { - bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); - bignum_digit_type * scan_y = (BIGNUM_START_PTR (y)); - bignum_digit_type * end_x = (scan_x + length); - while (scan_x < end_x) - if ((*scan_x++) != (*scan_y++)) - return (0); - return (1); - } + bignum_length_type length = (BIGNUM_LENGTH (x)); + if (length != (BIGNUM_LENGTH (y))) + return (0); + else + { + bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); + bignum_digit_type * scan_y = (BIGNUM_START_PTR (y)); + bignum_digit_type * end_x = (scan_x + length); + while (scan_x < end_x) + if ((*scan_x++) != (*scan_y++)) + return (0); + return (1); + } } enum bignum_comparison factorvm::bignum_compare_unsigned(bignum * x, bignum * y) { - bignum_length_type x_length = (BIGNUM_LENGTH (x)); - bignum_length_type y_length = (BIGNUM_LENGTH (y)); - if (x_length < y_length) - return (bignum_comparison_less); - if (x_length > y_length) - return (bignum_comparison_greater); - { - bignum_digit_type * start_x = (BIGNUM_START_PTR (x)); - bignum_digit_type * scan_x = (start_x + x_length); - bignum_digit_type * scan_y = ((BIGNUM_START_PTR (y)) + y_length); - while (start_x < scan_x) - { - bignum_digit_type digit_x = (*--scan_x); - bignum_digit_type digit_y = (*--scan_y); - if (digit_x < digit_y) - return (bignum_comparison_less); - if (digit_x > digit_y) - return (bignum_comparison_greater); - } - } - return (bignum_comparison_equal); + bignum_length_type x_length = (BIGNUM_LENGTH (x)); + bignum_length_type y_length = (BIGNUM_LENGTH (y)); + if (x_length < y_length) + return (bignum_comparison_less); + if (x_length > y_length) + return (bignum_comparison_greater); + { + bignum_digit_type * start_x = (BIGNUM_START_PTR (x)); + bignum_digit_type * scan_x = (start_x + x_length); + bignum_digit_type * scan_y = ((BIGNUM_START_PTR (y)) + y_length); + while (start_x < scan_x) + { + bignum_digit_type digit_x = (*--scan_x); + bignum_digit_type digit_y = (*--scan_y); + if (digit_x < digit_y) + return (bignum_comparison_less); + if (digit_x > digit_y) + return (bignum_comparison_greater); + } + } + return (bignum_comparison_equal); } @@ -507,64 +507,64 @@ bignum *factorvm::bignum_add_unsigned(bignum * x, bignum * y, int negative_p) { GC_BIGNUM(x,this); GC_BIGNUM(y,this); - if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x))) - { - bignum * z = x; - x = y; - y = z; - } - { - bignum_length_type x_length = (BIGNUM_LENGTH (x)); + if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x))) + { + bignum * z = x; + x = y; + y = z; + } + { + bignum_length_type x_length = (BIGNUM_LENGTH (x)); - bignum * r = (allot_bignum ((x_length + 1), negative_p)); - - bignum_digit_type sum; - bignum_digit_type carry = 0; - bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); - bignum_digit_type * scan_r = (BIGNUM_START_PTR (r)); - { - bignum_digit_type * scan_y = (BIGNUM_START_PTR (y)); - bignum_digit_type * end_y = (scan_y + (BIGNUM_LENGTH (y))); - while (scan_y < end_y) - { - sum = ((*scan_x++) + (*scan_y++) + carry); - if (sum < BIGNUM_RADIX) - { - (*scan_r++) = sum; - carry = 0; - } - else - { - (*scan_r++) = (sum - BIGNUM_RADIX); - carry = 1; - } - } - } - { - bignum_digit_type * end_x = ((BIGNUM_START_PTR (x)) + x_length); - if (carry != 0) - while (scan_x < end_x) - { - sum = ((*scan_x++) + 1); - if (sum < BIGNUM_RADIX) - { - (*scan_r++) = sum; - carry = 0; - break; - } - else - (*scan_r++) = (sum - BIGNUM_RADIX); - } - while (scan_x < end_x) - (*scan_r++) = (*scan_x++); - } - if (carry != 0) - { - (*scan_r) = 1; - return (r); - } - return (bignum_shorten_length (r, x_length)); - } + bignum * r = (allot_bignum ((x_length + 1), negative_p)); + + bignum_digit_type sum; + bignum_digit_type carry = 0; + bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); + bignum_digit_type * scan_r = (BIGNUM_START_PTR (r)); + { + bignum_digit_type * scan_y = (BIGNUM_START_PTR (y)); + bignum_digit_type * end_y = (scan_y + (BIGNUM_LENGTH (y))); + while (scan_y < end_y) + { + sum = ((*scan_x++) + (*scan_y++) + carry); + if (sum < BIGNUM_RADIX) + { + (*scan_r++) = sum; + carry = 0; + } + else + { + (*scan_r++) = (sum - BIGNUM_RADIX); + carry = 1; + } + } + } + { + bignum_digit_type * end_x = ((BIGNUM_START_PTR (x)) + x_length); + if (carry != 0) + while (scan_x < end_x) + { + sum = ((*scan_x++) + 1); + if (sum < BIGNUM_RADIX) + { + (*scan_r++) = sum; + carry = 0; + break; + } + else + (*scan_r++) = (sum - BIGNUM_RADIX); + } + while (scan_x < end_x) + (*scan_r++) = (*scan_x++); + } + if (carry != 0) + { + (*scan_r) = 1; + return (r); + } + return (bignum_shorten_length (r, x_length)); + } } @@ -575,149 +575,149 @@ bignum *factorvm::bignum_subtract_unsigned(bignum * x, bignum * y) { GC_BIGNUM(x,this); GC_BIGNUM(y,this); - int negative_p = 0; - switch (bignum_compare_unsigned (x, y)) - { - case bignum_comparison_equal: - return (BIGNUM_ZERO ()); - case bignum_comparison_less: - { - bignum * z = x; - x = y; - y = z; - } - negative_p = 1; - break; - case bignum_comparison_greater: - negative_p = 0; - break; - } - { - bignum_length_type x_length = (BIGNUM_LENGTH (x)); + int negative_p = 0; + switch (bignum_compare_unsigned (x, y)) + { + case bignum_comparison_equal: + return (BIGNUM_ZERO ()); + case bignum_comparison_less: + { + bignum * z = x; + x = y; + y = z; + } + negative_p = 1; + break; + case bignum_comparison_greater: + negative_p = 0; + break; + } + { + bignum_length_type x_length = (BIGNUM_LENGTH (x)); - bignum * r = (allot_bignum (x_length, negative_p)); - - bignum_digit_type difference; - bignum_digit_type borrow = 0; - bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); - bignum_digit_type * scan_r = (BIGNUM_START_PTR (r)); - { - bignum_digit_type * scan_y = (BIGNUM_START_PTR (y)); - bignum_digit_type * end_y = (scan_y + (BIGNUM_LENGTH (y))); - while (scan_y < end_y) - { - difference = (((*scan_x++) - (*scan_y++)) - borrow); - if (difference < 0) - { - (*scan_r++) = (difference + BIGNUM_RADIX); - borrow = 1; - } - else - { - (*scan_r++) = difference; - borrow = 0; - } - } - } - { - bignum_digit_type * end_x = ((BIGNUM_START_PTR (x)) + x_length); - if (borrow != 0) - while (scan_x < end_x) - { - difference = ((*scan_x++) - borrow); - if (difference < 0) - (*scan_r++) = (difference + BIGNUM_RADIX); - else - { - (*scan_r++) = difference; - borrow = 0; - break; - } - } - BIGNUM_ASSERT (borrow == 0); - while (scan_x < end_x) - (*scan_r++) = (*scan_x++); - } - return (bignum_trim (r)); - } + bignum * r = (allot_bignum (x_length, negative_p)); + + bignum_digit_type difference; + bignum_digit_type borrow = 0; + bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); + bignum_digit_type * scan_r = (BIGNUM_START_PTR (r)); + { + bignum_digit_type * scan_y = (BIGNUM_START_PTR (y)); + bignum_digit_type * end_y = (scan_y + (BIGNUM_LENGTH (y))); + while (scan_y < end_y) + { + difference = (((*scan_x++) - (*scan_y++)) - borrow); + if (difference < 0) + { + (*scan_r++) = (difference + BIGNUM_RADIX); + borrow = 1; + } + else + { + (*scan_r++) = difference; + borrow = 0; + } + } + } + { + bignum_digit_type * end_x = ((BIGNUM_START_PTR (x)) + x_length); + if (borrow != 0) + while (scan_x < end_x) + { + difference = ((*scan_x++) - borrow); + if (difference < 0) + (*scan_r++) = (difference + BIGNUM_RADIX); + else + { + (*scan_r++) = difference; + borrow = 0; + break; + } + } + BIGNUM_ASSERT (borrow == 0); + while (scan_x < end_x) + (*scan_r++) = (*scan_x++); + } + return (bignum_trim (r)); + } } /* Multiplication Maximum value for product_low or product_high: - ((R * R) + (R * (R - 2)) + (R - 1)) + ((R * R) + (R * (R - 2)) + (R - 1)) Maximum value for carry: ((R * (R - 1)) + (R - 1)) - where R == BIGNUM_RADIX_ROOT */ + where R == BIGNUM_RADIX_ROOT */ /* allocates memory */ bignum *factorvm::bignum_multiply_unsigned(bignum * x, bignum * y, int negative_p) { GC_BIGNUM(x,this); GC_BIGNUM(y,this); - if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x))) - { - bignum * z = x; - x = y; - y = z; - } - { - bignum_digit_type carry; - bignum_digit_type y_digit_low; - bignum_digit_type y_digit_high; - bignum_digit_type x_digit_low; - bignum_digit_type x_digit_high; - bignum_digit_type product_low; - bignum_digit_type * scan_r; - bignum_digit_type * scan_y; - bignum_length_type x_length = (BIGNUM_LENGTH (x)); - bignum_length_type y_length = (BIGNUM_LENGTH (y)); - - bignum * r = - (allot_bignum_zeroed ((x_length + y_length), negative_p)); - - bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); - bignum_digit_type * end_x = (scan_x + x_length); - bignum_digit_type * start_y = (BIGNUM_START_PTR (y)); - bignum_digit_type * end_y = (start_y + y_length); - bignum_digit_type * start_r = (BIGNUM_START_PTR (r)); + if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x))) + { + bignum * z = x; + x = y; + y = z; + } + { + bignum_digit_type carry; + bignum_digit_type y_digit_low; + bignum_digit_type y_digit_high; + bignum_digit_type x_digit_low; + bignum_digit_type x_digit_high; + bignum_digit_type product_low; + bignum_digit_type * scan_r; + bignum_digit_type * scan_y; + bignum_length_type x_length = (BIGNUM_LENGTH (x)); + bignum_length_type y_length = (BIGNUM_LENGTH (y)); + + bignum * r = + (allot_bignum_zeroed ((x_length + y_length), negative_p)); + + bignum_digit_type * scan_x = (BIGNUM_START_PTR (x)); + bignum_digit_type * end_x = (scan_x + x_length); + bignum_digit_type * start_y = (BIGNUM_START_PTR (y)); + bignum_digit_type * end_y = (start_y + y_length); + bignum_digit_type * start_r = (BIGNUM_START_PTR (r)); #define x_digit x_digit_high #define y_digit y_digit_high #define product_high carry - while (scan_x < end_x) - { - x_digit = (*scan_x++); - x_digit_low = (HD_LOW (x_digit)); - x_digit_high = (HD_HIGH (x_digit)); - carry = 0; - scan_y = start_y; - scan_r = (start_r++); - while (scan_y < end_y) - { - y_digit = (*scan_y++); - y_digit_low = (HD_LOW (y_digit)); - y_digit_high = (HD_HIGH (y_digit)); - product_low = - ((*scan_r) + - (x_digit_low * y_digit_low) + - (HD_LOW (carry))); - product_high = - ((x_digit_high * y_digit_low) + - (x_digit_low * y_digit_high) + - (HD_HIGH (product_low)) + - (HD_HIGH (carry))); - (*scan_r++) = - (HD_CONS ((HD_LOW (product_high)), (HD_LOW (product_low)))); - carry = - ((x_digit_high * y_digit_high) + - (HD_HIGH (product_high))); - } - (*scan_r) += carry; - } - return (bignum_trim (r)); + while (scan_x < end_x) + { + x_digit = (*scan_x++); + x_digit_low = (HD_LOW (x_digit)); + x_digit_high = (HD_HIGH (x_digit)); + carry = 0; + scan_y = start_y; + scan_r = (start_r++); + while (scan_y < end_y) + { + y_digit = (*scan_y++); + y_digit_low = (HD_LOW (y_digit)); + y_digit_high = (HD_HIGH (y_digit)); + product_low = + ((*scan_r) + + (x_digit_low * y_digit_low) + + (HD_LOW (carry))); + product_high = + ((x_digit_high * y_digit_low) + + (x_digit_low * y_digit_high) + + (HD_HIGH (product_low)) + + (HD_HIGH (carry))); + (*scan_r++) = + (HD_CONS ((HD_LOW (product_high)), (HD_LOW (product_low)))); + carry = + ((x_digit_high * y_digit_high) + + (HD_HIGH (product_high))); + } + (*scan_r) += carry; + } + return (bignum_trim (r)); #undef x_digit #undef y_digit #undef product_high - } + } } @@ -726,67 +726,67 @@ bignum *factorvm::bignum_multiply_unsigned_small_factor(bignum * x, bignum_digit { GC_BIGNUM(x,this); - bignum_length_type length_x = (BIGNUM_LENGTH (x)); + bignum_length_type length_x = (BIGNUM_LENGTH (x)); - bignum * p = (allot_bignum ((length_x + 1), negative_p)); + bignum * p = (allot_bignum ((length_x + 1), negative_p)); - bignum_destructive_copy (x, p); - (BIGNUM_REF (p, length_x)) = 0; - bignum_destructive_scale_up (p, y); - return (bignum_trim (p)); + bignum_destructive_copy (x, p); + (BIGNUM_REF (p, length_x)) = 0; + bignum_destructive_scale_up (p, y); + return (bignum_trim (p)); } void factorvm::bignum_destructive_add(bignum * bignum, bignum_digit_type n) { - bignum_digit_type * scan = (BIGNUM_START_PTR (bignum)); - bignum_digit_type digit; - digit = ((*scan) + n); - if (digit < BIGNUM_RADIX) - { - (*scan) = digit; - return; - } - (*scan++) = (digit - BIGNUM_RADIX); - while (1) - { - digit = ((*scan) + 1); - if (digit < BIGNUM_RADIX) - { - (*scan) = digit; - return; - } - (*scan++) = (digit - BIGNUM_RADIX); - } + bignum_digit_type * scan = (BIGNUM_START_PTR (bignum)); + bignum_digit_type digit; + digit = ((*scan) + n); + if (digit < BIGNUM_RADIX) + { + (*scan) = digit; + return; + } + (*scan++) = (digit - BIGNUM_RADIX); + while (1) + { + digit = ((*scan) + 1); + if (digit < BIGNUM_RADIX) + { + (*scan) = digit; + return; + } + (*scan++) = (digit - BIGNUM_RADIX); + } } void factorvm::bignum_destructive_scale_up(bignum * bignum, bignum_digit_type factor) { - bignum_digit_type carry = 0; - bignum_digit_type * scan = (BIGNUM_START_PTR (bignum)); - bignum_digit_type two_digits; - bignum_digit_type product_low; + bignum_digit_type carry = 0; + bignum_digit_type * scan = (BIGNUM_START_PTR (bignum)); + bignum_digit_type two_digits; + bignum_digit_type product_low; #define product_high carry - bignum_digit_type * end = (scan + (BIGNUM_LENGTH (bignum))); - BIGNUM_ASSERT ((factor > 1) && (factor < BIGNUM_RADIX_ROOT)); - while (scan < end) - { - two_digits = (*scan); - product_low = ((factor * (HD_LOW (two_digits))) + (HD_LOW (carry))); - product_high = - ((factor * (HD_HIGH (two_digits))) + - (HD_HIGH (product_low)) + - (HD_HIGH (carry))); - (*scan++) = (HD_CONS ((HD_LOW (product_high)), (HD_LOW (product_low)))); - carry = (HD_HIGH (product_high)); - } - /* A carry here would be an overflow, i.e. it would not fit. - Hopefully the callers allocate enough space that this will - never happen. - */ - BIGNUM_ASSERT (carry == 0); - return; + bignum_digit_type * end = (scan + (BIGNUM_LENGTH (bignum))); + BIGNUM_ASSERT ((factor > 1) && (factor < BIGNUM_RADIX_ROOT)); + while (scan < end) + { + two_digits = (*scan); + product_low = ((factor * (HD_LOW (two_digits))) + (HD_LOW (carry))); + product_high = + ((factor * (HD_HIGH (two_digits))) + + (HD_HIGH (product_low)) + + (HD_HIGH (carry))); + (*scan++) = (HD_CONS ((HD_LOW (product_high)), (HD_LOW (product_low)))); + carry = (HD_HIGH (product_high)); + } + /* A carry here would be an overflow, i.e. it would not fit. + Hopefully the callers allocate enough space that this will + never happen. + */ + BIGNUM_ASSERT (carry == 0); + return; #undef product_high } @@ -803,129 +803,129 @@ void factorvm::bignum_divide_unsigned_large_denominator(bignum * numerator, bign { GC_BIGNUM(numerator,this); GC_BIGNUM(denominator,this); - bignum_length_type length_n = ((BIGNUM_LENGTH (numerator)) + 1); - bignum_length_type length_d = (BIGNUM_LENGTH (denominator)); - - bignum * q = - ((quotient != ((bignum * *) 0)) - ? (allot_bignum ((length_n - length_d), q_negative_p)) - : BIGNUM_OUT_OF_BAND); - GC_BIGNUM(q,this); + bignum_length_type length_n = ((BIGNUM_LENGTH (numerator)) + 1); + bignum_length_type length_d = (BIGNUM_LENGTH (denominator)); + + bignum * q = + ((quotient != ((bignum * *) 0)) + ? (allot_bignum ((length_n - length_d), q_negative_p)) + : BIGNUM_OUT_OF_BAND); + GC_BIGNUM(q,this); - bignum * u = (allot_bignum (length_n, r_negative_p)); - GC_BIGNUM(u,this); + bignum * u = (allot_bignum (length_n, r_negative_p)); + GC_BIGNUM(u,this); - int shift = 0; - BIGNUM_ASSERT (length_d > 1); - { - bignum_digit_type v1 = (BIGNUM_REF ((denominator), (length_d - 1))); - while (v1 < (BIGNUM_RADIX / 2)) - { - v1 <<= 1; - shift += 1; - } - } - if (shift == 0) - { - bignum_destructive_copy (numerator, u); - (BIGNUM_REF (u, (length_n - 1))) = 0; - bignum_divide_unsigned_normalized (u, denominator, q); - } - else - { - bignum * v = (allot_bignum (length_d, 0)); - - bignum_destructive_normalization (numerator, u, shift); - bignum_destructive_normalization (denominator, v, shift); - bignum_divide_unsigned_normalized (u, v, q); - if (remainder != ((bignum * *) 0)) - bignum_destructive_unnormalization (u, shift); - } - - if(q) - q = bignum_trim (q); - - u = bignum_trim (u); - - if (quotient != ((bignum * *) 0)) - (*quotient) = q; - - if (remainder != ((bignum * *) 0)) - (*remainder) = u; - - return; + int shift = 0; + BIGNUM_ASSERT (length_d > 1); + { + bignum_digit_type v1 = (BIGNUM_REF ((denominator), (length_d - 1))); + while (v1 < (BIGNUM_RADIX / 2)) + { + v1 <<= 1; + shift += 1; + } + } + if (shift == 0) + { + bignum_destructive_copy (numerator, u); + (BIGNUM_REF (u, (length_n - 1))) = 0; + bignum_divide_unsigned_normalized (u, denominator, q); + } + else + { + bignum * v = (allot_bignum (length_d, 0)); + + bignum_destructive_normalization (numerator, u, shift); + bignum_destructive_normalization (denominator, v, shift); + bignum_divide_unsigned_normalized (u, v, q); + if (remainder != ((bignum * *) 0)) + bignum_destructive_unnormalization (u, shift); + } + + if(q) + q = bignum_trim (q); + + u = bignum_trim (u); + + if (quotient != ((bignum * *) 0)) + (*quotient) = q; + + if (remainder != ((bignum * *) 0)) + (*remainder) = u; + + return; } void factorvm::bignum_divide_unsigned_normalized(bignum * u, bignum * v, bignum * q) { - bignum_length_type u_length = (BIGNUM_LENGTH (u)); - bignum_length_type v_length = (BIGNUM_LENGTH (v)); - bignum_digit_type * u_start = (BIGNUM_START_PTR (u)); - bignum_digit_type * u_scan = (u_start + u_length); - bignum_digit_type * u_scan_limit = (u_start + v_length); - bignum_digit_type * u_scan_start = (u_scan - v_length); - bignum_digit_type * v_start = (BIGNUM_START_PTR (v)); - bignum_digit_type * v_end = (v_start + v_length); - bignum_digit_type * q_scan = NULL; - bignum_digit_type v1 = (v_end[-1]); - bignum_digit_type v2 = (v_end[-2]); - bignum_digit_type ph; /* high half of double-digit product */ - bignum_digit_type pl; /* low half of double-digit product */ - bignum_digit_type guess; - bignum_digit_type gh; /* high half-digit of guess */ - bignum_digit_type ch; /* high half of double-digit comparand */ - bignum_digit_type v2l = (HD_LOW (v2)); - bignum_digit_type v2h = (HD_HIGH (v2)); - bignum_digit_type cl; /* low half of double-digit comparand */ + bignum_length_type u_length = (BIGNUM_LENGTH (u)); + bignum_length_type v_length = (BIGNUM_LENGTH (v)); + bignum_digit_type * u_start = (BIGNUM_START_PTR (u)); + bignum_digit_type * u_scan = (u_start + u_length); + bignum_digit_type * u_scan_limit = (u_start + v_length); + bignum_digit_type * u_scan_start = (u_scan - v_length); + bignum_digit_type * v_start = (BIGNUM_START_PTR (v)); + bignum_digit_type * v_end = (v_start + v_length); + bignum_digit_type * q_scan = NULL; + bignum_digit_type v1 = (v_end[-1]); + bignum_digit_type v2 = (v_end[-2]); + bignum_digit_type ph; /* high half of double-digit product */ + bignum_digit_type pl; /* low half of double-digit product */ + bignum_digit_type guess; + bignum_digit_type gh; /* high half-digit of guess */ + bignum_digit_type ch; /* high half of double-digit comparand */ + bignum_digit_type v2l = (HD_LOW (v2)); + bignum_digit_type v2h = (HD_HIGH (v2)); + bignum_digit_type cl; /* low half of double-digit comparand */ #define gl ph /* low half-digit of guess */ #define uj pl #define qj ph - bignum_digit_type gm; /* memory loc for reference parameter */ - if (q != BIGNUM_OUT_OF_BAND) - q_scan = ((BIGNUM_START_PTR (q)) + (BIGNUM_LENGTH (q))); - while (u_scan_limit < u_scan) - { - uj = (*--u_scan); - if (uj != v1) - { - /* comparand = - (((((uj * BIGNUM_RADIX) + uj1) % v1) * BIGNUM_RADIX) + uj2); - guess = (((uj * BIGNUM_RADIX) + uj1) / v1); */ - cl = (u_scan[-2]); - ch = (bignum_digit_divide (uj, (u_scan[-1]), v1, (&gm))); - guess = gm; - } - else - { - cl = (u_scan[-2]); - ch = ((u_scan[-1]) + v1); - guess = (BIGNUM_RADIX - 1); - } - while (1) - { - /* product = (guess * v2); */ - gl = (HD_LOW (guess)); - gh = (HD_HIGH (guess)); - pl = (v2l * gl); - ph = ((v2l * gh) + (v2h * gl) + (HD_HIGH (pl))); - pl = (HD_CONS ((HD_LOW (ph)), (HD_LOW (pl)))); - ph = ((v2h * gh) + (HD_HIGH (ph))); - /* if (comparand >= product) */ - if ((ch > ph) || ((ch == ph) && (cl >= pl))) - break; - guess -= 1; - /* comparand += (v1 << BIGNUM_DIGIT_LENGTH) */ - ch += v1; - /* if (comparand >= (BIGNUM_RADIX * BIGNUM_RADIX)) */ - if (ch >= BIGNUM_RADIX) - break; - } - qj = (bignum_divide_subtract (v_start, v_end, guess, (--u_scan_start))); - if (q != BIGNUM_OUT_OF_BAND) - (*--q_scan) = qj; - } - return; + bignum_digit_type gm; /* memory loc for reference parameter */ + if (q != BIGNUM_OUT_OF_BAND) + q_scan = ((BIGNUM_START_PTR (q)) + (BIGNUM_LENGTH (q))); + while (u_scan_limit < u_scan) + { + uj = (*--u_scan); + if (uj != v1) + { + /* comparand = + (((((uj * BIGNUM_RADIX) + uj1) % v1) * BIGNUM_RADIX) + uj2); + guess = (((uj * BIGNUM_RADIX) + uj1) / v1); */ + cl = (u_scan[-2]); + ch = (bignum_digit_divide (uj, (u_scan[-1]), v1, (&gm))); + guess = gm; + } + else + { + cl = (u_scan[-2]); + ch = ((u_scan[-1]) + v1); + guess = (BIGNUM_RADIX - 1); + } + while (1) + { + /* product = (guess * v2); */ + gl = (HD_LOW (guess)); + gh = (HD_HIGH (guess)); + pl = (v2l * gl); + ph = ((v2l * gh) + (v2h * gl) + (HD_HIGH (pl))); + pl = (HD_CONS ((HD_LOW (ph)), (HD_LOW (pl)))); + ph = ((v2h * gh) + (HD_HIGH (ph))); + /* if (comparand >= product) */ + if ((ch > ph) || ((ch == ph) && (cl >= pl))) + break; + guess -= 1; + /* comparand += (v1 << BIGNUM_DIGIT_LENGTH) */ + ch += v1; + /* if (comparand >= (BIGNUM_RADIX * BIGNUM_RADIX)) */ + if (ch >= BIGNUM_RADIX) + break; + } + qj = (bignum_divide_subtract (v_start, v_end, guess, (--u_scan_start))); + if (q != BIGNUM_OUT_OF_BAND) + (*--q_scan) = qj; + } + return; #undef gl #undef uj #undef qj @@ -934,77 +934,77 @@ void factorvm::bignum_divide_unsigned_normalized(bignum * u, bignum * v, bignum bignum_digit_type factorvm::bignum_divide_subtract(bignum_digit_type * v_start, bignum_digit_type * v_end, bignum_digit_type guess, bignum_digit_type * u_start) { - bignum_digit_type * v_scan = v_start; - bignum_digit_type * u_scan = u_start; - bignum_digit_type carry = 0; - if (guess == 0) return (0); - { - bignum_digit_type gl = (HD_LOW (guess)); - bignum_digit_type gh = (HD_HIGH (guess)); - bignum_digit_type v; - bignum_digit_type pl; - bignum_digit_type vl; + bignum_digit_type * v_scan = v_start; + bignum_digit_type * u_scan = u_start; + bignum_digit_type carry = 0; + if (guess == 0) return (0); + { + bignum_digit_type gl = (HD_LOW (guess)); + bignum_digit_type gh = (HD_HIGH (guess)); + bignum_digit_type v; + bignum_digit_type pl; + bignum_digit_type vl; #define vh v #define ph carry #define diff pl - while (v_scan < v_end) - { - v = (*v_scan++); - vl = (HD_LOW (v)); - vh = (HD_HIGH (v)); - pl = ((vl * gl) + (HD_LOW (carry))); - ph = ((vl * gh) + (vh * gl) + (HD_HIGH (pl)) + (HD_HIGH (carry))); - diff = ((*u_scan) - (HD_CONS ((HD_LOW (ph)), (HD_LOW (pl))))); - if (diff < 0) - { - (*u_scan++) = (diff + BIGNUM_RADIX); - carry = ((vh * gh) + (HD_HIGH (ph)) + 1); - } - else - { - (*u_scan++) = diff; - carry = ((vh * gh) + (HD_HIGH (ph))); - } - } - if (carry == 0) - return (guess); - diff = ((*u_scan) - carry); - if (diff < 0) - (*u_scan) = (diff + BIGNUM_RADIX); - else - { - (*u_scan) = diff; - return (guess); - } + while (v_scan < v_end) + { + v = (*v_scan++); + vl = (HD_LOW (v)); + vh = (HD_HIGH (v)); + pl = ((vl * gl) + (HD_LOW (carry))); + ph = ((vl * gh) + (vh * gl) + (HD_HIGH (pl)) + (HD_HIGH (carry))); + diff = ((*u_scan) - (HD_CONS ((HD_LOW (ph)), (HD_LOW (pl))))); + if (diff < 0) + { + (*u_scan++) = (diff + BIGNUM_RADIX); + carry = ((vh * gh) + (HD_HIGH (ph)) + 1); + } + else + { + (*u_scan++) = diff; + carry = ((vh * gh) + (HD_HIGH (ph))); + } + } + if (carry == 0) + return (guess); + diff = ((*u_scan) - carry); + if (diff < 0) + (*u_scan) = (diff + BIGNUM_RADIX); + else + { + (*u_scan) = diff; + return (guess); + } #undef vh #undef ph #undef diff - } - /* Subtraction generated carry, implying guess is one too large. - Add v back in to bring it back down. */ - v_scan = v_start; - u_scan = u_start; - carry = 0; - while (v_scan < v_end) - { - bignum_digit_type sum = ((*v_scan++) + (*u_scan) + carry); - if (sum < BIGNUM_RADIX) - { - (*u_scan++) = sum; - carry = 0; - } - else - { - (*u_scan++) = (sum - BIGNUM_RADIX); - carry = 1; - } - } - if (carry == 1) - { - bignum_digit_type sum = ((*u_scan) + carry); - (*u_scan) = ((sum < BIGNUM_RADIX) ? sum : (sum - BIGNUM_RADIX)); - } - return (guess - 1); + } + /* Subtraction generated carry, implying guess is one too large. + Add v back in to bring it back down. */ + v_scan = v_start; + u_scan = u_start; + carry = 0; + while (v_scan < v_end) + { + bignum_digit_type sum = ((*v_scan++) + (*u_scan) + carry); + if (sum < BIGNUM_RADIX) + { + (*u_scan++) = sum; + carry = 0; + } + else + { + (*u_scan++) = (sum - BIGNUM_RADIX); + carry = 1; + } + } + if (carry == 1) + { + bignum_digit_type sum = ((*u_scan) + carry); + (*u_scan) = ((sum < BIGNUM_RADIX) ? sum : (sum - BIGNUM_RADIX)); + } + return (guess - 1); } @@ -1013,101 +1013,101 @@ void factorvm::bignum_divide_unsigned_medium_denominator(bignum * numerator,bign { GC_BIGNUM(numerator,this); - bignum_length_type length_n = (BIGNUM_LENGTH (numerator)); - bignum_length_type length_q; - bignum * q = NULL; - GC_BIGNUM(q,this); + bignum_length_type length_n = (BIGNUM_LENGTH (numerator)); + bignum_length_type length_q; + bignum * q = NULL; + GC_BIGNUM(q,this); - int shift = 0; - /* Because `bignum_digit_divide' requires a normalized denominator. */ - while (denominator < (BIGNUM_RADIX / 2)) - { - denominator <<= 1; - shift += 1; - } - if (shift == 0) - { - length_q = length_n; - - q = (allot_bignum (length_q, q_negative_p)); - bignum_destructive_copy (numerator, q); - } - else - { - length_q = (length_n + 1); - - q = (allot_bignum (length_q, q_negative_p)); - bignum_destructive_normalization (numerator, q, shift); - } - { - bignum_digit_type r = 0; - bignum_digit_type * start = (BIGNUM_START_PTR (q)); - bignum_digit_type * scan = (start + length_q); - bignum_digit_type qj; - - while (start < scan) - { - r = (bignum_digit_divide (r, (*--scan), denominator, (&qj))); - (*scan) = qj; - } - - q = bignum_trim (q); - - if (remainder != ((bignum * *) 0)) - { - if (shift != 0) - r >>= shift; - - (*remainder) = (bignum_digit_to_bignum (r, r_negative_p)); - } - - if (quotient != ((bignum * *) 0)) - (*quotient) = q; - } - return; + int shift = 0; + /* Because `bignum_digit_divide' requires a normalized denominator. */ + while (denominator < (BIGNUM_RADIX / 2)) + { + denominator <<= 1; + shift += 1; + } + if (shift == 0) + { + length_q = length_n; + + q = (allot_bignum (length_q, q_negative_p)); + bignum_destructive_copy (numerator, q); + } + else + { + length_q = (length_n + 1); + + q = (allot_bignum (length_q, q_negative_p)); + bignum_destructive_normalization (numerator, q, shift); + } + { + bignum_digit_type r = 0; + bignum_digit_type * start = (BIGNUM_START_PTR (q)); + bignum_digit_type * scan = (start + length_q); + bignum_digit_type qj; + + while (start < scan) + { + r = (bignum_digit_divide (r, (*--scan), denominator, (&qj))); + (*scan) = qj; + } + + q = bignum_trim (q); + + if (remainder != ((bignum * *) 0)) + { + if (shift != 0) + r >>= shift; + + (*remainder) = (bignum_digit_to_bignum (r, r_negative_p)); + } + + if (quotient != ((bignum * *) 0)) + (*quotient) = q; + } + return; } void factorvm::bignum_destructive_normalization(bignum * source, bignum * target, int shift_left) { - bignum_digit_type digit; - bignum_digit_type * scan_source = (BIGNUM_START_PTR (source)); - bignum_digit_type carry = 0; - bignum_digit_type * scan_target = (BIGNUM_START_PTR (target)); - bignum_digit_type * end_source = (scan_source + (BIGNUM_LENGTH (source))); - bignum_digit_type * end_target = (scan_target + (BIGNUM_LENGTH (target))); - int shift_right = (BIGNUM_DIGIT_LENGTH - shift_left); - bignum_digit_type mask = (((cell)1 << shift_right) - 1); - while (scan_source < end_source) - { - digit = (*scan_source++); - (*scan_target++) = (((digit & mask) << shift_left) | carry); - carry = (digit >> shift_right); - } - if (scan_target < end_target) - (*scan_target) = carry; - else - BIGNUM_ASSERT (carry == 0); - return; + bignum_digit_type digit; + bignum_digit_type * scan_source = (BIGNUM_START_PTR (source)); + bignum_digit_type carry = 0; + bignum_digit_type * scan_target = (BIGNUM_START_PTR (target)); + bignum_digit_type * end_source = (scan_source + (BIGNUM_LENGTH (source))); + bignum_digit_type * end_target = (scan_target + (BIGNUM_LENGTH (target))); + int shift_right = (BIGNUM_DIGIT_LENGTH - shift_left); + bignum_digit_type mask = (((cell)1 << shift_right) - 1); + while (scan_source < end_source) + { + digit = (*scan_source++); + (*scan_target++) = (((digit & mask) << shift_left) | carry); + carry = (digit >> shift_right); + } + if (scan_target < end_target) + (*scan_target) = carry; + else + BIGNUM_ASSERT (carry == 0); + return; } void factorvm::bignum_destructive_unnormalization(bignum * bignum, int shift_right) { - bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); - bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); - bignum_digit_type digit; - bignum_digit_type carry = 0; - int shift_left = (BIGNUM_DIGIT_LENGTH - shift_right); - bignum_digit_type mask = (((fixnum)1 << shift_right) - 1); - while (start < scan) - { - digit = (*--scan); - (*scan) = ((digit >> shift_right) | carry); - carry = ((digit & mask) << shift_left); - } - BIGNUM_ASSERT (carry == 0); - return; + bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); + bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); + bignum_digit_type digit; + bignum_digit_type carry = 0; + int shift_left = (BIGNUM_DIGIT_LENGTH - shift_right); + bignum_digit_type mask = (((fixnum)1 << shift_right) - 1); + while (start < scan) + { + digit = (*--scan); + (*scan) = ((digit >> shift_right) | carry); + carry = ((digit & mask) << shift_left); + } + BIGNUM_ASSERT (carry == 0); + return; } @@ -1115,128 +1115,128 @@ void factorvm::bignum_destructive_unnormalization(bignum * bignum, int shift_rig case of dividing two bignum digits by one bignum digit. It is assumed that the numerator, denominator are normalized. */ -#define BDD_STEP(qn, j) \ -{ \ - uj = (u[j]); \ - if (uj != v1) \ - { \ - uj_uj1 = (HD_CONS (uj, (u[j + 1]))); \ - guess = (uj_uj1 / v1); \ - comparand = (HD_CONS ((uj_uj1 % v1), (u[j + 2]))); \ - } \ - else \ - { \ - guess = (BIGNUM_RADIX_ROOT - 1); \ - comparand = (HD_CONS (((u[j + 1]) + v1), (u[j + 2]))); \ - } \ - while ((guess * v2) > comparand) \ - { \ - guess -= 1; \ - comparand += (v1 << BIGNUM_HALF_DIGIT_LENGTH); \ - if (comparand >= BIGNUM_RADIX) \ - break; \ - } \ - qn = (bignum_digit_divide_subtract (v1, v2, guess, (&u[j]))); \ +#define BDD_STEP(qn, j) \ +{ \ + uj = (u[j]); \ + if (uj != v1) \ + { \ + uj_uj1 = (HD_CONS (uj, (u[j + 1]))); \ + guess = (uj_uj1 / v1); \ + comparand = (HD_CONS ((uj_uj1 % v1), (u[j + 2]))); \ + } \ + else \ + { \ + guess = (BIGNUM_RADIX_ROOT - 1); \ + comparand = (HD_CONS (((u[j + 1]) + v1), (u[j + 2]))); \ + } \ + while ((guess * v2) > comparand) \ + { \ + guess -= 1; \ + comparand += (v1 << BIGNUM_HALF_DIGIT_LENGTH); \ + if (comparand >= BIGNUM_RADIX) \ + break; \ + } \ + qn = (bignum_digit_divide_subtract (v1, v2, guess, (&u[j]))); \ } bignum_digit_type factorvm::bignum_digit_divide(bignum_digit_type uh, bignum_digit_type ul, bignum_digit_type v, bignum_digit_type * q) /* return value */ { - bignum_digit_type guess; - bignum_digit_type comparand; - bignum_digit_type v1 = (HD_HIGH (v)); - bignum_digit_type v2 = (HD_LOW (v)); - bignum_digit_type uj; - bignum_digit_type uj_uj1; - bignum_digit_type q1; - bignum_digit_type q2; - bignum_digit_type u [4]; - if (uh == 0) - { - if (ul < v) - { - (*q) = 0; - return (ul); - } - else if (ul == v) - { - (*q) = 1; - return (0); - } - } - (u[0]) = (HD_HIGH (uh)); - (u[1]) = (HD_LOW (uh)); - (u[2]) = (HD_HIGH (ul)); - (u[3]) = (HD_LOW (ul)); - v1 = (HD_HIGH (v)); - v2 = (HD_LOW (v)); - BDD_STEP (q1, 0); - BDD_STEP (q2, 1); - (*q) = (HD_CONS (q1, q2)); - return (HD_CONS ((u[2]), (u[3]))); + bignum_digit_type guess; + bignum_digit_type comparand; + bignum_digit_type v1 = (HD_HIGH (v)); + bignum_digit_type v2 = (HD_LOW (v)); + bignum_digit_type uj; + bignum_digit_type uj_uj1; + bignum_digit_type q1; + bignum_digit_type q2; + bignum_digit_type u [4]; + if (uh == 0) + { + if (ul < v) + { + (*q) = 0; + return (ul); + } + else if (ul == v) + { + (*q) = 1; + return (0); + } + } + (u[0]) = (HD_HIGH (uh)); + (u[1]) = (HD_LOW (uh)); + (u[2]) = (HD_HIGH (ul)); + (u[3]) = (HD_LOW (ul)); + v1 = (HD_HIGH (v)); + v2 = (HD_LOW (v)); + BDD_STEP (q1, 0); + BDD_STEP (q2, 1); + (*q) = (HD_CONS (q1, q2)); + return (HD_CONS ((u[2]), (u[3]))); } #undef BDD_STEP -#define BDDS_MULSUB(vn, un, carry_in) \ -{ \ - product = ((vn * guess) + carry_in); \ - diff = (un - (HD_LOW (product))); \ - if (diff < 0) \ - { \ - un = (diff + BIGNUM_RADIX_ROOT); \ - carry = ((HD_HIGH (product)) + 1); \ - } \ - else \ - { \ - un = diff; \ - carry = (HD_HIGH (product)); \ - } \ +#define BDDS_MULSUB(vn, un, carry_in) \ +{ \ + product = ((vn * guess) + carry_in); \ + diff = (un - (HD_LOW (product))); \ + if (diff < 0) \ + { \ + un = (diff + BIGNUM_RADIX_ROOT); \ + carry = ((HD_HIGH (product)) + 1); \ + } \ + else \ + { \ + un = diff; \ + carry = (HD_HIGH (product)); \ + } \ } -#define BDDS_ADD(vn, un, carry_in) \ -{ \ - sum = (vn + un + carry_in); \ - if (sum < BIGNUM_RADIX_ROOT) \ - { \ - un = sum; \ - carry = 0; \ - } \ - else \ - { \ - un = (sum - BIGNUM_RADIX_ROOT); \ - carry = 1; \ - } \ +#define BDDS_ADD(vn, un, carry_in) \ +{ \ + sum = (vn + un + carry_in); \ + if (sum < BIGNUM_RADIX_ROOT) \ + { \ + un = sum; \ + carry = 0; \ + } \ + else \ + { \ + un = (sum - BIGNUM_RADIX_ROOT); \ + carry = 1; \ + } \ } bignum_digit_type factorvm::bignum_digit_divide_subtract(bignum_digit_type v1, bignum_digit_type v2, bignum_digit_type guess, bignum_digit_type * u) { - { - bignum_digit_type product; - bignum_digit_type diff; - bignum_digit_type carry; - BDDS_MULSUB (v2, (u[2]), 0); - BDDS_MULSUB (v1, (u[1]), carry); - if (carry == 0) - return (guess); - diff = ((u[0]) - carry); - if (diff < 0) - (u[0]) = (diff + BIGNUM_RADIX); - else - { - (u[0]) = diff; - return (guess); - } - } - { - bignum_digit_type sum; - bignum_digit_type carry; - BDDS_ADD(v2, (u[2]), 0); - BDDS_ADD(v1, (u[1]), carry); - if (carry == 1) - (u[0]) += 1; - } - return (guess - 1); + { + bignum_digit_type product; + bignum_digit_type diff; + bignum_digit_type carry; + BDDS_MULSUB (v2, (u[2]), 0); + BDDS_MULSUB (v1, (u[1]), carry); + if (carry == 0) + return (guess); + diff = ((u[0]) - carry); + if (diff < 0) + (u[0]) = (diff + BIGNUM_RADIX); + else + { + (u[0]) = diff; + return (guess); + } + } + { + bignum_digit_type sum; + bignum_digit_type carry; + BDDS_ADD(v2, (u[2]), 0); + BDDS_ADD(v1, (u[1]), carry); + if (carry == 1) + (u[0]) += 1; + } + return (guess - 1); } @@ -1248,19 +1248,19 @@ void factorvm::bignum_divide_unsigned_small_denominator(bignum * numerator, bign { GC_BIGNUM(numerator,this); - bignum * q = (bignum_new_sign (numerator, q_negative_p)); - GC_BIGNUM(q,this); + bignum * q = (bignum_new_sign (numerator, q_negative_p)); + GC_BIGNUM(q,this); - bignum_digit_type r = (bignum_destructive_scale_down (q, denominator)); + bignum_digit_type r = (bignum_destructive_scale_down (q, denominator)); - q = (bignum_trim (q)); + q = (bignum_trim (q)); - if (remainder != ((bignum * *) 0)) - (*remainder) = (bignum_digit_to_bignum (r, r_negative_p)); + if (remainder != ((bignum * *) 0)) + (*remainder) = (bignum_digit_to_bignum (r, r_negative_p)); - (*quotient) = q; + (*quotient) = q; - return; + return; } @@ -1270,23 +1270,23 @@ void factorvm::bignum_divide_unsigned_small_denominator(bignum * numerator, bign bignum_digit_type factorvm::bignum_destructive_scale_down(bignum * bignum, bignum_digit_type denominator) { - bignum_digit_type numerator; - bignum_digit_type remainder = 0; - bignum_digit_type two_digits; + bignum_digit_type numerator; + bignum_digit_type remainder = 0; + bignum_digit_type two_digits; #define quotient_high remainder - bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); - bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); - BIGNUM_ASSERT ((denominator > 1) && (denominator < BIGNUM_RADIX_ROOT)); - while (start < scan) - { - two_digits = (*--scan); - numerator = (HD_CONS (remainder, (HD_HIGH (two_digits)))); - quotient_high = (numerator / denominator); - numerator = (HD_CONS ((numerator % denominator), (HD_LOW (two_digits)))); - (*scan) = (HD_CONS (quotient_high, (numerator / denominator))); - remainder = (numerator % denominator); - } - return (remainder); + bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); + bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum))); + BIGNUM_ASSERT ((denominator > 1) && (denominator < BIGNUM_RADIX_ROOT)); + while (start < scan) + { + two_digits = (*--scan); + numerator = (HD_CONS (remainder, (HD_HIGH (two_digits)))); + quotient_high = (numerator / denominator); + numerator = (HD_CONS ((numerator % denominator), (HD_LOW (two_digits)))); + (*scan) = (HD_CONS (quotient_high, (numerator / denominator))); + remainder = (numerator % denominator); + } + return (remainder); #undef quotient_high } @@ -1294,92 +1294,92 @@ bignum_digit_type factorvm::bignum_destructive_scale_down(bignum * bignum, bignu /* allocates memory */ bignum * factorvm::bignum_remainder_unsigned_small_denominator(bignum * n, bignum_digit_type d, int negative_p) { - bignum_digit_type two_digits; - bignum_digit_type * start = (BIGNUM_START_PTR (n)); - bignum_digit_type * scan = (start + (BIGNUM_LENGTH (n))); - bignum_digit_type r = 0; - BIGNUM_ASSERT ((d > 1) && (d < BIGNUM_RADIX_ROOT)); - while (start < scan) - { - two_digits = (*--scan); - r = - ((HD_CONS (((HD_CONS (r, (HD_HIGH (two_digits)))) % d), - (HD_LOW (two_digits)))) - % d); - } - return (bignum_digit_to_bignum (r, negative_p)); + bignum_digit_type two_digits; + bignum_digit_type * start = (BIGNUM_START_PTR (n)); + bignum_digit_type * scan = (start + (BIGNUM_LENGTH (n))); + bignum_digit_type r = 0; + BIGNUM_ASSERT ((d > 1) && (d < BIGNUM_RADIX_ROOT)); + while (start < scan) + { + two_digits = (*--scan); + r = + ((HD_CONS (((HD_CONS (r, (HD_HIGH (two_digits)))) % d), + (HD_LOW (two_digits)))) + % d); + } + return (bignum_digit_to_bignum (r, negative_p)); } /* allocates memory */ bignum *factorvm::bignum_digit_to_bignum(bignum_digit_type digit, int negative_p) { - if (digit == 0) - return (BIGNUM_ZERO ()); - else - { - bignum * result = (allot_bignum (1, negative_p)); - (BIGNUM_REF (result, 0)) = digit; - return (result); - } + if (digit == 0) + return (BIGNUM_ZERO ()); + else + { + bignum * result = (allot_bignum (1, negative_p)); + (BIGNUM_REF (result, 0)) = digit; + return (result); + } } /* allocates memory */ bignum *factorvm::allot_bignum(bignum_length_type length, int negative_p) { - BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX)); - bignum * result = allot_array_internal(length + 1); - BIGNUM_SET_NEGATIVE_P (result, negative_p); - return (result); + BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX)); + bignum * result = allot_array_internal(length + 1); + BIGNUM_SET_NEGATIVE_P (result, negative_p); + return (result); } /* allocates memory */ bignum * factorvm::allot_bignum_zeroed(bignum_length_type length, int negative_p) { - bignum * result = allot_bignum(length,negative_p); - bignum_digit_type * scan = (BIGNUM_START_PTR (result)); - bignum_digit_type * end = (scan + length); - while (scan < end) - (*scan++) = 0; - return (result); + bignum * result = allot_bignum(length,negative_p); + bignum_digit_type * scan = (BIGNUM_START_PTR (result)); + bignum_digit_type * end = (scan + length); + while (scan < end) + (*scan++) = 0; + return (result); } -#define BIGNUM_REDUCE_LENGTH(source, length) \ - source = reallot_array(source,length + 1) +#define BIGNUM_REDUCE_LENGTH(source, length) \ +source = reallot_array(source,length + 1) /* allocates memory */ bignum *factorvm::bignum_shorten_length(bignum * bignum, bignum_length_type length) { - bignum_length_type current_length = (BIGNUM_LENGTH (bignum)); - BIGNUM_ASSERT ((length >= 0) || (length <= current_length)); - if (length < current_length) - { - BIGNUM_REDUCE_LENGTH (bignum, length); - BIGNUM_SET_NEGATIVE_P (bignum, (length != 0) && (BIGNUM_NEGATIVE_P (bignum))); - } - return (bignum); + bignum_length_type current_length = (BIGNUM_LENGTH (bignum)); + BIGNUM_ASSERT ((length >= 0) || (length <= current_length)); + if (length < current_length) + { + BIGNUM_REDUCE_LENGTH (bignum, length); + BIGNUM_SET_NEGATIVE_P (bignum, (length != 0) && (BIGNUM_NEGATIVE_P (bignum))); + } + return (bignum); } /* allocates memory */ bignum *factorvm::bignum_trim(bignum * bignum) { - bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); - bignum_digit_type * end = (start + (BIGNUM_LENGTH (bignum))); - bignum_digit_type * scan = end; - while ((start <= scan) && ((*--scan) == 0)) - ; - scan += 1; - if (scan < end) - { - bignum_length_type length = (scan - start); - BIGNUM_REDUCE_LENGTH (bignum, length); - BIGNUM_SET_NEGATIVE_P (bignum, (length != 0) && (BIGNUM_NEGATIVE_P (bignum))); - } - return (bignum); + bignum_digit_type * start = (BIGNUM_START_PTR (bignum)); + bignum_digit_type * end = (start + (BIGNUM_LENGTH (bignum))); + bignum_digit_type * scan = end; + while ((start <= scan) && ((*--scan) == 0)) + ; + scan += 1; + if (scan < end) + { + bignum_length_type length = (scan - start); + BIGNUM_REDUCE_LENGTH (bignum, length); + BIGNUM_SET_NEGATIVE_P (bignum, (length != 0) && (BIGNUM_NEGATIVE_P (bignum))); + } + return (bignum); } @@ -1389,37 +1389,37 @@ bignum *factorvm::bignum_trim(bignum * bignum) bignum *factorvm::bignum_new_sign(bignum * x, int negative_p) { GC_BIGNUM(x,this); - bignum * result = (allot_bignum ((BIGNUM_LENGTH (x)), negative_p)); + bignum * result = (allot_bignum ((BIGNUM_LENGTH (x)), negative_p)); - bignum_destructive_copy (x, result); - return (result); + bignum_destructive_copy (x, result); + return (result); } /* allocates memory */ bignum *factorvm::bignum_maybe_new_sign(bignum * x, int negative_p) { - if ((BIGNUM_NEGATIVE_P (x)) ? negative_p : (! negative_p)) - return (x); - else - { - bignum * result = - (allot_bignum ((BIGNUM_LENGTH (x)), negative_p)); - bignum_destructive_copy (x, result); - return (result); - } + if ((BIGNUM_NEGATIVE_P (x)) ? negative_p : (! negative_p)) + return (x); + else + { + bignum * result = + (allot_bignum ((BIGNUM_LENGTH (x)), negative_p)); + bignum_destructive_copy (x, result); + return (result); + } } void factorvm::bignum_destructive_copy(bignum * source, bignum * target) { - bignum_digit_type * scan_source = (BIGNUM_START_PTR (source)); - bignum_digit_type * end_source = - (scan_source + (BIGNUM_LENGTH (source))); - bignum_digit_type * scan_target = (BIGNUM_START_PTR (target)); - while (scan_source < end_source) - (*scan_target++) = (*scan_source++); - return; + bignum_digit_type * scan_source = (BIGNUM_START_PTR (source)); + bignum_digit_type * end_source = + (scan_source + (BIGNUM_LENGTH (source))); + bignum_digit_type * scan_target = (BIGNUM_START_PTR (target)); + while (scan_source < end_source) + (*scan_target++) = (*scan_source++); + return; } @@ -1430,17 +1430,17 @@ void factorvm::bignum_destructive_copy(bignum * source, bignum * target) /* allocates memory */ bignum *factorvm::bignum_bitwise_not(bignum * x) { - return bignum_subtract(BIGNUM_ONE(1), x); + return bignum_subtract(BIGNUM_ONE(1), x); } /* allocates memory */ bignum *factorvm::bignum_arithmetic_shift(bignum * arg1, fixnum n) { - if (BIGNUM_NEGATIVE_P(arg1) && n < 0) - return bignum_bitwise_not(bignum_magnitude_ash(bignum_bitwise_not(arg1), n)); - else - return bignum_magnitude_ash(arg1, n); + if (BIGNUM_NEGATIVE_P(arg1) && n < 0) + return bignum_bitwise_not(bignum_magnitude_ash(bignum_bitwise_not(arg1), n)); + else + return bignum_magnitude_ash(arg1, n); } @@ -1451,45 +1451,45 @@ bignum *factorvm::bignum_arithmetic_shift(bignum * arg1, fixnum n) /* allocates memory */ bignum *factorvm::bignum_bitwise_and(bignum * arg1, bignum * arg2) { - return( - (BIGNUM_NEGATIVE_P (arg1)) - ? (BIGNUM_NEGATIVE_P (arg2)) + return( + (BIGNUM_NEGATIVE_P (arg1)) + ? (BIGNUM_NEGATIVE_P (arg2)) ? bignum_negneg_bitwise_op(AND_OP, arg1, arg2) : bignum_posneg_bitwise_op(AND_OP, arg2, arg1) - : (BIGNUM_NEGATIVE_P (arg2)) + : (BIGNUM_NEGATIVE_P (arg2)) ? bignum_posneg_bitwise_op(AND_OP, arg1, arg2) : bignum_pospos_bitwise_op(AND_OP, arg1, arg2) - ); + ); } /* allocates memory */ bignum *factorvm::bignum_bitwise_ior(bignum * arg1, bignum * arg2) { - return( - (BIGNUM_NEGATIVE_P (arg1)) - ? (BIGNUM_NEGATIVE_P (arg2)) + return( + (BIGNUM_NEGATIVE_P (arg1)) + ? (BIGNUM_NEGATIVE_P (arg2)) ? bignum_negneg_bitwise_op(IOR_OP, arg1, arg2) : bignum_posneg_bitwise_op(IOR_OP, arg2, arg1) - : (BIGNUM_NEGATIVE_P (arg2)) + : (BIGNUM_NEGATIVE_P (arg2)) ? bignum_posneg_bitwise_op(IOR_OP, arg1, arg2) : bignum_pospos_bitwise_op(IOR_OP, arg1, arg2) - ); + ); } /* allocates memory */ bignum *factorvm::bignum_bitwise_xor(bignum * arg1, bignum * arg2) { - return( - (BIGNUM_NEGATIVE_P (arg1)) - ? (BIGNUM_NEGATIVE_P (arg2)) + return( + (BIGNUM_NEGATIVE_P (arg1)) + ? (BIGNUM_NEGATIVE_P (arg2)) ? bignum_negneg_bitwise_op(XOR_OP, arg1, arg2) : bignum_posneg_bitwise_op(XOR_OP, arg2, arg1) - : (BIGNUM_NEGATIVE_P (arg2)) + : (BIGNUM_NEGATIVE_P (arg2)) ? bignum_posneg_bitwise_op(XOR_OP, arg1, arg2) : bignum_pospos_bitwise_op(XOR_OP, arg1, arg2) - ); + ); } @@ -1500,60 +1500,60 @@ bignum *factorvm::bignum_magnitude_ash(bignum * arg1, fixnum n) { GC_BIGNUM(arg1,this); - bignum * result = NULL; - bignum_digit_type *scan1; - bignum_digit_type *scanr; - bignum_digit_type *end; + bignum * result = NULL; + bignum_digit_type *scan1; + bignum_digit_type *scanr; + bignum_digit_type *end; - fixnum digit_offset,bit_offset; + fixnum digit_offset,bit_offset; - if (BIGNUM_ZERO_P (arg1)) return (arg1); + if (BIGNUM_ZERO_P (arg1)) return (arg1); - if (n > 0) { - digit_offset = n / BIGNUM_DIGIT_LENGTH; - bit_offset = n % BIGNUM_DIGIT_LENGTH; + if (n > 0) { + digit_offset = n / BIGNUM_DIGIT_LENGTH; + bit_offset = n % BIGNUM_DIGIT_LENGTH; - result = allot_bignum_zeroed (BIGNUM_LENGTH (arg1) + digit_offset + 1, - BIGNUM_NEGATIVE_P(arg1)); + result = allot_bignum_zeroed (BIGNUM_LENGTH (arg1) + digit_offset + 1, + BIGNUM_NEGATIVE_P(arg1)); - scanr = BIGNUM_START_PTR (result) + digit_offset; - scan1 = BIGNUM_START_PTR (arg1); - end = scan1 + BIGNUM_LENGTH (arg1); + scanr = BIGNUM_START_PTR (result) + digit_offset; + scan1 = BIGNUM_START_PTR (arg1); + end = scan1 + BIGNUM_LENGTH (arg1); - while (scan1 < end) { - *scanr = *scanr | (*scan1 & BIGNUM_DIGIT_MASK) << bit_offset; - *scanr = *scanr & BIGNUM_DIGIT_MASK; - scanr++; - *scanr = *scan1++ >> (BIGNUM_DIGIT_LENGTH - bit_offset); - *scanr = *scanr & BIGNUM_DIGIT_MASK; - } - } - else if (n < 0 - && (-n >= (BIGNUM_LENGTH (arg1) * (bignum_length_type) BIGNUM_DIGIT_LENGTH))) - result = BIGNUM_ZERO (); - - else if (n < 0) { - digit_offset = -n / BIGNUM_DIGIT_LENGTH; - bit_offset = -n % BIGNUM_DIGIT_LENGTH; + while (scan1 < end) { + *scanr = *scanr | (*scan1 & BIGNUM_DIGIT_MASK) << bit_offset; + *scanr = *scanr & BIGNUM_DIGIT_MASK; + scanr++; + *scanr = *scan1++ >> (BIGNUM_DIGIT_LENGTH - bit_offset); + *scanr = *scanr & BIGNUM_DIGIT_MASK; + } + } + else if (n < 0 + && (-n >= (BIGNUM_LENGTH (arg1) * (bignum_length_type) BIGNUM_DIGIT_LENGTH))) + result = BIGNUM_ZERO (); + + else if (n < 0) { + digit_offset = -n / BIGNUM_DIGIT_LENGTH; + bit_offset = -n % BIGNUM_DIGIT_LENGTH; - result = allot_bignum_zeroed (BIGNUM_LENGTH (arg1) - digit_offset, - BIGNUM_NEGATIVE_P(arg1)); + result = allot_bignum_zeroed (BIGNUM_LENGTH (arg1) - digit_offset, + BIGNUM_NEGATIVE_P(arg1)); - scanr = BIGNUM_START_PTR (result); - scan1 = BIGNUM_START_PTR (arg1) + digit_offset; - end = scanr + BIGNUM_LENGTH (result) - 1; + scanr = BIGNUM_START_PTR (result); + scan1 = BIGNUM_START_PTR (arg1) + digit_offset; + end = scanr + BIGNUM_LENGTH (result) - 1; - while (scanr < end) { - *scanr = (*scan1++ & BIGNUM_DIGIT_MASK) >> bit_offset ; - *scanr = (*scanr | - *scan1 << (BIGNUM_DIGIT_LENGTH - bit_offset)) & BIGNUM_DIGIT_MASK; - scanr++; - } - *scanr = (*scan1++ & BIGNUM_DIGIT_MASK) >> bit_offset ; - } - else if (n == 0) result = arg1; + while (scanr < end) { + *scanr = (*scan1++ & BIGNUM_DIGIT_MASK) >> bit_offset ; + *scanr = (*scanr | + *scan1 << (BIGNUM_DIGIT_LENGTH - bit_offset)) & BIGNUM_DIGIT_MASK; + scanr++; + } + *scanr = (*scan1++ & BIGNUM_DIGIT_MASK) >> bit_offset ; + } + else if (n == 0) result = arg1; - return (bignum_trim (result)); + return (bignum_trim (result)); } @@ -1562,33 +1562,33 @@ bignum *factorvm::bignum_pospos_bitwise_op(int op, bignum * arg1, bignum * arg2) { GC_BIGNUM(arg1,this); GC_BIGNUM(arg2,this); - bignum * result; - bignum_length_type max_length; - - bignum_digit_type *scan1, *end1, digit1; - bignum_digit_type *scan2, *end2, digit2; - bignum_digit_type *scanr, *endr; - - max_length = (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2)) - ? BIGNUM_LENGTH(arg1) : BIGNUM_LENGTH(arg2); - - result = allot_bignum(max_length, 0); - - scanr = BIGNUM_START_PTR(result); - scan1 = BIGNUM_START_PTR(arg1); - scan2 = BIGNUM_START_PTR(arg2); - endr = scanr + max_length; - end1 = scan1 + BIGNUM_LENGTH(arg1); - end2 = scan2 + BIGNUM_LENGTH(arg2); - - while (scanr < endr) { - digit1 = (scan1 < end1) ? *scan1++ : 0; - digit2 = (scan2 < end2) ? *scan2++ : 0; - *scanr++ = (op == AND_OP) ? digit1 & digit2 : - (op == IOR_OP) ? digit1 | digit2 : - digit1 ^ digit2; - } - return bignum_trim(result); + bignum * result; + bignum_length_type max_length; + + bignum_digit_type *scan1, *end1, digit1; + bignum_digit_type *scan2, *end2, digit2; + bignum_digit_type *scanr, *endr; + + max_length = (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2)) + ? BIGNUM_LENGTH(arg1) : BIGNUM_LENGTH(arg2); + + result = allot_bignum(max_length, 0); + + scanr = BIGNUM_START_PTR(result); + scan1 = BIGNUM_START_PTR(arg1); + scan2 = BIGNUM_START_PTR(arg2); + endr = scanr + max_length; + end1 = scan1 + BIGNUM_LENGTH(arg1); + end2 = scan2 + BIGNUM_LENGTH(arg2); + + while (scanr < endr) { + digit1 = (scan1 < end1) ? *scan1++ : 0; + digit2 = (scan2 < end2) ? *scan2++ : 0; + *scanr++ = (op == AND_OP) ? digit1 & digit2 : + (op == IOR_OP) ? digit1 | digit2 : + digit1 ^ digit2; + } + return bignum_trim(result); } @@ -1597,51 +1597,51 @@ bignum *factorvm::bignum_posneg_bitwise_op(int op, bignum * arg1, bignum * arg2) { GC_BIGNUM(arg1,this); GC_BIGNUM(arg2,this); - bignum * result; - bignum_length_type max_length; + bignum * result; + bignum_length_type max_length; - bignum_digit_type *scan1, *end1, digit1; - bignum_digit_type *scan2, *end2, digit2, carry2; - bignum_digit_type *scanr, *endr; + bignum_digit_type *scan1, *end1, digit1; + bignum_digit_type *scan2, *end2, digit2, carry2; + bignum_digit_type *scanr, *endr; - char neg_p = op == IOR_OP || op == XOR_OP; + char neg_p = op == IOR_OP || op == XOR_OP; - max_length = (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2) + 1) - ? BIGNUM_LENGTH(arg1) : BIGNUM_LENGTH(arg2) + 1; + max_length = (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2) + 1) + ? BIGNUM_LENGTH(arg1) : BIGNUM_LENGTH(arg2) + 1; - result = allot_bignum(max_length, neg_p); + result = allot_bignum(max_length, neg_p); - scanr = BIGNUM_START_PTR(result); - scan1 = BIGNUM_START_PTR(arg1); - scan2 = BIGNUM_START_PTR(arg2); - endr = scanr + max_length; - end1 = scan1 + BIGNUM_LENGTH(arg1); - end2 = scan2 + BIGNUM_LENGTH(arg2); + scanr = BIGNUM_START_PTR(result); + scan1 = BIGNUM_START_PTR(arg1); + scan2 = BIGNUM_START_PTR(arg2); + endr = scanr + max_length; + end1 = scan1 + BIGNUM_LENGTH(arg1); + end2 = scan2 + BIGNUM_LENGTH(arg2); - carry2 = 1; + carry2 = 1; - while (scanr < endr) { - digit1 = (scan1 < end1) ? *scan1++ : 0; - digit2 = (~((scan2 < end2) ? *scan2++ : 0) & BIGNUM_DIGIT_MASK) - + carry2; + while (scanr < endr) { + digit1 = (scan1 < end1) ? *scan1++ : 0; + digit2 = (~((scan2 < end2) ? *scan2++ : 0) & BIGNUM_DIGIT_MASK) + + carry2; - if (digit2 < BIGNUM_RADIX) - carry2 = 0; - else - { - digit2 = (digit2 - BIGNUM_RADIX); - carry2 = 1; - } + if (digit2 < BIGNUM_RADIX) + carry2 = 0; + else + { + digit2 = (digit2 - BIGNUM_RADIX); + carry2 = 1; + } - *scanr++ = (op == AND_OP) ? digit1 & digit2 : - (op == IOR_OP) ? digit1 | digit2 : - digit1 ^ digit2; - } + *scanr++ = (op == AND_OP) ? digit1 & digit2 : + (op == IOR_OP) ? digit1 | digit2 : + digit1 ^ digit2; + } - if (neg_p) - bignum_negate_magnitude(result); + if (neg_p) + bignum_negate_magnitude(result); - return bignum_trim(result); + return bignum_trim(result); } @@ -1650,87 +1650,87 @@ bignum *factorvm::bignum_negneg_bitwise_op(int op, bignum * arg1, bignum * arg2) { GC_BIGNUM(arg1,this); GC_BIGNUM(arg2,this); - bignum * result; - bignum_length_type max_length; + bignum * result; + bignum_length_type max_length; - bignum_digit_type *scan1, *end1, digit1, carry1; - bignum_digit_type *scan2, *end2, digit2, carry2; - bignum_digit_type *scanr, *endr; + bignum_digit_type *scan1, *end1, digit1, carry1; + bignum_digit_type *scan2, *end2, digit2, carry2; + bignum_digit_type *scanr, *endr; - char neg_p = op == AND_OP || op == IOR_OP; + char neg_p = op == AND_OP || op == IOR_OP; - max_length = (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2)) - ? BIGNUM_LENGTH(arg1) + 1 : BIGNUM_LENGTH(arg2) + 1; + max_length = (BIGNUM_LENGTH(arg1) > BIGNUM_LENGTH(arg2)) + ? BIGNUM_LENGTH(arg1) + 1 : BIGNUM_LENGTH(arg2) + 1; - result = allot_bignum(max_length, neg_p); + result = allot_bignum(max_length, neg_p); - scanr = BIGNUM_START_PTR(result); - scan1 = BIGNUM_START_PTR(arg1); - scan2 = BIGNUM_START_PTR(arg2); - endr = scanr + max_length; - end1 = scan1 + BIGNUM_LENGTH(arg1); - end2 = scan2 + BIGNUM_LENGTH(arg2); + scanr = BIGNUM_START_PTR(result); + scan1 = BIGNUM_START_PTR(arg1); + scan2 = BIGNUM_START_PTR(arg2); + endr = scanr + max_length; + end1 = scan1 + BIGNUM_LENGTH(arg1); + end2 = scan2 + BIGNUM_LENGTH(arg2); - carry1 = 1; - carry2 = 1; + carry1 = 1; + carry2 = 1; - while (scanr < endr) { - digit1 = (~((scan1 < end1) ? *scan1++ : 0) & BIGNUM_DIGIT_MASK) + carry1; - digit2 = (~((scan2 < end2) ? *scan2++ : 0) & BIGNUM_DIGIT_MASK) + carry2; + while (scanr < endr) { + digit1 = (~((scan1 < end1) ? *scan1++ : 0) & BIGNUM_DIGIT_MASK) + carry1; + digit2 = (~((scan2 < end2) ? *scan2++ : 0) & BIGNUM_DIGIT_MASK) + carry2; - if (digit1 < BIGNUM_RADIX) - carry1 = 0; - else - { - digit1 = (digit1 - BIGNUM_RADIX); - carry1 = 1; - } + if (digit1 < BIGNUM_RADIX) + carry1 = 0; + else + { + digit1 = (digit1 - BIGNUM_RADIX); + carry1 = 1; + } - if (digit2 < BIGNUM_RADIX) - carry2 = 0; - else - { - digit2 = (digit2 - BIGNUM_RADIX); - carry2 = 1; - } + if (digit2 < BIGNUM_RADIX) + carry2 = 0; + else + { + digit2 = (digit2 - BIGNUM_RADIX); + carry2 = 1; + } - *scanr++ = (op == AND_OP) ? digit1 & digit2 : - (op == IOR_OP) ? digit1 | digit2 : - digit1 ^ digit2; - } + *scanr++ = (op == AND_OP) ? digit1 & digit2 : + (op == IOR_OP) ? digit1 | digit2 : + digit1 ^ digit2; + } - if (neg_p) - bignum_negate_magnitude(result); + if (neg_p) + bignum_negate_magnitude(result); - return bignum_trim(result); + return bignum_trim(result); } void factorvm::bignum_negate_magnitude(bignum * arg) { - bignum_digit_type *scan; - bignum_digit_type *end; - bignum_digit_type digit; - bignum_digit_type carry; - - scan = BIGNUM_START_PTR(arg); - end = scan + BIGNUM_LENGTH(arg); - - carry = 1; - - while (scan < end) { - digit = (~*scan & BIGNUM_DIGIT_MASK) + carry; - - if (digit < BIGNUM_RADIX) - carry = 0; - else - { - digit = (digit - BIGNUM_RADIX); - carry = 1; - } + bignum_digit_type *scan; + bignum_digit_type *end; + bignum_digit_type digit; + bignum_digit_type carry; + + scan = BIGNUM_START_PTR(arg); + end = scan + BIGNUM_LENGTH(arg); + + carry = 1; + + while (scan < end) { + digit = (~*scan & BIGNUM_DIGIT_MASK) + carry; + + if (digit < BIGNUM_RADIX) + carry = 0; + else + { + digit = (digit - BIGNUM_RADIX); + carry = 1; + } - *scan++ = digit; - } + *scan++ = digit; + } } @@ -1739,80 +1739,80 @@ bignum *factorvm::bignum_integer_length(bignum * x) { GC_BIGNUM(x,this); - bignum_length_type index = ((BIGNUM_LENGTH (x)) - 1); - bignum_digit_type digit = (BIGNUM_REF (x, index)); + bignum_length_type index = ((BIGNUM_LENGTH (x)) - 1); + bignum_digit_type digit = (BIGNUM_REF (x, index)); - bignum * result = (allot_bignum (2, 0)); + bignum * result = (allot_bignum (2, 0)); - (BIGNUM_REF (result, 0)) = index; - (BIGNUM_REF (result, 1)) = 0; - bignum_destructive_scale_up (result, BIGNUM_DIGIT_LENGTH); - while (digit > 1) - { - bignum_destructive_add (result, ((bignum_digit_type) 1)); - digit >>= 1; - } - return (bignum_trim (result)); + (BIGNUM_REF (result, 0)) = index; + (BIGNUM_REF (result, 1)) = 0; + bignum_destructive_scale_up (result, BIGNUM_DIGIT_LENGTH); + while (digit > 1) + { + bignum_destructive_add (result, ((bignum_digit_type) 1)); + digit >>= 1; + } + return (bignum_trim (result)); } /* Allocates memory */ int factorvm::bignum_logbitp(int shift, bignum * arg) { - return((BIGNUM_NEGATIVE_P (arg)) - ? !bignum_unsigned_logbitp (shift, bignum_bitwise_not (arg)) - : bignum_unsigned_logbitp (shift,arg)); + return((BIGNUM_NEGATIVE_P (arg)) + ? !bignum_unsigned_logbitp (shift, bignum_bitwise_not (arg)) + : bignum_unsigned_logbitp (shift,arg)); } int factorvm::bignum_unsigned_logbitp(int shift, bignum * bignum) { - bignum_length_type len = (BIGNUM_LENGTH (bignum)); - int index = shift / BIGNUM_DIGIT_LENGTH; - if (index >= len) - return 0; - bignum_digit_type digit = (BIGNUM_REF (bignum, index)); - int p = shift % BIGNUM_DIGIT_LENGTH; - bignum_digit_type mask = ((fixnum)1) << p; - return (digit & mask) ? 1 : 0; + bignum_length_type len = (BIGNUM_LENGTH (bignum)); + int index = shift / BIGNUM_DIGIT_LENGTH; + if (index >= len) + return 0; + bignum_digit_type digit = (BIGNUM_REF (bignum, index)); + int p = shift % BIGNUM_DIGIT_LENGTH; + bignum_digit_type mask = ((fixnum)1) << p; + return (digit & mask) ? 1 : 0; } /* Allocates memory */ bignum *factorvm::digit_stream_to_bignum(unsigned int n_digits, unsigned int (*producer)(unsigned int, factorvm*), unsigned int radix, int negative_p) { - BIGNUM_ASSERT ((radix > 1) && (radix <= BIGNUM_RADIX_ROOT)); - if (n_digits == 0) - return (BIGNUM_ZERO ()); - if (n_digits == 1) - { - fixnum digit = ((fixnum) ((*producer) (0,this))); - return (fixnum_to_bignum (negative_p ? (- digit) : digit)); - } - { - bignum_length_type length; - { - unsigned int radix_copy = radix; - unsigned int log_radix = 0; - while (radix_copy > 0) - { - radix_copy >>= 1; - log_radix += 1; - } - /* This length will be at least as large as needed. */ - length = (BIGNUM_BITS_TO_DIGITS (n_digits * log_radix)); - } - { - bignum * result = (allot_bignum_zeroed (length, negative_p)); - while ((n_digits--) > 0) - { - bignum_destructive_scale_up (result, ((bignum_digit_type) radix)); - bignum_destructive_add - (result, ((bignum_digit_type) ((*producer) (n_digits,this)))); - } - return (bignum_trim (result)); - } - } + BIGNUM_ASSERT ((radix > 1) && (radix <= BIGNUM_RADIX_ROOT)); + if (n_digits == 0) + return (BIGNUM_ZERO ()); + if (n_digits == 1) + { + fixnum digit = ((fixnum) ((*producer) (0,this))); + return (fixnum_to_bignum (negative_p ? (- digit) : digit)); + } + { + bignum_length_type length; + { + unsigned int radix_copy = radix; + unsigned int log_radix = 0; + while (radix_copy > 0) + { + radix_copy >>= 1; + log_radix += 1; + } + /* This length will be at least as large as needed. */ + length = (BIGNUM_BITS_TO_DIGITS (n_digits * log_radix)); + } + { + bignum * result = (allot_bignum_zeroed (length, negative_p)); + while ((n_digits--) > 0) + { + bignum_destructive_scale_up (result, ((bignum_digit_type) radix)); + bignum_destructive_add + (result, ((bignum_digit_type) ((*producer) (n_digits,this)))); + } + return (bignum_trim (result)); + } + } } diff --git a/vm/errors.cpp b/vm/errors.cpp index c137782f81..b3e9543b13 100755 --- a/vm/errors.cpp +++ b/vm/errors.cpp @@ -3,13 +3,6 @@ namespace factor { -/* Global variables used to pass fault handler state from signal handler to -user-space */ -cell signal_number; -cell signal_fault_addr; -unsigned int signal_fpu_status; -stack_frame *signal_callstack_top; - void factorvm::out_of_memory() { print_string("Out of memory\n\n"); diff --git a/vm/factor.cpp b/vm/factor.cpp index 4ef4d11796..34e2267a88 100755 --- a/vm/factor.cpp +++ b/vm/factor.cpp @@ -235,6 +235,8 @@ void* start_standalone_factor_thread(void *arg) VM_C_API void start_standalone_factor(int argc, vm_char **argv) { factorvm *newvm = new factorvm; + newvm->print_vm_data(); + printf("PHIL YEAH: %d %d %d %d\n",(void*)(newvm),(void*)(newvm+1),sizeof(newvm), sizeof(factorvm)); vm = newvm; register_vm_with_thread(newvm); return newvm->start_standalone_factor(argc,argv); @@ -247,4 +249,158 @@ VM_C_API THREADHANDLE start_standalone_factor_in_new_thread(int argc, vm_char ** return start_thread(start_standalone_factor_thread,args); } + +void factorvm::print_vm_data() { + printf("PHIL: stack_chain %d\n",&stack_chain); + printf("PHIL: nursery %d\n",&nursery); + printf("PHIL: cards_offset %d\n",&cards_offset); + printf("PHIL: decks_offset %d\n",&decks_offset); + printf("PHIL: userenv %d\n",&userenv); + printf("PHIL: ds_size %d\n",&ds_size); + printf("PHIL: rs_size %d\n",&rs_size); + printf("PHIL: unused_contexts %d\n",&unused_contexts); + printf("PHIL: T %d\n",&T); + printf("PHIL: profiling_p %d\n",&profiling_p); + printf("PHIL: signal_number %d\n",&signal_number); + printf("PHIL: signal_fault_addr %d\n",&signal_fault_addr); + printf("PHIL: signal_callstack_top %d\n",&signal_callstack_top); + printf("PHIL: secure_gc %d\n",&secure_gc); + printf("PHIL: gc_off %d\n",&gc_off); + printf("PHIL: data %d\n",&data); + printf("PHIL: heap_scan_ptr %d\n",&heap_scan_ptr); + printf("PHIL: allot_markers_offset %d\n",&allot_markers_offset); + printf("PHIL: newspace %d\n",&newspace); + printf("PHIL: performing_gc %d\n",&performing_gc); + printf("PHIL: performing_compaction %d\n",&performing_compaction); + printf("PHIL: collecting_gen %d\n",&collecting_gen); + printf("PHIL: collecting_aging_again %d\n",&collecting_aging_again); + printf("PHIL: gc_jmp %d\n",&gc_jmp); + printf("PHIL: stats %d\n",&stats); + printf("PHIL: cards_scanned %d\n",&cards_scanned); + printf("PHIL: decks_scanned %d\n",&decks_scanned); + printf("PHIL: card_scan_time %d\n",&card_scan_time); + printf("PHIL: code_heap_scans %d\n",&code_heap_scans); + printf("PHIL: last_code_heap_scan %d\n",&last_code_heap_scan); + printf("PHIL: growing_data_heap %d\n",&growing_data_heap); + printf("PHIL: old_data_heap %d\n",&old_data_heap); + printf("PHIL: gc_locals %d\n",&gc_locals); + printf("PHIL: gc_bignums %d\n",&gc_bignums); + printf("PHIL: fep_disabled %d\n",&fep_disabled); + printf("PHIL: full_output %d\n",&full_output); + printf("PHIL: look_for %d\n",&look_for); + printf("PHIL: obj %d\n",&obj); + printf("PHIL: bignum_zero %d\n",&bignum_zero); + printf("PHIL: bignum_pos_one %d\n",&bignum_pos_one); + printf("PHIL: bignum_neg_one %d\n",&bignum_neg_one); + printf("PHIL: code %d\n",&code); + printf("PHIL: forwarding %d\n",&forwarding); + printf("PHIL: code_relocation_base %d\n",&code_relocation_base); + printf("PHIL: data_relocation_base %d\n",&data_relocation_base); + printf("PHIL: megamorphic_cache_hits %d\n",&megamorphic_cache_hits); + printf("PHIL: megamorphic_cache_misses %d\n",&megamorphic_cache_misses); + printf("PHIL: max_pic_size %d\n",&max_pic_size); + printf("PHIL: cold_call_to_ic_transitions %d\n",&cold_call_to_ic_transitions); + printf("PHIL: ic_to_pic_transitions %d\n",&ic_to_pic_transitions); + printf("PHIL: pic_to_mega_transitions %d\n",&pic_to_mega_transitions); + printf("PHIL: pic_counts %d\n",&pic_counts); +} + + // if you change this struct, also change vm.factor k-------- + context *stack_chain; + zone nursery; /* new objects are allocated here */ + cell cards_offset; + cell decks_offset; + cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */ + + // ------------------------------- + + // contexts + cell ds_size, rs_size; + context *unused_contexts; + + // run + cell T; /* Canonical T object. It's just a word */ + + // profiler + bool profiling_p; + + // errors + /* Global variables used to pass fault handler state from signal handler to + user-space */ + cell signal_number; + cell signal_fault_addr; + unsigned int signal_fpu_status; + stack_frame *signal_callstack_top; + + //data_heap + bool secure_gc; /* Set by the -securegc command line argument */ + bool gc_off; /* GC is off during heap walking */ + data_heap *data; + /* A heap walk allows useful things to be done, like finding all + references to an object for debugging purposes. */ + cell heap_scan_ptr; + //write barrier + cell allot_markers_offset; + //data_gc + /* used during garbage collection only */ + zone *newspace; + bool performing_gc; + bool performing_compaction; + cell collecting_gen; + /* if true, we are collecting aging space for the second time, so if it is still + full, we go on to collect tenured */ + bool collecting_aging_again; + /* in case a generation fills up in the middle of a gc, we jump back + up to try collecting the next generation. */ + jmp_buf gc_jmp; + gc_stats stats[max_gen_count]; + u64 cards_scanned; + u64 decks_scanned; + u64 card_scan_time; + cell code_heap_scans; + /* What generation was being collected when copy_code_heap_roots() was last + called? Until the next call to add_code_block(), future + collections of younger generations don't have to touch the code + heap. */ + cell last_code_heap_scan; + /* sometimes we grow the heap */ + bool growing_data_heap; + data_heap *old_data_heap; + + // local roots + /* If a runtime function needs to call another function which potentially + allocates memory, it must wrap any local variable references to Factor + objects in gc_root instances */ + std::vector gc_locals; + std::vector gc_bignums; + + //debug + bool fep_disabled; + bool full_output; + cell look_for; + cell obj; + + //math + cell bignum_zero; + cell bignum_pos_one; + cell bignum_neg_one; + + //code_heap + heap code; + unordered_map forwarding; + + //image + cell code_relocation_base; + cell data_relocation_base; + + //dispatch + cell megamorphic_cache_hits; + cell megamorphic_cache_misses; + + //inline cache + cell max_pic_size; + cell cold_call_to_ic_transitions; + cell ic_to_pic_transitions; + cell pic_to_mega_transitions; + cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */ } diff --git a/vm/os-windows-nt.cpp b/vm/os-windows-nt.cpp index ee00e1434a..988ce60a8a 100755 --- a/vm/os-windows-nt.cpp +++ b/vm/os-windows-nt.cpp @@ -39,21 +39,20 @@ s64 current_micros() - EPOCH_OFFSET) / 10; } -FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe) +LONG factorvm::exception_handler(PEXCEPTION_POINTERS pe) { - factorvm *myvm = SIGNAL_VM_PTR(); PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord; CONTEXT *c = (CONTEXT*)pe->ContextRecord; - if(myvm->in_code_heap_p(c->EIP)) - myvm->signal_callstack_top = (stack_frame *)c->ESP; + if(in_code_heap_p(c->EIP)) + signal_callstack_top = (stack_frame *)c->ESP; else - myvm->signal_callstack_top = NULL; + signal_callstack_top = NULL; switch (e->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: - myvm->signal_fault_addr = e->ExceptionInformation[1]; - c->EIP = (cell)memory_signal_handler_impl; + signal_fault_addr = e->ExceptionInformation[1]; + c->EIP = (cell)factor::memory_signal_handler_impl; break; case STATUS_FLOAT_DENORMAL_OPERAND: @@ -65,10 +64,10 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe) case STATUS_FLOAT_UNDERFLOW: case STATUS_FLOAT_MULTIPLE_FAULTS: case STATUS_FLOAT_MULTIPLE_TRAPS: - myvm->signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c)); + signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c)); X87SW(c) = 0; MXCSR(c) &= 0xffffffc0; - c->EIP = (cell)fp_signal_handler_impl; + c->EIP = (cell)factor::fp_signal_handler_impl; break; case 0x40010006: /* If the Widcomm bluetooth stack is installed, the BTTray.exe @@ -79,24 +78,30 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe) enabled. Don't really have any idea what this exception means. */ break; default: - myvm->signal_number = e->ExceptionCode; - c->EIP = (cell)misc_signal_handler_impl; + signal_number = e->ExceptionCode; + c->EIP = (cell)factor::misc_signal_handler_impl; break; } return EXCEPTION_CONTINUE_EXECUTION; } + +FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe) +{ + return SIGNAL_VM_PTR()->exception_handler(pe); +} + bool handler_added = 0; void factorvm::c_to_factor_toplevel(cell quot) { if(!handler_added){ - if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)exception_handler)) + if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler)) fatal_error("AddVectoredExceptionHandler failed", 0); handler_added = 1; } c_to_factor(quot,this); - RemoveVectoredExceptionHandler((void *)exception_handler); + RemoveVectoredExceptionHandler((void *)factor::exception_handler); } void factorvm::open_console() diff --git a/vm/vm-data-dummy.hpp b/vm/vm-data-dummy.hpp new file mode 100644 index 0000000000..c028a61503 --- /dev/null +++ b/vm/vm-data-dummy.hpp @@ -0,0 +1,116 @@ +namespace factor +{ + + // if you change this struct, also change vm.factor k-------- + extern "C" context *stack_chain; + extern "C" zone nursery; /* new objects are allocated here */ + extern "C" cell cards_offset; + extern "C" cell decks_offset; +//extern "C" cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */ + + // ------------------------------- + + // contexts + extern "C" cell ds_size, rs_size; + extern "C" context *unused_contexts; + + + // profiler + extern "C" bool profiling_p; + + // errors + /* Global variables used to pass fault handler state from signal handler to + user-space */ + extern "C" cell signal_number; + extern "C" cell signal_fault_addr; + extern "C" unsigned int signal_fpu_status; + extern "C" stack_frame *signal_callstack_top; + + //data_heap + extern "C" bool secure_gc; /* Set by the -securegc command line argument */ + extern "C" bool gc_off; /* GC is off during heap walking */ + extern "C" data_heap *data; + /* A heap walk allows useful things to be done, like finding all + references to an object for debugging purposes. */ + extern "C" cell heap_scan_ptr; + //write barrier + extern "C" cell allot_markers_offset; + //data_gc + /* used during garbage collection only */ + extern "C" zone *newspace; + extern "C" bool performing_gc; + extern "C" bool performing_compaction; + extern "C" cell collecting_gen; + /* if true, we are collecting aging space for the second time, so if it is still + full, we go on to collect tenured */ + extern "C" bool collecting_aging_again; + /* in case a generation fills up in the middle of a gc, we jump back + up to try collecting the next generation. */ + extern "C" jmp_buf gc_jmp; + extern "C" gc_stats stats[max_gen_count]; + extern "C" u64 cards_scanned; + extern "C" u64 decks_scanned; + extern "C" u64 card_scan_time; + extern "C" cell code_heap_scans; + /* What generation was being collected when copy_code_heap_roots() was last + called? Until the next call to add_code_block(), future + collections of younger generations don't have to touch the code + heap. */ + extern "C" cell last_code_heap_scan; + /* sometimes we grow the heap */ + extern "C" bool growing_data_heap; + extern "C" data_heap *old_data_heap; + + // local roots + /* If a runtime function needs to call another function which potentially + allocates memory, it must wrap any local variable references to Factor + objects in gc_root instances */ + //extern "C" segment *gc_locals_region; + //extern "C" cell gc_locals; + //extern "C" segment *gc_bignums_region; + //extern "C" cell gc_bignums; + + //debug + extern "C" bool fep_disabled; + extern "C" bool full_output; + extern "C" cell look_for; + extern "C" cell obj; + + //math + extern "C" cell bignum_zero; + extern "C" cell bignum_pos_one; + extern "C" cell bignum_neg_one; + + //code_heap + extern "C" heap code; + extern "C" unordered_map forwarding; + + //image + extern "C" cell code_relocation_base; + extern "C" cell data_relocation_base; + + //dispatch + extern "C" cell megamorphic_cache_hits; + extern "C" cell megamorphic_cache_misses; + + //inline cache + extern "C" cell max_pic_size; + extern "C" cell cold_call_to_ic_transitions; + extern "C" cell ic_to_pic_transitions; + extern "C" cell pic_to_mega_transitions; + extern "C" cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */ + +struct factorvmdata { + cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */ + + // run + cell T; /* Canonical T object. It's just a word */ + + // local roots + /* If a runtime function needs to call another function which potentially + allocates memory, it must wrap any local variable references to Factor + objects in gc_root instances */ + std::vector gc_locals; + std::vector gc_bignums; +}; +} diff --git a/vm/vm-data.hpp b/vm/vm-data.hpp new file mode 100644 index 0000000000..701e35da9d --- /dev/null +++ b/vm/vm-data.hpp @@ -0,0 +1,105 @@ +namespace factor +{ + +struct factorvmdata { + // if you change this struct, also change vm.factor k-------- + context *stack_chain; + zone nursery; /* new objects are allocated here */ + cell cards_offset; + cell decks_offset; + cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */ + + // ------------------------------- + + // contexts + cell ds_size, rs_size; + context *unused_contexts; + + // run + cell T; /* Canonical T object. It's just a word */ + + // profiler + bool profiling_p; + + // errors + /* Global variables used to pass fault handler state from signal handler to + user-space */ + cell signal_number; + cell signal_fault_addr; + unsigned int signal_fpu_status; + stack_frame *signal_callstack_top; + + //data_heap + bool secure_gc; /* Set by the -securegc command line argument */ + bool gc_off; /* GC is off during heap walking */ + data_heap *data; + /* A heap walk allows useful things to be done, like finding all + references to an object for debugging purposes. */ + cell heap_scan_ptr; + //write barrier + cell allot_markers_offset; + //data_gc + /* used during garbage collection only */ + zone *newspace; + bool performing_gc; + bool performing_compaction; + cell collecting_gen; + /* if true, we are collecting aging space for the second time, so if it is still + full, we go on to collect tenured */ + bool collecting_aging_again; + /* in case a generation fills up in the middle of a gc, we jump back + up to try collecting the next generation. */ + jmp_buf gc_jmp; + gc_stats stats[max_gen_count]; + u64 cards_scanned; + u64 decks_scanned; + u64 card_scan_time; + cell code_heap_scans; + /* What generation was being collected when copy_code_heap_roots() was last + called? Until the next call to add_code_block(), future + collections of younger generations don't have to touch the code + heap. */ + cell last_code_heap_scan; + /* sometimes we grow the heap */ + bool growing_data_heap; + data_heap *old_data_heap; + + // local roots + /* If a runtime function needs to call another function which potentially + allocates memory, it must wrap any local variable references to Factor + objects in gc_root instances */ + std::vector gc_locals; + std::vector gc_bignums; + + //debug + bool fep_disabled; + bool full_output; + cell look_for; + cell obj; + + //math + cell bignum_zero; + cell bignum_pos_one; + cell bignum_neg_one; + + //code_heap + heap code; + unordered_map forwarding; + + //image + cell code_relocation_base; + cell data_relocation_base; + + //dispatch + cell megamorphic_cache_hits; + cell megamorphic_cache_misses; + + //inline cache + cell max_pic_size; + cell cold_call_to_ic_transitions; + cell ic_to_pic_transitions; + cell pic_to_mega_transitions; + cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */ +}; + +} diff --git a/vm/vm.hpp b/vm/vm.hpp index b6508c7560..baa67deae8 100644 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -1,106 +1,8 @@ +#include "vm-data-dummy.hpp" + namespace factor { -struct factorvmdata { - // if you change this struct, also change vm.factor k-------- - context *stack_chain; - zone nursery; /* new objects are allocated here */ - cell cards_offset; - cell decks_offset; - cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */ - - // ------------------------------- - - // contexts - cell ds_size, rs_size; - context *unused_contexts; - - // run - cell T; /* Canonical T object. It's just a word */ - - // profiler - bool profiling_p; - - // errors - /* Global variables used to pass fault handler state from signal handler to - user-space */ - cell signal_number; - cell signal_fault_addr; - unsigned int signal_fpu_status; - stack_frame *signal_callstack_top; - //data_heap - bool secure_gc; /* Set by the -securegc command line argument */ - bool gc_off; /* GC is off during heap walking */ - data_heap *data; - /* A heap walk allows useful things to be done, like finding all - references to an object for debugging purposes. */ - cell heap_scan_ptr; - //write barrier - cell allot_markers_offset; - //data_gc - /* used during garbage collection only */ - zone *newspace; - bool performing_gc; - bool performing_compaction; - cell collecting_gen; - /* if true, we are collecting aging space for the second time, so if it is still - full, we go on to collect tenured */ - bool collecting_aging_again; - /* in case a generation fills up in the middle of a gc, we jump back - up to try collecting the next generation. */ - jmp_buf gc_jmp; - gc_stats stats[max_gen_count]; - u64 cards_scanned; - u64 decks_scanned; - u64 card_scan_time; - cell code_heap_scans; - /* What generation was being collected when copy_code_heap_roots() was last - called? Until the next call to add_code_block(), future - collections of younger generations don't have to touch the code - heap. */ - cell last_code_heap_scan; - /* sometimes we grow the heap */ - bool growing_data_heap; - data_heap *old_data_heap; - - // local roots - /* If a runtime function needs to call another function which potentially - allocates memory, it must wrap any local variable references to Factor - objects in gc_root instances */ - std::vector gc_locals; - std::vector gc_bignums; - - //debug - bool fep_disabled; - bool full_output; - cell look_for; - cell obj; - - //math - cell bignum_zero; - cell bignum_pos_one; - cell bignum_neg_one; - - //code_heap - heap code; - unordered_map forwarding; - - //image - cell code_relocation_base; - cell data_relocation_base; - - //dispatch - cell megamorphic_cache_hits; - cell megamorphic_cache_misses; - - //inline cache - cell max_pic_size; - cell cold_call_to_ic_transitions; - cell ic_to_pic_transitions; - cell pic_to_mega_transitions; - cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */ -}; - struct factorvm : factorvmdata { // segments @@ -694,6 +596,7 @@ struct factorvm : factorvmdata { #if defined(WINNT) void open_console(); + LONG exception_handler(PEXCEPTION_POINTERS pe); // next method here: #endif #else // UNIX @@ -702,9 +605,11 @@ struct factorvm : factorvmdata { #endif + void print_vm_data(); }; + #define FACTOR_SINGLE_THREADED_SINGLETON #ifdef FACTOR_SINGLE_THREADED_SINGLETON -- 2.34.1