Skip to content

Commit

Permalink
[js] Very basic int64/uint64 support
Browse files Browse the repository at this point in the history
Currently only ++/-- and converting them back and forth between Int works
  • Loading branch information
pmurias committed Oct 11, 2018
1 parent fbfccfa commit 3caccd5
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/Perl6/Actions.nqp
Expand Up @@ -7537,7 +7537,8 @@ class Perl6::Actions is HLL::Actions does STDActions {
}
}

my @native_assign_ops := ['', 'assign_i', 'assign_n', 'assign_s'];
# The _i64 and _u64 are only used on backends that emulate int64/uint64
my @native_assign_ops := ['', 'assign_i', 'assign_n', 'assign_s', 'assign_i64', 'assign_u64'];
sub assign_op($/, $lhs_ast, $rhs_ast, :$initialize) {
my $past;
my $var_sigil;
Expand Down
31 changes: 31 additions & 0 deletions src/Perl6/Metamodel/BOOTSTRAP.nqp
Expand Up @@ -92,6 +92,13 @@ my stub IntMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... };
my stub NumMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... };
my stub StrMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... };

#?if js
my stub Int64LexRef metaclass Perl6::Metamodel::NativeRefHOW { ... };
my stub Int64AttrRef metaclass Perl6::Metamodel::NativeRefHOW { ... };
my stub Int64PosRef metaclass Perl6::Metamodel::NativeRefHOW { ... };
my stub Int64MultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... };
#?endif

# Implement the signature binder.
# The JVM backend really only uses trial_bind,
# so we exclude everything else.
Expand Down Expand Up @@ -1704,6 +1711,13 @@ BEGIN {
setup_native_ref_type(NumMultidimRef, num, 'multidim');
setup_native_ref_type(StrMultidimRef, str, 'multidim');

#?if js
setup_native_ref_type(Int64LexRef, int64, 'lexical');
setup_native_ref_type(Int64AttrRef, int64, 'attribute');
setup_native_ref_type(Int64PosRef, int64, 'positional');
setup_native_ref_type(Int64MultidimRef, int64, 'multidim');
#?endif

# class Proxy is Any {
# has Mu &!FETCH;
# has Mu &!STORE;
Expand Down Expand Up @@ -3366,6 +3380,12 @@ BEGIN {
Perl6::Metamodel::NativeRefHOW.add_stash(IntMultidimRef);
Perl6::Metamodel::NativeRefHOW.add_stash(NumMultidimRef);
Perl6::Metamodel::NativeRefHOW.add_stash(StrMultidimRef);
#?if js
Perl6::Metamodel::NativeRefHOW.add_stash(Int64LexRef);
Perl6::Metamodel::NativeRefHOW.add_stash(Int64AttrRef);
Perl6::Metamodel::NativeRefHOW.add_stash(Int64PosRef);
Perl6::Metamodel::NativeRefHOW.add_stash(Int64MultidimRef);
#?endif
Perl6::Metamodel::ClassHOW.add_stash(List);
Perl6::Metamodel::ClassHOW.add_stash(Slip);
Perl6::Metamodel::ClassHOW.add_stash(Array);
Expand Down Expand Up @@ -3483,6 +3503,11 @@ BEGIN {
EXPORT::DEFAULT.WHO<IntPosRef> := IntPosRef;
EXPORT::DEFAULT.WHO<NumPosRef> := NumPosRef;
EXPORT::DEFAULT.WHO<StrPosRef> := StrPosRef;
#?if
EXPORT::DEFAULT.WHO<Int64LexRef> := Int64LexRef;
EXPORT::DEFAULT.WHO<Int64AttrRef> := Int64AttrRef;
EXPORT::DEFAULT.WHO<Int64PosRef> := Int64PosRef;
#?endif
EXPORT::DEFAULT.WHO<Proxy> := Proxy;
EXPORT::DEFAULT.WHO<Grammar> := Grammar;
EXPORT::DEFAULT.WHO<Junction> := Junction;
Expand Down Expand Up @@ -3714,6 +3739,12 @@ nqp::sethllconfig('perl6', nqp::hash(
'int_multidim_ref', IntMultidimRef,
'num_multidim_ref', NumMultidimRef,
'str_multidim_ref', StrMultidimRef,
#?if js
'int64_lex_ref', Int64LexRef,
'int64_attr_ref', Int64AttrRef,
'int64_pos_ref', Int64PosRef,
'int64_multidim_ref', Int64MultidimRef,
#?endif
));

# Tell parametric role groups how to create a dispatcher.
Expand Down
22 changes: 21 additions & 1 deletion src/Perl6/Optimizer.nqp
Expand Up @@ -1915,7 +1915,7 @@ class Perl6::Optimizer {
# if we got a native int/num, we can rewrite into nqp ops
if nqp::istype($var,QAST::Var) && $var.scope eq 'lexicalref'
&& ((my $primspec := nqp::objprimspec($var.returns)) == 1 # native int
|| $primspec == 2) # native num
|| $primspec == 2 || $primspec == 4 || $primspec == 5) # native num or "emulated" 64bit int
{
my $returns := $var.returns;
my $is-dec := nqp::eqat($op.name, '--', -3);
Expand Down Expand Up @@ -1958,6 +1958,26 @@ class Perl6::Optimizer {
$one
}
}
elsif $primspec == 4 || $primspec == 5 { # 64bit int on 32bit backends
my str $assign_op := $primspec == 4 ?? 'assign_i64' !! 'assign_u64';
my $one := QAST::IVal.new: :value(1);
if $!void_context || nqp::eqat($op.name, '&pre', 0) {
# we can just use (or ignore) the result
return QAST::Op.new: :op($assign_op), :$node, :$returns, $var,
QAST::Op.new: :op($is-dec ?? 'sub_i64' !! 'add_i64'),
:$returns, $var, $one
}
else {
# need to assign original value; it's cheaper to just
# do the reverse operation than to use a temp var
return QAST::Op.new: :op($is-dec ?? 'add_i64' !! 'sub_i64'),
:$node, :$returns,
QAST::Op.new(:op($assign_op), :$returns, $var,
QAST::Op.new: :op($is-dec ?? 'sub_i64' !! 'add_i64'),
:$returns, $var, $one),
$one
}
}
}

# XXX TODO: my tests show the opt below makes things 25% slower.
Expand Down
2 changes: 1 addition & 1 deletion src/Perl6/World.nqp
Expand Up @@ -1593,7 +1593,7 @@ class Perl6::World is HLL::World {
my $prim := %cont_info<sigil> eq '$' && nqp::objprimspec($descriptor.of);
if $prim {
if $scope eq 'state' { nqp::die("Natively typed state variables not yet implemented") }
if $prim == 1 {
if $prim == 1 || $prim == 4 || $prim == 5 {
$block[0].push(QAST::Op.new( :op('bind'),
QAST::Var.new( :scope('lexical'), :name($name) ),
QAST::IVal.new( :value(0) ) ))
Expand Down
3 changes: 3 additions & 0 deletions src/vm/js/Perl6/Ops.nqp
Expand Up @@ -49,6 +49,9 @@ $ops.add_hll_unbox('perl6', $ops.INT, 'getInt');
$ops.add_hll_unbox('perl6', $ops.NUM, 'getNum');
$ops.add_hll_unbox('perl6', $ops.STR, 'getStr');

$ops.add_hll_unbox('perl6', $ops.INT64, 'getInt64');
$ops.add_hll_unbox('perl6', $ops.UINT64, 'getUint64');

# Signature binding related bits.

$ops.add_simple_op('p6setbinder', $ops.VOID, [$ops.OBJ], :side_effects, sub ($binder) {"nqp.p6binder = $binder"});
Expand Down
8 changes: 8 additions & 0 deletions src/vm/js/perl6-runtime/runtime.js
Expand Up @@ -324,6 +324,14 @@ module.exports.load = function(nqp, CodeRef, Capture, containerSpecs) {
return this.$$getattr(Scalar, '$!value').$$getInt();
});

this.STable.addInternalMethod('$$getInt64', function(ctx) {
return this.$$getattr(Scalar, '$!value').$$getInt64();
});

this.STable.addInternalMethod('$$getUint64', function(ctx) {
return this.$$getattr(Scalar, '$!value').$$getUint64();
});

this.STable.addInternalMethod('$$getStr', function(ctx) {
return this.$$getattr(Scalar, '$!value').$$getStr();
});
Expand Down

0 comments on commit 3caccd5

Please sign in to comment.