(My first post to stack overflow, hope I am using the right format)
I have a need to evaluate code that manipulates 64-bit integers in a "Safe" compartment. Since I supply both the script and the code to be evaluated, I could do a normal eval, but I wanted to try to make things more robust from unintentional errors by using 'Safe".
Should I expect that Math::Int64 should work properly inside a "Safe" compartment? I get conflicting results across different bitness of Perl versions, integer bit-width, and OSes. (See below).
All fail in the same way inside the debugger.
I am sure I am making some incorrect assumption some place, but can't figure out where.
Thanks for any help you can give.
use strict;
use warnings;
use Exporter;
use Safe;
use Math::Int64 qw(int64 hex_to_int64);
#use Math::Int64 ':native_if_available';
my $safe = new Safe 'Root';
$safe->permit( qw(:browse) );
$safe->share( qw/int64 hex_to_int64 my_sprintf/ );
my $X = 0xFF & (hex_to_int64("0xAA12345678") >> 4);
print my_sprintf("X ",$X);
my $Z = evalme('$X = 0xFF & (hex_to_int64("0xAA12345678") >> 4)', $safe);
print my_sprintf("Z ",$Z);
print evalme('my_sprintf("Xe", $X)',$safe);
exit;
sub my_sprintf {
my ($string, $value) = @_;
return sprintf( "Value of %s: %X,\tType: %s\n",
$string, $value, ref($value) || "scalar"
);
}
sub evalme {
my($expr, $safe) = @_;
my $retval = $safe->reval($expr);
die "Error: $@\n" if ($@);
return $retval;
}
% perl -w dummy.pl
=== "Win7 x64 SP1, Strawberry Perl 5.12.3" ===
Value of X : 67, Type: Math::Int64
Can't locate package Exporter for @Math::Int64::ISA at (eval 5) line 1.
...
Can't locate package Exporter for @Math::Int64::ISA at (eval 5) line 1.
Value of Z : 67, Type: Math::Int64
Value of Xe: 67, Type: Math::Int64
=== "Win XP SP3 32-bit Strawberry Perl 5.16.0" ===
Value of X : 67, Type: Math::Int64
Value of Z : 8E, Type: scalar
Value of Xe: 8E, Type: scalar
(No ':native-if-available')
=== "Ubuntu 10.04 x86_64 Server, Perl 5.10.1" ===
Value of X : 67, Type: Math::Int64
Value of Z : 4D, Type: scalar
Value of Xe: 4D, Type: scalar
(':native-if-available')
=== "Ubuntu 10.04 x86_64 Server, Perl 5.10.1" ===
Value of X : 67, Type: scalar
Value of Z : 71, Type: scalar
Value of Xe: 71, Type: scalar
% perl -wd dummy.pl
All versions return effectively:
Value of X : 67, Type: Math::Int64
Error: Undefined subroutine &Math::Int64::hex_to_int64 called at c:/.../perl5db.
at dummy.pl line 35
main::evalme('$X = 0xFF & (hex_to_int64("0xAA12345678") >> 4)',
'Safe=HASH(xxxxxxxx)'
"Win7 x64 SP1, Strawberry Perl 5.12.3":
Platform:
osname=MSWin32, osvers=6.1, archname=MSWin32-x64-multi-thread
uname='Win32 strawberryperl 5.12.3.0 #1 Sun May 15 09:43:50 2011 x64'
use64bitint=define, use64bitall=undef, uselongdouble=undef
Compiler:
intsize=4, longsize=4, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='long long',
Characteristics of this binary (from libperl):
Compile-time options: ... USE_64_BIT_INT
"Win XP 32-bit Strawberry Perl 5.16.0":
Platform:
osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
uname='Win32 strawberry-perl 5.16.0.1 #1 Mon May 21 22:07:30 2012 i386'
use64bitint=undef, use64bitall=undef, uselongdouble=undef
Compiler:
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long',
Characteristics of this binary (from libperl):
Compile-time options: ...
"Ubuntu 10.04 x86_64 Server, Perl 5.10.1":
Linux 2.6.32-31-server,
Platform:
use64bitint=define, use64bitall=define, uselongdouble=undef
Compiler:
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
Characteristics of this binary (from libperl):
Compile-time options: ... USE_64_BIT_ALL USE_64_BIT_INT
It seems that the issue is caused by overloading not working inside Safe compartments.
Overloading was one of the ways to circumvent Safe so it may be disabled on purpose. You can ask on the perl5-porters mailing list if you really want to know.
I don't think this could be solved from Math::Int64 (BTW, I am its author).
On the other hand, you can try compiling Perl with native 64bit support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With