On Sat, 26 Apr 2008 19:18:21 -0700 Geoffrey Broadwell (via RT) <[EMAIL PROTECTED]> wrote:
> # New Ticket Created by Geoffrey Broadwell > # Please include the string: [perl #53406] > # in the subject line of all future correspondence about this issue. > # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=53406 > > (I wish we could just insist that INTVAL be 64 bits everywhere, but > alas that doesn't make a lot of sense for very memory-constrained > environments. Though those do get rarer by the day ....) In the future, INTVAL will probably be 128 bits for some platforms. I'd really like to see a set of fixed-width types (similar to what p5 has for pack and unpack), so you have the option of "native int" or "exactly 32 bits" or whatever you need. HUGEINTVAL is 64 bits on both linux-x86 and linux-amd64, so it seems like a good start. Here's an ugly patch that attempts to add it. Problems with this patch: 1. It probably won't work on win32-x64... I seem to recall someone mentioning HUGEINTVAL is just 32 bits there. 2. The patch adds a HUGEINTVAL to the PObj union, and would probably require additional fixups all over parrot to be able to access the resulting object. The above makes me think we might be better off using a BigInt object for this data. But anyway, here's what I got. Mark
Index: src/call_list.txt =================================================================== --- src/call_list.txt (revision 27216) +++ src/call_list.txt (working copy) @@ -13,6 +13,7 @@ # s - short # i - int # l - long +# L - long long # NUM register stuff # N - FLOATVAL @@ -34,6 +35,7 @@ # 2 - pointer to short # 3 - pointer to int # 4 - pointer to long +# 5 - pointer to long long # void stuff # v - void Index: tools/build/nativecall.pl =================================================================== --- tools/build/nativecall.pl (revision 27216) +++ tools/build/nativecall.pl (working copy) @@ -43,6 +43,8 @@ 3 => "int *", l => "long", 4 => "long *", + L => "long long", + 5 => "long long *", c => "char", s => "short", 2 => "short *", @@ -65,6 +67,8 @@ 3 => "int *", l => "long", 4 => "long *", + L => "long long", + 5 => "long long *", c => "char", s => "short", 2 => "short *", @@ -105,6 +109,8 @@ 3 => "int *", l => "long", 4 => "long *", + L => "long long", + 5 => "long long *", c => "char", s => "short", 2 => "short *", @@ -126,8 +132,10 @@ i => "set_nci_I(interp, &st, return_data);", I => "set_nci_I(interp, &st, return_data);", l => "set_nci_I(interp, &st, return_data);", + L => "set_nci_L(interp, &st, return_data);", s => "set_nci_I(interp, &st, return_data);", c => "set_nci_I(interp, &st, return_data);", + 5 => "set_nci_L(interp, &st, *return_data);", 4 => "set_nci_I(interp, &st, *return_data);", 3 => "set_nci_I(interp, &st, *return_data);", 2 => "set_nci_I(interp, &st, *return_data);", @@ -147,10 +155,12 @@ my %func_call_assign = ( p => "return_data = ", i => "return_data = ", + 2 => "return_data = ", 3 => "return_data = ", - 2 => "return_data = ", 4 => "return_data = ", + 5 => "return_data = ", l => "return_data = ", + L => "return_data = ", c => "return_data = ", s => "return_data = ", f => "return_data = ", @@ -173,6 +183,7 @@ 2 => "P", 4 => "P", l => "I", + L => "L", c => "I", s => "I", f => "N", @@ -320,6 +331,18 @@ return UVal_int(st->val); } +static HUGEINTVAL +get_nci_L(PARROT_INTERP, ARGMOD(call_state *st), int n) +{ + if (n >= st->src.n) { + real_exception(interp, NULL, E_ValueError, + "too few arguments passed to NCI function"); + } + Parrot_fetch_arg_nci(interp, st); + + return UVal_hugeint(st->val); +} + static FLOATVAL get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n) { @@ -367,6 +390,7 @@ #define GET_NCI_I(n) get_nci_I(interp, &st, n) #define GET_NCI_S(n) get_nci_S(interp, &st, n) #define GET_NCI_N(n) get_nci_N(interp, &st, n) +#define GET_NCI_L(n) get_nci_L(interp, &st, n) #define GET_NCI_P(n) get_nci_P(interp, &st, n) /* @@ -384,6 +408,17 @@ } static void +set_nci_L(PARROT_INTERP, ARGOUT(call_state *st), HUGEINTVAL val) +{ + Parrot_init_ret_nci(interp, st, "L"); + if (st->dest.i < st->dest.n) { + UVal_hugeint(st->val) = val; + Parrot_convert_arg(interp, st); + Parrot_store_arg(interp, st); + } +} + +static void set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val) { Parrot_init_ret_nci(interp, st, "N"); @@ -454,6 +489,11 @@ push @{$extra_preamble_ref}, "t_$temp_num = (long)GET_NCI_I($reg_num);"; return "t_$temp_num"; }; + /L/ && do { + push @{$temps_ref}, "long long t_$temp_num;"; + push @{$extra_preamble_ref}, "t_$temp_num = (long long)GET_NCI_I($reg_num);"; + return "t_$temp_num"; + }; /I/ && do { push @{$temps_ref}, "INTVAL t_$temp_num;"; push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_I($reg_num);"; @@ -464,6 +504,11 @@ push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_P($reg_num);"; return "(long*)&PMC_int_val(t_$temp_num)"; }; + /5/ && do { + push @{$temps_ref}, "PMC *t_$temp_num;"; + push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_P($reg_num);"; + return "(long long*)&PMC_hugeint_val(t_$temp_num)"; + }; /s/ && do { push @{$temps_ref}, "short t_$temp_num;"; push @{$extra_preamble_ref}, "t_$temp_num = (short)GET_NCI_I($reg_num);"; Index: include/parrot/pobj.h =================================================================== --- include/parrot/pobj.h (revision 27216) +++ include/parrot/pobj.h (working copy) @@ -28,6 +28,7 @@ INTVAL _int_val; /* or 2 intvals */ INTVAL _int_val2; } _i; + HUGEINTVAL _hugeint_val; /* or one hugeintval */ FLOATVAL _num_val; /* or one float */ struct parrot_string_t * _string_val; /* or a pointer to a string */ } UnionVal; @@ -37,6 +38,7 @@ #define UVal_int(u) (u)._i._int_val #define UVal_int2(u) (u)._i._int_val2 #define UVal_num(u) (u)._num_val +#define UVal_hugeint(u) (u)._hugeint_val #define UVal_str(u) (u)._string_val /* Parrot Object - base class for all others */