Skip to content

Commit be65536

Browse files
committed
[js] Add support for uint32
1 parent 4039aeb commit be65536

File tree

5 files changed

+69
-13
lines changed

5 files changed

+69
-13
lines changed

src/vm/js/Chunk.nqp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ my $T_RETVAL := 8; # Something that will be returned from a sub/method call
1313

1414
my $T_UINT16 := 9; # We use a javascript number but always treat it as a 16bit integer
1515
my $T_UINT8 := 10; # We use a javascript number but always treat it as a 8bit integer
16+
my $T_UINT32 := 11; # We use a javascript number but always treat it as a unsigned 32bit integer
1617

1718
my $T_VOID := -1; # Value of this type shouldn't exist, we use a "" as the expr
1819
my $T_NONVAL := -2; # something that is not a nqp value

src/vm/js/Compiler.nqp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -534,15 +534,16 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
534534
$type == $T_INT8
535535
|| $type == $T_INT16
536536
|| $type == $T_UINT8
537-
|| $type == $T_UINT16;
537+
|| $type == $T_UINT16
538+
|| $type == $T_UINT32;
538539
}
539540

540541
#= Convert a 32bit integer which is a result of js expr $expr into integer type $type for storage
541542
method int_to_fancy_int(int $type, str $expr) {
542543
if $type == $T_INT8 || $type == $T_INT16 {
543544
my int $shift := 32 - self.bits($type);
544545
"($expr << $shift >> $shift)";
545-
} elsif $type == $T_UINT8 || $type == $T_UINT16 {
546+
} elsif $type == $T_UINT8 || $type == $T_UINT16 || $type == $T_UINT32 {
546547
my int $shift := 32 - self.bits($type);
547548
"($expr << $shift >>> $shift)";
548549
} else {
@@ -552,17 +553,19 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
552553

553554
method bits(int $type) {
554555
if $type == $T_INT8 || $type == $T_UINT8 {
555-
8
556+
8;
556557
} elsif $type == $T_INT16 || $type == $T_UINT16 {
557-
16
558+
16;
559+
} elsif $type == $T_INT || $type == $T_UINT32 {
560+
32;
558561
} else {
559562
nqp::die("We can't determine the number of bits for $type");
560563
}
561564
}
562565

563566
method coerce(Chunk $chunk, $desired) {
564567
my int $got := $chunk.type;
565-
my int $got_int := $got == $T_INT || self.is_fancy_int($got);
568+
my int $got_int := $got == $T_INT || (self.is_fancy_int($got) && $got != $T_UINT32);
566569

567570
if $got != $desired {
568571
if $desired == $T_VOID {
@@ -579,6 +582,9 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
579582
if $got_int {
580583
return Chunk.new($T_RETVAL, $chunk.expr, $chunk);
581584
}
585+
if $got == $T_UINT32 {
586+
return Chunk.new($T_RETVAL, "new nqp.NativeUIntRet({$chunk.expr})", $chunk);
587+
}
582588
if $got == $T_NUM {
583589
return Chunk.new($T_RETVAL, "new nqp.NativeNumRet({$chunk.expr})", $chunk);
584590
}
@@ -600,6 +606,9 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
600606
if $got_int {
601607
return Chunk.new($T_CALL_ARG, "new nqp.NativeIntArg({$chunk.expr})", $chunk);
602608
}
609+
if $got == $T_UINT32 {
610+
return Chunk.new($T_CALL_ARG, "new nqp.NativeUIntArg({$chunk.expr})", $chunk);
611+
}
603612
if $got == $T_NUM {
604613
return Chunk.new($T_CALL_ARG, "new nqp.NativeNumArg({$chunk.expr})", $chunk);
605614
}
@@ -609,7 +618,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
609618
}
610619

611620
if $desired == $T_NUM {
612-
if $got_int {
621+
if $got_int || $got == $T_UINT32 {
613622
# we store both as a javascript number, and 32bit integers fit into doubles
614623
return Chunk.new($T_NUM, $chunk.expr, $chunk);
615624
}
@@ -625,7 +634,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
625634
if $got == $T_STR {
626635
return Chunk.new($T_INT, "parseInt({$chunk.expr})", $chunk);
627636
}
628-
if $got == $T_NUM {
637+
if $got == $T_NUM || $got == $T_UINT32 {
629638
return Chunk.new($T_INT, "({$chunk.expr}|0)", $chunk);
630639
}
631640
if $got == $T_BOOL {
@@ -645,7 +654,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
645654
}
646655

647656
if $desired == $T_STR {
648-
if $got_int {
657+
if $got_int || $got == $T_UINT32 {
649658
return Chunk.new($T_STR, $chunk.expr ~ '.toString()', $chunk);
650659
}
651660
elsif $got == $T_NUM {
@@ -684,6 +693,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
684693
%convert{$T_INT16} := 'intToObj';
685694
%convert{$T_UINT8} := 'intToObj';
686695
%convert{$T_UINT16} := 'intToObj';
696+
%convert{$T_UINT32} := 'intToObj';
687697
%convert{$T_NUM} := 'numToObj';
688698
%convert{$T_STR} := 'strToObj';
689699
%convert{$T_RETVAL} := 'retval';
@@ -693,7 +703,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
693703
}
694704

695705
if $desired == $T_BOOL {
696-
if $got_int {
706+
if $got_int || $got == $T_UINT32 {
697707
return Chunk.new($T_BOOL, $chunk.expr, $chunk);
698708
} elsif $got == $T_NUM {
699709
return Chunk.new($T_BOOL, "({$chunk.expr} !== 0)", $chunk);
@@ -1593,6 +1603,9 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
15931603
elsif $bits == 16 {
15941604
$unsigned ?? $T_UINT16 !! $T_INT16;
15951605
}
1606+
elsif $bits == 32 {
1607+
$unsigned ?? $T_UINT32 !! $T_INT;
1608+
}
15961609
else {
15971610
$T_INT;
15981611
}
@@ -1703,7 +1716,7 @@ class QAST::CompilerJS does DWIMYNameMangling does SerializeOnce {
17031716
Chunk.void($check, "if (!{$check.expr}) return nqp.paramcheckfailed(HLL, $*CTX, Array.prototype.slice.call(arguments));\n");
17041717
}
17051718

1706-
my %default_value := nqp::hash($T_OBJ, 'nqp.Null', $T_INT, '0', $T_NUM, '0', $T_STR, 'nqp.null_s', $T_INT16, '0', $T_INT8, '0', $T_UINT8, '0', $T_UINT16, '0');
1719+
my %default_value := nqp::hash($T_OBJ, 'nqp.Null', $T_INT, '0', $T_NUM, '0', $T_STR, 'nqp.null_s', $T_INT16, '0', $T_INT8, '0', $T_UINT8, '0', $T_UINT16, '0', $T_UINT32, '0');
17071720

17081721
method declare_var(QAST::Var $node) {
17091722
my int $type := self.type_from_typeobj($node.returns);

src/vm/js/nqp-runtime/core.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ exports.hash = function() {
190190

191191
const nativeArgs = require('./native-args.js');
192192
const NativeIntArg = nativeArgs.NativeIntArg;
193+
const NativeUIntArg = nativeArgs.NativeUIntArg;
193194
const NativeNumArg = nativeArgs.NativeNumArg;
194195
const NativeStrArg = nativeArgs.NativeStrArg;
195196

@@ -232,6 +233,8 @@ const strToObj = exports.strToObj = function(currentHLL, s) {
232233
const arg = exports.arg = function(currentHLL, arg) {
233234
if (arg instanceof NativeIntArg) {
234235
return intToObj(currentHLL, arg.value);
236+
} else if (arg instanceof NativeUIntArg) { // TODO: should work only for bignums
237+
return intToObj(currentHLL, arg.value);
235238
} else if (arg instanceof NativeNumArg) {
236239
return numToObj(currentHLL, arg.value);
237240
} else if (arg instanceof NativeStrArg) {
@@ -623,7 +626,7 @@ function fromJS(obj) {
623626
}
624627

625628
function toJS(obj) {
626-
if (obj instanceof NativeIntArg) {
629+
if (obj instanceof NativeIntArg || obj instanceof NativeUIntArg) {
627630
return obj.value;
628631
} else if (obj instanceof NativeNumArg) {
629632
return obj.value;
@@ -1612,7 +1615,7 @@ op.ctxouterskipthunks = function(ctx) {
16121615
};
16131616

16141617
op.captureposprimspec = function(capture, idx) {
1615-
if (capture.pos[idx] instanceof NativeIntArg) {
1618+
if (capture.pos[idx] instanceof NativeIntArg || capture.pos[idx] instanceof NativeUIntArg) {
16161619
return 1;
16171620
} else if (capture.pos[idx] instanceof NativeNumArg) {
16181621
return 2;

src/vm/js/nqp-runtime/native-args.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ class NativeIntArg {
1414

1515
exports.NativeIntArg = NativeIntArg;
1616

17+
class NativeUIntArg {
18+
constructor(value) {
19+
this.value = value;
20+
}
21+
22+
$$getInt() {
23+
return (this.value|0);
24+
}
25+
26+
$$decont() {
27+
throw new Error('deconting native int arg');
28+
}
29+
};
30+
31+
exports.NativeUIntArg = NativeUIntArg;
32+
1733
class NativeNumArg {
1834
constructor(value) {
1935
this.value = value;
@@ -61,3 +77,19 @@ class NativeNumRet {
6177
}
6278

6379
exports.NativeNumRet = NativeNumRet;
80+
81+
class NativeUIntRet {
82+
constructor(value) {
83+
this.value = value;
84+
}
85+
86+
$$getInt() {
87+
return this.value|0;
88+
}
89+
90+
$$decont() {
91+
return this;
92+
}
93+
}
94+
95+
exports.NativeUIntRet = NativeUIntRet;

src/vm/js/nqp-runtime/runtime.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ const BOOT = require('./BOOT.js');
2222
const nativeArgs = require('./native-args.js');
2323

2424
const NativeIntArg = exports.NativeIntArg = nativeArgs.NativeIntArg;
25+
const NativeUIntArg = exports.NativeUIntArg = nativeArgs.NativeUIntArg;
2526
const NativeNumArg = exports.NativeNumArg = nativeArgs.NativeNumArg;
2627
const NativeStrArg = exports.NativeStrArg = nativeArgs.NativeStrArg;
2728

2829
const NativeNumRet = exports.NativeNumRet = nativeArgs.NativeNumRet;
30+
const NativeUIntRet = exports.NativeUIntRet = nativeArgs.NativeUIntRet;
2931

3032
const stripMarks = require('./strip-marks.js');
3133
const foldCase = require('fold-case');
@@ -271,6 +273,8 @@ exports.retval = function(currentHLL, arg) {
271273
return core.strToObj(currentHLL, arg);
272274
} else if (arg instanceof NativeNumRet) {
273275
return core.numToObj(currentHLL, arg.value);
276+
} else if (arg instanceof NativeUIntRet) {
277+
return core.intToObj(currentHLL, arg.value);
274278
} else {
275279
return arg;
276280
}
@@ -471,6 +475,8 @@ exports.tooManyPos = function(got, expected) {
471475
exports.arg_i = function(ctx, contedArg) {
472476
if (contedArg instanceof NativeIntArg) {
473477
return contedArg.value;
478+
} else if (contedArg instanceof NativeUIntArg) {
479+
return contedArg.value|0;
474480
} else if (contedArg instanceof NativeNumArg) {
475481
throw new NQPException('Expected native int argument, but got num');
476482
} else if (contedArg instanceof NativeStrArg) {
@@ -540,8 +546,9 @@ const chunkNamesToTypes = {
540546
T_INT16: 6,
541547
T_INT8: 7,
542548
T_RETVAL: 8,
543-
T_INT16: 9,
549+
T_UINT16: 9,
544550
T_UINT8: 10,
551+
T_UINT32: 11,
545552

546553
T_VOID: -1,
547554
T_NONVAL: -2,

0 commit comments

Comments
 (0)