From 118d8fdb37ecdda7ed3429bbd128c04502a7c5c5 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Sun, 9 Jan 2022 13:39:45 +0100 Subject: [PATCH] Use unsigned ops when handling unsigned buffers Split off most Blob/Buf code into roles for signed and unsigned versions using appropriate ops. --- src/core.c/Buf.pm6 | 1103 ++++++++++++++++++++++--------- t/02-rakudo/03-corekeys-6c.t | 2 + t/02-rakudo/03-corekeys-6d.t | 2 + t/02-rakudo/03-corekeys-6e.t | 2 + t/02-rakudo/03-corekeys.t | 2 + t/02-rakudo/04-settingkeys-6c.t | 2 + t/02-rakudo/04-settingkeys-6e.t | 2 + 7 files changed, 817 insertions(+), 298 deletions(-) diff --git a/src/core.c/Buf.pm6 b/src/core.c/Buf.pm6 index ff6e3f9c62c..22db54eeb81 100644 --- a/src/core.c/Buf.pm6 +++ b/src/core.c/Buf.pm6 @@ -11,9 +11,337 @@ enum Endian ( BigEndian => nqp::box_i(nqp::const::BINARY_ENDIAN_BIG,Int), ); +my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is array_type(T) { ... } + +my role SignedBlob[::T] is repr('VMArray') is array_type(T) is implementation-detail { + method !push-list(\action,\to,\from) { + if nqp::istype(from,List) { + my Mu $from := nqp::getattr(from,List,'$!reified'); + if nqp::defined($from) { + my int $elems = nqp::elems($from); + my int $j = nqp::elems(to); + nqp::setelems(to, $j + $elems); # presize for efficiency + my int $i = -1; + my $got; + nqp::while( + nqp::islt_i(++$i,$elems), + nqp::stmts( + ($got := nqp::atpos($from,$i)), + nqp::istype(nqp::hllize($got),Int) + ?? nqp::bindpos_i(to,$j++,$got) + !! self!fail-typecheck-element(action,$i,$got).throw)) + } + } + else { + my $iter := from.iterator; + my int $i = 0; + nqp::until( + nqp::eqaddr((my $got := $iter.pull-one),IterationEnd), + nqp::if( + nqp::istype(nqp::hllize($got),Int), + nqp::stmts( + nqp::push_i(to,$got), + ($i = nqp::add_i($i,1)) + ), + self!fail-typecheck-element(action,$i,$got).throw + ) + ) + } + to + } + method !spread(\to,\from) { + if nqp::elems(from) -> int $values { # something to init with + my int $elems = nqp::elems(to) - $values; + my int $i = -$values; + nqp::splice(to,from,$i,$values) + while nqp::isle_i($i = $i + $values,$elems); + + if nqp::isgt_i($i,$elems) { # something left to init + --$i; # went one too far + $elems = $elems + $values; + my int $j = -1; + if from.^array_type.^unsigned { + nqp::bindpos_i(to,$i,nqp::atpos_u(from, $j = ($j + 1) % $values)) + while nqp::islt_i(++$i,$elems); + } + else { + nqp::bindpos_i(to,$i,nqp::atpos_i(from, $j = ($j + 1) % $values)) + while nqp::islt_i(++$i,$elems); + } + } + } + to + } + multi method allocate(::?CLASS:U: Int:D $elements, int $value) { + my int $elems = $elements; + my $blob := nqp::setelems(nqp::create(self),$elems); + my int $i = -1; + nqp::bindpos_i($blob,$i,$value) while nqp::islt_i(++$i,$elems); + $blob; + } + multi method AT-POS(::?ROLE:D: int \pos) { + nqp::isge_i(pos,nqp::elems(self)) || nqp::islt_i(pos,0) + ?? self!fail-range(pos) + !! nqp::atpos_i(self,pos) + } + multi method AT-POS(::?ROLE:D: Int:D \pos) { + nqp::isge_i(pos,nqp::elems(self)) || nqp::islt_i(pos,0) + ?? self!fail-range(pos) + !! nqp::atpos_i(self,pos) + } + + multi method list(::?ROLE:D:) { + my int $elems = nqp::elems(self); + + # presize memory, but keep it empty, so we can just push + my $buffer := nqp::setelems( + nqp::setelems(nqp::create(IterationBuffer),$elems), + 0 + ); + + my int $i = -1; + nqp::while( + nqp::islt_i(++$i,$elems), + nqp::push($buffer,nqp::atpos_i(self,$i)) + ); + $buffer.List + } + + method reverse(::?CLASS:D:) { + my int $elems = nqp::elems(self); + my int $last = nqp::sub_i($elems,1); + my $reversed := nqp::setelems(nqp::create(self),$elems); + my int $i = -1; + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems), + nqp::bindpos_i($reversed,nqp::sub_i($last,$i), + nqp::atpos_i(self,$i)) + ); + $reversed + } + + method COMPARE(::?CLASS:D: ::?CLASS:D \other) is implementation-detail { + nqp::unless( + nqp::cmp_i( + (my int $elems = nqp::elems(self)), + nqp::elems(my $other := nqp::decont(other)) + ), + nqp::stmts( # same number of elements + (my int $i = -1), + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems) + && nqp::not_i( + nqp::cmp_i(nqp::atpos_i(self,$i),nqp::atpos_i($other,$i)) + ), + nqp::null + ), + nqp::if( + nqp::isne_i($i,$elems), + nqp::cmp_i(nqp::atpos_i(self,$i),nqp::atpos_i($other,$i)) + ) + ) + ) + } + + method SAME(::?CLASS:D: ::?CLASS:D \other) is implementation-detail { + nqp::if( + nqp::iseq_i( + (my int $elems = nqp::elems(self)), + nqp::elems(my $other := nqp::decont(other)) + ), + nqp::stmts( # same number of elements + (my int $i = -1), + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems) + && nqp::iseq_i(nqp::atpos_i(self,$i),nqp::atpos_i($other,$i)), + nqp::null + ), + nqp::iseq_i($i,$elems) + ) + ) + } + + method join(::?CLASS:D: $delim = '') { + my int $elems = nqp::elems(self); + my int $i = -1; + my $list := nqp::setelems(nqp::setelems(nqp::list_s,$elems),0); + + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems), + nqp::push_s($list,nqp::atpos_i(self,$i)) + ); + + nqp::join($delim.Str,$list) + } +} + +my role UnsignedBlob[::T] is repr('VMArray') is array_type(T) is implementation-detail { + method !push-list(\action,\to,\from) { + if nqp::istype(from,List) { + my Mu $from := nqp::getattr(from,List,'$!reified'); + if nqp::defined($from) { + my int $elems = nqp::elems($from); + my int $j = nqp::elems(to); + nqp::setelems(to, $j + $elems); # presize for efficiency + my int $i = -1; + my $got; + nqp::while( + nqp::islt_i(++$i,$elems), + nqp::stmts( + ($got := nqp::atpos($from,$i)), + nqp::istype(nqp::hllize($got),Int) + ?? nqp::bindpos_u(to,$j++,$got) + !! self!fail-typecheck-element(action,$i,$got).throw)) + } + } + else { + my $iter := from.iterator; + my int $i = 0; + nqp::until( + nqp::eqaddr((my $got := $iter.pull-one),IterationEnd), + nqp::if( + nqp::istype(nqp::hllize($got),Int), + nqp::stmts( + nqp::push_i(to,$got), + ($i = nqp::add_i($i,1)) + ), + self!fail-typecheck-element(action,$i,$got).throw + ) + ) + } + to + } + method !spread(\to,\from) { + if nqp::elems(from) -> int $values { # something to init with + my int $elems = nqp::elems(to) - $values; + my int $i = -$values; + nqp::splice(to,from,$i,$values) + while nqp::isle_i($i = $i + $values,$elems); + + if nqp::isgt_i($i,$elems) { # something left to init + --$i; # went one too far + $elems = $elems + $values; + my int $j = -1; + if from.^array_type.^unsigned { + nqp::bindpos_u(to,$i,nqp::atpos_u(from, $j = ($j + 1) % $values)) + while nqp::islt_i(++$i,$elems); + } + else { + nqp::bindpos_u(to,$i,nqp::atpos_i(from, $j = ($j + 1) % $values)) + while nqp::islt_i(++$i,$elems); + } + } + } + to + } + multi method allocate(::?CLASS:U: Int:D $elements, int $value) { + my int $elems = $elements; + my $blob := nqp::setelems(nqp::create(self),$elems); + my int $i = -1; + nqp::bindpos_u($blob,$i,$value) while nqp::islt_i(++$i,$elems); + $blob; + } + multi method AT-POS(::?ROLE:D: int \pos) { + nqp::isge_i(pos,nqp::elems(self)) || nqp::islt_i(pos,0) + ?? self!fail-range(pos) + !! nqp::atpos_u(self,pos) + } + multi method AT-POS(::?ROLE:D: Int:D \pos) { + nqp::isge_i(pos,nqp::elems(self)) || nqp::islt_i(pos,0) + ?? self!fail-range(pos) + !! nqp::atpos_u(self,pos) + } + + multi method list(::?ROLE:D:) { + my int $elems = nqp::elems(self); + + # presize memory, but keep it empty, so we can just push + my $buffer := nqp::setelems( + nqp::setelems(nqp::create(IterationBuffer),$elems), + 0 + ); + + my int $i = -1; + nqp::while( + nqp::islt_i(++$i,$elems), + nqp::push($buffer,nqp::atpos_u(self,$i)) + ); + $buffer.List + } + + method reverse(::?CLASS:D:) { + my int $elems = nqp::elems(self); + my int $last = nqp::sub_i($elems,1); + my $reversed := nqp::setelems(nqp::create(self),$elems); + my int $i = -1; + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems), + nqp::bindpos_u($reversed,nqp::sub_i($last,$i), + nqp::atpos_u(self,$i)) + ); + $reversed + } + + method COMPARE(::?CLASS:D: ::?CLASS:D \other) is implementation-detail { + nqp::unless( + nqp::cmp_i( + (my int $elems = nqp::elems(self)), + nqp::elems(my $other := nqp::decont(other)) + ), + nqp::stmts( # same number of elements + (my int $i = -1), + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems) + && nqp::not_i( + nqp::cmp_i(nqp::atpos_u(self,$i),nqp::atpos_u($other,$i)) + ), + nqp::null + ), + nqp::if( + nqp::isne_i($i,$elems), + nqp::cmp_i(nqp::atpos_u(self,$i),nqp::atpos_u($other,$i)) + ) + ) + ) + } + + method SAME(::?CLASS:D: Blob:D \other) is implementation-detail { + nqp::if( + nqp::iseq_i( + (my int $elems = nqp::elems(self)), + nqp::elems(my $other := nqp::decont(other)) + ), + nqp::stmts( # same number of elements + (my int $i = -1), + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems) + && nqp::iseq_i(nqp::atpos_u(self,$i),nqp::atpos_u($other,$i)), + nqp::null + ), + nqp::iseq_i($i,$elems) + ) + ) + } + + method join(::?CLASS:D: $delim = '') { + my int $elems = nqp::elems(self); + my int $i = -1; + my $list := nqp::setelems(nqp::setelems(nqp::list_s,$elems),0); + + nqp::while( + nqp::islt_i(($i = nqp::add_i($i,1)),$elems), + nqp::push_s($list,nqp::atpos_u(self,$i)) + ); + + nqp::join($delim.Str,$list) + } +} + my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is array_type(T) { die "Can only parameterize with native int types, not '{T.^name}'." - unless nqp::objprimspec(T) == 1 || nqp::objprimspec(T) == 4 || nqp::objprimspec(T) == 5; + unless nqp::objprimspec(T) == 1 || (nqp::objprimspec(T) >= 4 && nqp::objprimspec(T) <= 10); + + $?CLASS.^add_role(T.^unsigned ?? UnsignedBlob.^parameterize(T) !! SignedBlob.^parameterize(T)); # other then *8 not supported yet my int $bpe = try { @@ -78,13 +406,6 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is multi method allocate(Blob:U: Int:D $elements) { nqp::setelems(nqp::create(self),$elements) } - multi method allocate(Blob:U: Int:D $elements, int $value) { - my int $elems = $elements; - my $blob := nqp::setelems(nqp::create(self),$elems); - my int $i = -1; - nqp::bindpos_i($blob,$i,$value) while nqp::islt_i(++$i,$elems); - $blob; - } multi method allocate(Blob:U: Int:D $elements, Int:D \value) { my int $value = value; self.allocate($elements,$value) @@ -113,17 +434,6 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is ); } - multi method AT-POS(Blob:D: int \pos) { - nqp::isge_i(pos,nqp::elems(self)) || nqp::islt_i(pos,0) - ?? self!fail-range(pos) - !! nqp::atpos_i(self,pos) - } - multi method AT-POS(Blob:D: Int:D \pos) { - nqp::isge_i(pos,nqp::elems(self)) || nqp::islt_i(pos,0) - ?? self!fail-range(pos) - !! nqp::atpos_i(self,pos) - } - #?if moar # for simplicity's sake, these are not multis method read-int8(::?ROLE:D: int $offset, Endian $? --> int) is raw { @@ -253,14 +563,14 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is nqp::if( nqp::iseq_i($first-byte,$last-byte), - (my $result := nqp::atpos_i(self,$first-byte)), + (my $result := self.AT-POS($first-byte)), nqp::stmts( ($result := 0), (my int $i = $first-byte - 1), nqp::while( nqp::isle_i(++$i,$last-byte), ($result := - nqp::bitshiftl_I($result,8,Int) +| nqp::atpos_i(self,$i)) + nqp::bitshiftl_I($result,8,Int) +| self.AT-POS($i)) ) ) ); @@ -327,23 +637,6 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is } #?endif - multi method list(Blob:D:) { - my int $elems = nqp::elems(self); - - # presize memory, but keep it empty, so we can just push - my $buffer := nqp::setelems( - nqp::setelems(nqp::create(IterationBuffer),$elems), - 0 - ); - - my int $i = -1; - nqp::while( - nqp::islt_i(++$i,$elems), - nqp::push($buffer,nqp::atpos_i(self,$i)) - ); - $buffer.List - } - my $char := nqp::list_s( '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' ); @@ -355,11 +648,12 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is my int $todo = nqp::elems(self) min nqp::div_i(200,$nativesize); my int $i = -1; my $chunks := nqp::list_s; + my int $unsigned = T.^unsigned; nqp::while( nqp::islt_i($i = nqp::add_i($i,1),$todo), nqp::stmts( - (my int $elem = nqp::atpos_i(self,$i)), + (my int $elem = $unsigned ?? nqp::atpos_u(self,$i) !! nqp::atpos_i(self,$i)), (my $chunk := nqp::list_s), (my int $size = $nativesize), nqp::while( @@ -480,73 +774,6 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is length == Inf ?? self.subbuf(from) !! self.subbuf(from,length.Int) } - method reverse(Blob:D:) { - my int $elems = nqp::elems(self); - my int $last = nqp::sub_i($elems,1); - my $reversed := nqp::setelems(nqp::create(self),$elems); - my int $i = -1; - nqp::while( - nqp::islt_i(($i = nqp::add_i($i,1)),$elems), - nqp::bindpos_i($reversed,nqp::sub_i($last,$i), - nqp::atpos_i(self,$i)) - ); - $reversed - } - - method COMPARE(Blob:D: Blob:D \other) is implementation-detail { - nqp::unless( - nqp::cmp_i( - (my int $elems = nqp::elems(self)), - nqp::elems(my $other := nqp::decont(other)) - ), - nqp::stmts( # same number of elements - (my int $i = -1), - nqp::while( - nqp::islt_i(($i = nqp::add_i($i,1)),$elems) - && nqp::not_i( - nqp::cmp_i(nqp::atpos_i(self,$i),nqp::atpos_i($other,$i)) - ), - nqp::null - ), - nqp::if( - nqp::isne_i($i,$elems), - nqp::cmp_i(nqp::atpos_i(self,$i),nqp::atpos_i($other,$i)) - ) - ) - ) - } - - method SAME(Blob:D: Blob:D \other) is implementation-detail { - nqp::if( - nqp::iseq_i( - (my int $elems = nqp::elems(self)), - nqp::elems(my $other := nqp::decont(other)) - ), - nqp::stmts( # same number of elements - (my int $i = -1), - nqp::while( - nqp::islt_i(($i = nqp::add_i($i,1)),$elems) - && nqp::iseq_i(nqp::atpos_i(self,$i),nqp::atpos_i($other,$i)), - nqp::null - ), - nqp::iseq_i($i,$elems) - ) - ) - } - - method join(Blob:D: $delim = '') { - my int $elems = nqp::elems(self); - my int $i = -1; - my $list := nqp::setelems(nqp::setelems(nqp::list_s,$elems),0); - - nqp::while( - nqp::islt_i(($i = nqp::add_i($i,1)),$elems), - nqp::push_s($list,nqp::atpos_i(self,$i)) - ); - - nqp::join($delim.Str,$list) - } - proto method unpack(|) {*} multi method unpack(Blob:D: Str:D $template) { nqp::isnull(nqp::getlexcaller('EXPERIMENTAL-PACK')) @@ -571,41 +798,6 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is method encoding() { Any } - method !push-list(\action,\to,\from) { - if nqp::istype(from,List) { - my Mu $from := nqp::getattr(from,List,'$!reified'); - if nqp::defined($from) { - my int $elems = nqp::elems($from); - my int $j = nqp::elems(to); - nqp::setelems(to, $j + $elems); # presize for efficiency - my int $i = -1; - my $got; - nqp::while( - nqp::islt_i(++$i,$elems), - nqp::stmts( - ($got := nqp::atpos($from,$i)), - nqp::istype(nqp::hllize($got),Int) - ?? nqp::bindpos_i(to,$j++,$got) - !! self!fail-typecheck-element(action,$i,$got).throw)) - } - } - else { - my $iter := from.iterator; - my int $i = 0; - nqp::until( - nqp::eqaddr((my $got := $iter.pull-one),IterationEnd), - nqp::if( - nqp::istype(nqp::hllize($got),Int), - nqp::stmts( - nqp::push_i(to,$got), - ($i = nqp::add_i($i,1)) - ), - self!fail-typecheck-element(action,$i,$got).throw - ) - ) - } - to - } method !unshift-list(\action,\to,\from) { if nqp::istype(from,List) { my Mu $from := nqp::getattr(from,List,'$!reified'); @@ -622,23 +814,6 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is nqp::splice(to,self!push-list(action,nqp::create(self),from),0,0) } } - method !spread(\to,\from) { - if nqp::elems(from) -> int $values { # something to init with - my int $elems = nqp::elems(to) - $values; - my int $i = -$values; - nqp::splice(to,from,$i,$values) - while nqp::isle_i($i = $i + $values,$elems); - - if nqp::isgt_i($i,$elems) { # something left to init - --$i; # went one too far - $elems = $elems + $values; - my int $j = -1; - nqp::bindpos_i(to,$i,nqp::atpos_i(from,$j = ($j + 1) % $values)) - while nqp::islt_i(++$i,$elems); - } - } - to - } method !fail-range($got) { Failure.new(X::OutOfRange.new( :what($*INDEX // 'Index'), @@ -669,8 +844,7 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is (my int $i = -1), nqp::while( nqp::islt_i(($i = nqp::add_i($i,1)),$elems) - && nqp::iseq_i(nqp::atpos_i(self,$i),nqp::atpos_i(other,$i) - ), + && (self[$i] == other[$i]), nqp::null ), nqp::iseq_i($i,$elems) @@ -681,63 +855,261 @@ my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is } } -constant blob8 = Blob[uint8]; -constant blob16 = Blob[uint16]; -constant blob32 = Blob[uint32]; -constant blob64 = Blob[uint64]; +constant blob8 = Blob[uint8]; +constant blob16 = Blob[uint16]; +constant blob32 = Blob[uint32]; +constant blob64 = Blob[uint64]; + +my class utf8 does Blob[uint8] is repr('VMArray') { + method encoding(--> "utf-8") { } + multi method Str(utf8:D:) { self.decode } + multi method Stringy(utf8:D:) { self.decode } +} + +my class utf16 does Blob[uint16] is repr('VMArray') { + method encoding(--> "utf-16") { } + multi method Str(utf16:D:) { self.decode } + multi method Stringy(utf16:D:) { self.decode } +} + +my class utf32 does Blob[uint32] is repr('VMArray') { + method encoding(--> "utf-32") { } + multi method Str(utf32:D:) { self.decode } + multi method Stringy(utf32:D:) { self.decode } +} + +my role Buf[::T = uint8] does Blob[T] is repr('VMArray') is array_type(T) { + + my role SignedBuf[::T] is repr('VMArray') is array_type(T) is implementation-detail { + multi method AT-POS(::?ROLE:D: int \pos) is raw { + nqp::islt_i(pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::atposref_i(self, pos) + } + multi method AT-POS(::?ROLE:D: Int:D \pos) is raw { + my int $pos = nqp::unbox_i(pos); + nqp::islt_i($pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::atposref_i(self,$pos) + } + + multi method ASSIGN-POS(::?CLASS:D: int \pos, Mu \assignee) { + nqp::islt_i(pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::bindpos_i(self,pos,assignee) + } + multi method ASSIGN-POS(::?CLASS:D: Int:D \pos, Mu \assignee) { + my int $pos = nqp::unbox_i(pos); + nqp::islt_i($pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::bindpos_i(self,$pos,assignee) + } + + multi method list(::?ROLE:D:) is default { + my int $elems = nqp::elems(self); + + # presize memory, but keep it empty, so we can just push + my $buffer := nqp::setelems( + nqp::setelems(nqp::create(IterationBuffer),$elems), + 0 + ); + + my int $i = -1; + nqp::while( + nqp::islt_i(++$i,$elems), + nqp::push($buffer,nqp::atposref_i(self,$i)) + ); + $buffer.List + } + + method write-ubits(::?ROLE \SELF: + int $pos, Int:D $bits, UInt:D \value + ) is raw { + + # sanity check + POS-OOR(SELF, $pos) if $pos < 0; + my $self := nqp::isconcrete(self) ?? self !! nqp::create(self); + + # set up basic info + my int $first-bit = $pos +& 7; + my int $last-bit = ($pos + $bits) +& 7; + my int $first-byte = $pos +> 3; + my int $last-byte = ($pos + $bits - 1) +> 3; + + my $value := value +& (1 +< $bits - 1); # mask valid part + $value := $value +< (8 - $last-bit) if $last-bit; # move into position + + my int $lmask = nqp::sub_i(1 +< $first-bit,1) +< (8 - $first-bit) + if $first-bit; + my int $rmask = 1 +< nqp::sub_i(8 - $last-bit,1) + if $last-bit; + + # all done in a single byte + if $first-byte == $last-byte { + nqp::bindpos_i($self,$first-byte, + $value +| (nqp::atpos_i($self,$first-byte) +& ($lmask +| $rmask)) + ); + } + + # spread over multiple bytes + else { + my int $i = $last-byte; + + # process last byte first if it is a partial + if $last-bit { + nqp::bindpos_i($self,$i, + ($value +& 255) +| (nqp::atpos_i($self,$i) +& $rmask) + ); + $value := $value +> 8; + } + + # not a partial, so make sure we process last byte later + else { + ++$i; + } + + # walk from right to left, exclude left-most is partial + my int $last = $first-byte + nqp::isgt_i($first-bit,0); + nqp::while( + nqp::isge_i(--$i,$last), + nqp::stmts( + nqp::bindpos_i($self,$i,($value +& 255)), + ($value := $value +> 8) + ) + ); + + # process last byte if it was a partial + nqp::bindpos_i($self,$i,($value +& 255) + +| (nqp::atpos_i($self,$i) +& $lmask)) + if $first-bit; + } + + $self + } + } + + my role UnsignedBuf[::T] is repr('VMArray') is array_type(T) is implementation-detail { + multi method AT-POS(::?ROLE:D: int \pos) is raw is default { + nqp::islt_i(pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::atposref_u(self, pos) + } + multi method AT-POS(::?ROLE:D: Int:D \pos) is raw is default { + my int $pos = nqp::unbox_i(pos); + nqp::islt_i($pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::atposref_u(self,$pos) + } + + multi method ASSIGN-POS(::?CLASS:D: int \pos, Mu \assignee) { + nqp::islt_i(pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::bindpos_u(self,pos,assignee) + } + multi method ASSIGN-POS(::?CLASS:D: Int:D \pos, Mu \assignee) { + my int $pos = nqp::unbox_i(pos); + nqp::islt_i($pos,0) + ?? Failure.new(X::OutOfRange.new( + :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) + !! nqp::bindpos_u(self,$pos,assignee) + } + + multi method list(::?ROLE:D:) is default { + my int $elems = nqp::elems(self); + + # presize memory, but keep it empty, so we can just push + my $buffer := nqp::setelems( + nqp::setelems(nqp::create(IterationBuffer),$elems), + 0 + ); -my class utf8 does Blob[uint8] is repr('VMArray') { - method encoding(--> "utf-8") { } - multi method Str(utf8:D:) { self.decode } - multi method Stringy(utf8:D:) { self.decode } -} + my int $i = -1; + nqp::while( + nqp::islt_i(++$i,$elems), + nqp::push($buffer,nqp::atposref_u(self,$i)) + ); + $buffer.List + } -my class utf16 does Blob[uint16] is repr('VMArray') { - method encoding(--> "utf-16") { } - multi method Str(utf16:D:) { self.decode } - multi method Stringy(utf16:D:) { self.decode } -} + method write-ubits(::?ROLE \SELF: + int $pos, Int:D $bits, UInt:D \value + ) is raw { -my class utf32 does Blob[uint32] is repr('VMArray') { - method encoding(--> "utf-32") { } - multi method Str(utf32:D:) { self.decode } - multi method Stringy(utf32:D:) { self.decode } -} + # sanity check + POS-OOR(SELF, $pos) if $pos < 0; + my $self := nqp::isconcrete(self) ?? self !! nqp::create(self); -my role Buf[::T = uint8] does Blob[T] is repr('VMArray') is array_type(T) { + # set up basic info + my int $first-bit = $pos +& 7; + my int $last-bit = ($pos + $bits) +& 7; + my int $first-byte = $pos +> 3; + my int $last-byte = ($pos + $bits - 1) +> 3; - multi method WHICH(Buf:D:) { self.Mu::WHICH } + my $value := value +& (1 +< $bits - 1); # mask valid part + $value := $value +< (8 - $last-bit) if $last-bit; # move into position - method Blob(Blob:D:) { - (nqp::eqaddr(T,uint8) ?? Blob !! Blob.^parameterize(T)).new: self - } + my int $lmask = nqp::sub_i(1 +< $first-bit,1) +< (8 - $first-bit) + if $first-bit; + my int $rmask = 1 +< nqp::sub_i(8 - $last-bit,1) + if $last-bit; - multi method AT-POS(Buf:D: int \pos) is raw { - nqp::islt_i(pos,0) - ?? Failure.new(X::OutOfRange.new( - :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) - !! nqp::atposref_i(self, pos) - } - multi method AT-POS(Buf:D: Int:D \pos) is raw { - my int $pos = nqp::unbox_i(pos); - nqp::islt_i($pos,0) - ?? Failure.new(X::OutOfRange.new( - :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) - !! nqp::atposref_i(self,$pos) - } + # all done in a single byte + if $first-byte == $last-byte { + nqp::bindpos_u($self,$first-byte, + $value +| (nqp::atpos_u($self,$first-byte) +& ($lmask +| $rmask)) + ); + } + + # spread over multiple bytes + else { + my int $i = $last-byte; + + # process last byte first if it is a partial + if $last-bit { + nqp::bindpos_u($self,$i, + ($value +& 255) +| (nqp::atpos_u($self,$i) +& $rmask) + ); + $value := $value +> 8; + } + + # not a partial, so make sure we process last byte later + else { + ++$i; + } + + # walk from right to left, exclude left-most is partial + my int $last = $first-byte + nqp::isgt_i($first-bit,0); + nqp::while( + nqp::isge_i(--$i,$last), + nqp::stmts( + nqp::bindpos_u($self,$i,($value +& 255)), + ($value := $value +> 8) + ) + ); + + # process last byte if it was a partial + nqp::bindpos_u($self,$i,($value +& 255) + +| (nqp::atpos_u($self,$i) +& $lmask)) + if $first-bit; + } - multi method ASSIGN-POS(Buf:D: int \pos, Mu \assignee) { - nqp::islt_i(pos,0) - ?? Failure.new(X::OutOfRange.new( - :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) - !! nqp::bindpos_i(self,pos,assignee) + $self + } } - multi method ASSIGN-POS(Buf:D: Int:D \pos, Mu \assignee) { - my int $pos = nqp::unbox_i(pos); - nqp::islt_i($pos,0) - ?? Failure.new(X::OutOfRange.new( - :what($*INDEX // 'Index'),:got(pos),:range<0..^Inf>)) - !! nqp::bindpos_i(self,$pos,assignee) + + $?CLASS.^add_role(T.^unsigned ?? UnsignedBuf[T] !! SignedBuf[T]); + + multi method WHICH(Buf:D:) { self.Mu::WHICH } + + method Blob(Blob:D:) { + (nqp::eqaddr(T,uint8) ?? Blob !! Blob.^parameterize(T)).new: self } multi method STORE(Buf:D: Blob:D $blob) { @@ -803,8 +1175,8 @@ my role Buf[::T = uint8] does Blob[T] is repr('VMArray') is array_type(T) { || ($endian == NativeEndian && Kernel.endian == BigEndian); my $self := nqp::isconcrete(self) ?? self !! nqp::create(self); - $self.write-int64($offset, $be ?? $first !! $second, $endian); - $self.write-int64($offset + 8, $be ?? $second !! $first, $endian); + $self.write-uint64($offset, $be ?? $first !! $second, $endian); + $self.write-uint64($offset + 8, $be ?? $second !! $first, $endian); $self } method write-uint8(::?ROLE: @@ -882,88 +1254,6 @@ my role Buf[::T = uint8] does Blob[T] is repr('VMArray') is array_type(T) { SELF.write-ubits($pos, $bits, value +& (1 +< $bits - 1)) } - method write-ubits(::?ROLE \SELF: - int $pos, Int:D $bits, UInt:D \value - ) is raw { - - # sanity check - POS-OOR(SELF, $pos) if $pos < 0; - my $self := nqp::isconcrete(self) ?? self !! nqp::create(self); - - # set up basic info - my int $first-bit = $pos +& 7; - my int $last-bit = ($pos + $bits) +& 7; - my int $first-byte = $pos +> 3; - my int $last-byte = ($pos + $bits - 1) +> 3; - - my $value := value +& (1 +< $bits - 1); # mask valid part - $value := $value +< (8 - $last-bit) if $last-bit; # move into position - - my int $lmask = nqp::sub_i(1 +< $first-bit,1) +< (8 - $first-bit) - if $first-bit; - my int $rmask = 1 +< nqp::sub_i(8 - $last-bit,1) - if $last-bit; - - # all done in a single byte - if $first-byte == $last-byte { - nqp::bindpos_i($self,$first-byte, - $value +| (nqp::atpos_i($self,$first-byte) +& ($lmask +| $rmask)) - ); - } - - # spread over multiple bytes - else { - my int $i = $last-byte; - - # process last byte first if it is a partial - if $last-bit { - nqp::bindpos_i($self,$i, - ($value +& 255) +| (nqp::atpos_i($self,$i) +& $rmask) - ); - $value := $value +> 8; - } - - # not a partial, so make sure we process last byte later - else { - ++$i; - } - - # walk from right to left, exclude left-most is partial - my int $last = $first-byte + nqp::isgt_i($first-bit,0); - nqp::while( - nqp::isge_i(--$i,$last), - nqp::stmts( - nqp::bindpos_i($self,$i,($value +& 255)), - ($value := $value +> 8) - ) - ); - - # process last byte if it was a partial - nqp::bindpos_i($self,$i,($value +& 255) - +| (nqp::atpos_i($self,$i) +& $lmask)) - if $first-bit; - } - - $self - } - - multi method list(Buf:D:) { - my int $elems = nqp::elems(self); - - # presize memory, but keep it empty, so we can just push - my $buffer := nqp::setelems( - nqp::setelems(nqp::create(IterationBuffer),$elems), - 0 - ); - - my int $i = -1; - nqp::while( - nqp::islt_i(++$i,$elems), - nqp::push($buffer,nqp::atposref_i(self,$i)) - ); - $buffer.List - } - proto method pop(|) { * } multi method pop(Buf:D:) { nqp::elems(self) @@ -1108,7 +1398,19 @@ multi sub infix:<~>(Blob:D $a, Blob:D $b) { nqp::splice($res, $bdc, $alen, $blen); } -multi sub prefix:<~^>(Blob:D $a) { +multi sub prefix:<~^>(UnsignedBlob:D $a) { + my int $elems = nqp::elems($a); + + my $r := nqp::create($a); + nqp::setelems($a,$elems); + + my int $i = -1; + nqp::bindpos_u($r,$i,nqp::bitneg_i(nqp::atpos_u($a,$i))) + while nqp::islt_i(++$i,$elems); + + $r +} +multi sub prefix:<~^>(SignedBlob:D $a) { my int $elems = nqp::elems($a); my $r := nqp::create($a); @@ -1121,7 +1423,64 @@ multi sub prefix:<~^>(Blob:D $a) { $r } -multi sub infix:<~&>(Blob:D $a, Blob:D $b) { +multi sub infix:<~&>(UnsignedBlob:D $a, UnsignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_u($r,$i, + nqp::bitand_i(nqp::atpos_u($a,$i),nqp::atpos_u($b,$i))) + while nqp::islt_i(++$i,$do); + + --$i; # went one too far + nqp::bindpos_u($r,$i,0) while nqp::islt_i(++$i,$max); + + $r +} +multi sub infix:<~&>(UnsignedBlob:D $a, SignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_u($r,$i, + nqp::bitand_i(nqp::atpos_u($a,$i),nqp::atpos_i($b,$i))) + while nqp::islt_i(++$i,$do); + + --$i; # went one too far + nqp::bindpos_u($r,$i,0) while nqp::islt_i(++$i,$max); + + $r +} +multi sub infix:<~&>(SignedBlob:D $a, UnsignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_i($r,$i, + nqp::bitand_i(nqp::atpos_i($a,$i),nqp::atpos_u($b,$i))) + while nqp::islt_i(++$i,$do); + + --$i; # went one too far + nqp::bindpos_u($r,$i,0) while nqp::islt_i(++$i,$max); + + $r +} +multi sub infix:<~&>(SignedBlob:D $a, SignedBlob:D $b) { my int $elemsa = nqp::elems($a); my int $elemsb = nqp::elems($b); my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; @@ -1136,12 +1495,85 @@ multi sub infix:<~&>(Blob:D $a, Blob:D $b) { while nqp::islt_i(++$i,$do); --$i; # went one too far - nqp::bindpos_i($r,$i,0) while nqp::islt_i(++$i,$max); + nqp::bindpos_u($r,$i,0) while nqp::islt_i(++$i,$max); + + $r +} + +multi sub infix:<~|>(UnsignedBlob:D $a, UnsignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + my $from := $elemsa > $elemsb ?? $a !! $b; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_u($r,$i, + nqp::bitor_i(nqp::atpos_u($a,$i),nqp::atpos_u($b,$i))) + while nqp::islt_i(++$i,$do); + + $i = $i - 1; # went one too far + nqp::bindpos_u($r,$i,nqp::atpos_u($from,$i)) + while nqp::islt_i(++$i,$max); + + $r +} +multi sub infix:<~|>(UnsignedBlob:D $a, SignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_u($r,$i, + nqp::bitor_i(nqp::atpos_u($a,$i),nqp::atpos_i($b,$i))) + while nqp::islt_i(++$i,$do); + + $i = $i - 1; # went one too far + if $elemsa > $elemsb { + nqp::bindpos_u($r,$i,nqp::atpos_u($a,$i)) + while nqp::islt_i(++$i,$max); + } + else { + nqp::bindpos_u($r,$i,nqp::atpos_i($b,$i)) + while nqp::islt_i(++$i,$max); + } $r } +multi sub infix:<~|>(SignedBlob:D $a, UnsignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_i($r,$i, + nqp::bitor_i(nqp::atpos_i($a,$i),nqp::atpos_u($b,$i))) + while nqp::islt_i(++$i,$do); + + $i = $i - 1; # went one too far + if $elemsa > $elemsb { + nqp::bindpos_i($r,$i,nqp::atpos_i($a,$i)) + while nqp::islt_i(++$i,$max); + } + else { + nqp::bindpos_i($r,$i,nqp::atpos_u($b,$i)) + while nqp::islt_i(++$i,$max); + } -multi sub infix:<~|>(Blob:D $a, Blob:D $b) { + $r +} +multi sub infix:<~|>(SignedBlob:D $a, SignedBlob:D $b) { my int $elemsa = nqp::elems($a); my int $elemsb = nqp::elems($b); my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; @@ -1157,13 +1589,88 @@ multi sub infix:<~|>(Blob:D $a, Blob:D $b) { while nqp::islt_i(++$i,$do); $i = $i - 1; # went one too far - nqp::bindpos_i($r,$i,nqp::atpos_i($from,$i)) + nqp::bindpos_u($r,$i,nqp::atpos_i($from,$i)) + while nqp::islt_i(++$i,$max); + + $r +} + +multi sub infix:<~^>(UnsignedBlob:D $a, UnsignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + my $from := $elemsa > $elemsb ?? $a !! $b; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_u($r,$i, + nqp::bitxor_i(nqp::atpos_u($a,$i),nqp::atpos_u($b,$i))) + while nqp::islt_i(++$i,$do); + + --$i; # went one too far + nqp::bindpos_u($r,$i,nqp::atpos_u($from,$i)) while nqp::islt_i(++$i,$max); $r } +multi sub infix:<~^>(UnsignedBlob:D $a, SignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + my $from := $elemsa > $elemsb ?? $a !! $b; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_u($r,$i, + nqp::bitxor_i(nqp::atpos_u($a,$i),nqp::atpos_i($b,$i))) + while nqp::islt_i(++$i,$do); + + --$i; # went one too far + if $elemsa > $elemsb { + nqp::bindpos_u($r,$i,nqp::atpos_u($a,$i)) + while nqp::islt_i(++$i,$max); + } + else { + nqp::bindpos_u($r,$i,nqp::atpos_i($b,$i)) + while nqp::islt_i(++$i,$max); + } + + $r +} +multi sub infix:<~^>(SignedBlob:D $a, UnsignedBlob:D $b) { + my int $elemsa = nqp::elems($a); + my int $elemsb = nqp::elems($b); + my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; + my int $max = $elemsa > $elemsb ?? $elemsa !! $elemsb; + my $from := $elemsa > $elemsb ?? $a !! $b; + + my $r := nqp::create($a); + nqp::setelems($r,$max); + + my int $i = -1; + nqp::bindpos_i($r,$i, + nqp::bitxor_i(nqp::atpos_i($a,$i),nqp::atpos_u($b,$i))) + while nqp::islt_i(++$i,$do); + + --$i; # went one too far + if $elemsa > $elemsb { + nqp::bindpos_i($r,$i,nqp::atpos_i($a,$i)) + while nqp::islt_i(++$i,$max); + } + else { + nqp::bindpos_i($r,$i,nqp::atpos_u($b,$i)) + while nqp::islt_i(++$i,$max); + } -multi sub infix:<~^>(Blob:D $a, Blob:D $b) { + $r +} +multi sub infix:<~^>(SignedBlob:D $a, SignedBlob:D $b) { my int $elemsa = nqp::elems($a); my int $elemsb = nqp::elems($b); my int $do = $elemsa > $elemsb ?? $elemsb !! $elemsa; diff --git a/t/02-rakudo/03-corekeys-6c.t b/t/02-rakudo/03-corekeys-6c.t index 5ef520d1ac1..1fc1cff096c 100644 --- a/t/02-rakudo/03-corekeys-6c.t +++ b/t/02-rakudo/03-corekeys-6c.t @@ -694,6 +694,7 @@ my @expected = ( Q{Setty}, Q{Signal}, Q{Signature}, + Q{SignedBlob}, Q{Slang}, Q{Slip}, Q{SocketType}, @@ -722,6 +723,7 @@ my @expected = ( Q{UIntLexRef}, Q{UIntPosRef}, Q{Uni}, + Q{UnsignedBlob}, Q{VM}, Q{ValueObjAt}, Q{Variable}, diff --git a/t/02-rakudo/03-corekeys-6d.t b/t/02-rakudo/03-corekeys-6d.t index 7bf07f07316..d05a5efd176 100644 --- a/t/02-rakudo/03-corekeys-6d.t +++ b/t/02-rakudo/03-corekeys-6d.t @@ -694,6 +694,7 @@ my @expected = ( Q{Setty}, Q{Signal}, Q{Signature}, + Q{SignedBlob}, Q{Slang}, Q{Slip}, Q{SocketType}, @@ -722,6 +723,7 @@ my @expected = ( Q{UIntLexRef}, Q{UIntPosRef}, Q{Uni}, + Q{UnsignedBlob}, Q{VM}, Q{ValueObjAt}, Q{Variable}, diff --git a/t/02-rakudo/03-corekeys-6e.t b/t/02-rakudo/03-corekeys-6e.t index f3d589436a9..ef7030bbd73 100644 --- a/t/02-rakudo/03-corekeys-6e.t +++ b/t/02-rakudo/03-corekeys-6e.t @@ -697,6 +697,7 @@ my @expected = ( Q{Setty}, Q{Signal}, Q{Signature}, + Q{SignedBlob}, Q{Slang}, Q{Slip}, Q{SocketType}, @@ -725,6 +726,7 @@ my @expected = ( Q{UIntLexRef}, Q{UIntPosRef}, Q{Uni}, + Q{UnsignedBlob}, Q{VM}, Q{ValueObjAt}, Q{Variable}, diff --git a/t/02-rakudo/03-corekeys.t b/t/02-rakudo/03-corekeys.t index 7057d275998..8e7af6ff41b 100644 --- a/t/02-rakudo/03-corekeys.t +++ b/t/02-rakudo/03-corekeys.t @@ -697,6 +697,7 @@ my @allowed = Q{Setty}, Q{Signal}, Q{Signature}, + Q{SignedBlob}, Q{Slang}, Q{Slip}, Q{SocketType}, @@ -725,6 +726,7 @@ my @allowed = Q{UIntLexRef}, Q{UIntPosRef}, Q{Uni}, + Q{UnsignedBlob}, Q{VM}, Q{ValueObjAt}, Q{Variable}, diff --git a/t/02-rakudo/04-settingkeys-6c.t b/t/02-rakudo/04-settingkeys-6c.t index 8084a6dacb5..50f0be67658 100644 --- a/t/02-rakudo/04-settingkeys-6c.t +++ b/t/02-rakudo/04-settingkeys-6c.t @@ -694,6 +694,7 @@ my %allowed = ( Q{Setty}, Q{Signal}, Q{Signature}, + Q{SignedBlob}, Q{Slang}, Q{Slip}, Q{SocketType}, @@ -722,6 +723,7 @@ my %allowed = ( Q{UIntLexRef}, Q{UIntPosRef}, Q{Uni}, + Q{UnsignedBlob}, Q{VM}, Q{ValueObjAt}, Q{Variable}, diff --git a/t/02-rakudo/04-settingkeys-6e.t b/t/02-rakudo/04-settingkeys-6e.t index 6459e2a0fc4..b1b984f131d 100644 --- a/t/02-rakudo/04-settingkeys-6e.t +++ b/t/02-rakudo/04-settingkeys-6e.t @@ -695,6 +695,7 @@ my %allowed = ( Q{Setty}, Q{Signal}, Q{Signature}, + Q{SignedBlob}, Q{Slang}, Q{Slip}, Q{SocketType}, @@ -723,6 +724,7 @@ my %allowed = ( Q{UIntLexRef}, Q{UIntPosRef}, Q{Uni}, + Q{UnsignedBlob}, Q{VM}, Q{ValueObjAt}, Q{Variable},