...
 
Commits (4)
......@@ -21,19 +21,9 @@ Makefile
*~
/nqp
/*.html
nqp.c
nqp_group.c
nqp_group.h
src/gen/*.nqp
src/gen/*.pm
src/gen/*.setting
src/stage1
src/stage2
tools/build/install-jvm-runner.pl
config.status
config.default
3rdparty/dyncall/ConfigVars
3rdparty/dyncall/*/*.a
node_modules
nqp-runtime.jar
*.class
......@@ -49,7 +39,7 @@ nqp-runtime.jar
/nqp-js.bat
/nqp-js-cross.bat
/jvmconfig.properties
*.moarvm
/*.moarvm
MoarVM
MANIFEST
/bin
......
......@@ -476,6 +476,7 @@ t/moar/10-eqatim.t
t/moar/11-decode.t
t/moar/50-jit-register-alloc.t
t/moar/51-jit-div_i.t
t/moar/52-pluggable-spesh.t
t/nativecall/01-basic.t
t/nqp/001-literals.t
t/nqp/002-if.t
......
nqp (2018.06+dfsg-1) unstable; urgency=medium
[ Dominique Dumont ]
* work-around test that hang in autopkgtest (Closes: #900230)
[ Robert Lemmen ]
* New upstream version 2018.06+dfsg
* control: update moarvm-dev dep versions
-- Robert Lemmen <robertle@semistable.com> Tue, 26 Jun 2018 20:51:17 +0200
nqp (2018.05+dfsg-1) unstable; urgency=medium
* New upstream version 2018.05+dfsg
......
......@@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 9),
libjs-jquery,
libreadline-dev,
libtommath-dev (>= 0.42.0-1.2),
moarvm-dev (>= 2018.05),
moarvm-dev (>= 2018.06),
perl
Standards-Version: 4.1.4
Vcs-Browser: https://salsa.debian.org/perl6-team/nqp
......
......@@ -296,6 +296,7 @@
* [debugnoop `jvm`](#debugnoop-jvm)
* [exit](#exit)
* [getenvhash](#getenvhash)
* [getsignals](#getsignals)
* [backendconfig](#backendconfig)
* [getpid](#getpid)
* [getppid `moar`](#getppid)
......@@ -836,6 +837,9 @@ You can also use `nqp::iterator()` to iterate over a hash's key-value pairs.
## atkey
* `atkey(%hash, str $key --> Mu)`
* `atkey_i(%hash, str $key --> int)`
* `atkey_u(%hash, str $key --> uint)`
* Note, there's no bindkey_u yet since at the moment since atkey_u is only used
for getting values from the lexpad
* `atkey_n(%hash, str $key --> num)`
* `atkey_s(%hash, str $key --> str)`
......@@ -2460,47 +2464,6 @@ constants below can be used in nqp as (e.g.) `nqp::const::CCLASS_ANY`.
* TYPE_CHECK_CACHE_THEN_METHOD
* TYPE_CHECK_NEEDS_ACCEPTS
The JVM only supports SIG_INT and SIG_KILL.
On the MoarVM all of those signal constants below are defined.
* SIG_HUP
* SIG_INT
* SIG_QUIT
* SIG_ILL
* SIG_TRAP
* SIG_ABRT
* SIG_EMT
* SIG_FPE
* SIG_KILL
* SIG_BUS
* SIG_SEGV
* SIG_SYS
* SIG_PIPE
* SIG_ALRM
* SIG_TERM
* SIG_URG
* SIG_STOP
* SIG_TSTP
* SIG_CONT
* SIG_CHLD
* SIG_TTIN
* SIG_TTOU
* SIG_IO
* SIG_XCPU
* SIG_XFSZ
* SIG_VTALRM
* SIG_PROF
* SIG_WINCH
* SIG_INFO
* SIG_USR1
* SIG_USR2
* SIG_THR
* SIG_STKFLT
* SIG_PWR
* SIG_BREAK
## debugnoop `jvm`
* `debugnoop(Mu $a)`
......@@ -2518,6 +2481,56 @@ Exit nqp, using the given status as the compiler's exit value.
Returns a hash containing the environment variables.
Changing the hash doesn't affect the environment variables
## getsignals
* `getsignals(--> Mu)`
Returns a list containing signal names interleaved with the associated signum
integer on the host platform (MacOSX, Linux, BSD, etc).
If the current backend does not support the registering of a signal handler for
a given signal, the hash value will be a negative integer. For instance, the JVM
only supports signal handlers for SIGINT and SIGKILL, so all the values will be
negative except 2 (SIGINT) and 9 (SIGKILL). If a signal is not available on the
host system, the hash value will be set to 0.
The complete list of signal entries is as follows:
* SIGHUP
* SIGINT
* SIGQUIT
* SIGILL
* SIGTRAP
* SIGABRT
* SIGEMT
* SIGFPE
* SIGKILL
* SIGBUS
* SIGSEGV
* SIGSYS
* SIGPIPE
* SIGALRM
* SIGTERM
* SIGURG
* SIGSTOP
* SIGTSTP
* SIGCONT
* SIGCHLD
* SIGTTIN
* SIGTTOU
* SIGIO
* SIGXCPU
* SIGXFSZ
* SIGVTALRM
* SIGPROF
* SIGWINCH
* SIGINFO
* SIGUSR1
* SIGUSR2
* SIGTHR
* SIGSTKFLT
* SIGPWR
* SIGBREAK
## backendconfig
* `backendconfig(--> Mu)`
......
......@@ -14,5 +14,4 @@ Any word (other than 'cut') is accepted as an identifier. The entry may be used
...any text
=end ...optional identifier...
If the ```=begin``` has an identifier, the ```=end``` should have the same identifier (not
yet enforced).
If the ```=begin``` has an identifier, the ```=end``` must have the same identifier.
......@@ -56,18 +56,55 @@ class HLL::Actions {
my str $key := ~$_;
unless $block.symbol($key) {
my $lextype := nqp::lexprimspec($pad, $key);
# obj
if $lextype == 0 {
$block.symbol($key, :scope<lexical>, :lazy_value_from($pad));
}
# int
elsif $lextype == 1 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_i($pad, $key)), :type(int));
}
# num
elsif $lextype == 2 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_n($pad, $key)), :type(num));
}
# str
elsif $lextype == 3 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_s($pad, $key)), :type(str));
}
# int8
elsif $lextype == 4 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_i($pad, $key)), :type(int8));
}
# int16
elsif $lextype == 5 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_i($pad, $key)), :type(int16));
}
# int32
elsif $lextype == 6 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_i($pad, $key)), :type(int32));
}
#?if moar
# uint8
elsif $lextype == 7 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_u($pad, $key)), :type(uint8));
}
# uint16
elsif $lextype == 8 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_u($pad, $key)), :type(uint16));
}
# uint32
elsif $lextype == 9 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_u($pad, $key)), :type(uint32));
}
# uint64
elsif $lextype == 10 {
$block.symbol($key, :scope<lexical>, :value(nqp::atkey_u($pad, $key)), :type(uint64));
}
#?endif
else {
die("Unhandled lexical type")
}
}
}
}
......@@ -132,7 +169,7 @@ class HLL::Actions {
$ast := QAST::SVal.new( :value(~@words[0]) );
}
}
else {
else {
$/.panic("Can't form :w list from non-constant strings (yet)");
}
}
......
......@@ -412,7 +412,9 @@ class HLL::Compiler does HLL::Backend::Default {
nqp::exit(1) if $err;
try {
nqp::push(@codes, $in-handle.slurp());
$in-handle.close;
unless $filename eq '-' {
$in-handle.close;
}
CATCH {
note("Error while reading from file: $_");
$err := 1;
......
......@@ -1626,12 +1626,9 @@ class NQP::Actions is HLL::Actions {
method postfix:sym<.>($/) { make $<dotty>.ast; }
method term:sym<return>($/) {
# This can go away in favor of nqp::const::CONTROL_RETURN after rebootstrap
# of Moar and JVM backends.
my $CONTROL_RETURN := 32;
make QAST::Op.new(
:op('throwpayloadlex'),
QAST::IVal.new( :value($CONTROL_RETURN) ),
QAST::IVal.new( :value(nqp::const::CONTROL_RETURN) ),
$<EXPR> ?? $<EXPR>.ast !! QAST::WVal.new( :value($*W.find_sym(['NQPMu'])))
);
}
......@@ -1677,6 +1674,10 @@ class NQP::Actions is HLL::Actions {
make QAST::Op.new( :op<callmethod>, :name<ACCEPTS>, :node($/) );
}
method infix:sym<!~~>($/) {
make QAST::Op.new( :op<callmethod>, :name<NOT-ACCEPTS>, :node($/) );
}
# Takes a multi-part name that we know is in a package and generates
# QAST to look it up using NQP package semantics.
sub lexical_package_lookup(@name, $/) {
......
......@@ -238,46 +238,46 @@ grammar NQP::Grammar is HLL::Grammar {
proto rule statement_control { <...> }
rule statement_control:sym<use> {
<sym>\s <name>
<sym> <name>
}
rule statement_control:sym<if> {
<sym>\s
<sym>
<xblock>
[ 'elsif'\s <xblock> ]*
[ 'else'\s <else=.pblock> ]?
[ 'elsif' <xblock> ]*
[ 'else' <else=.pblock> ]?
}
rule statement_control:sym<unless> {
<sym>\s
<sym>
<xblock>
[ <!before 'else'> || <.panic: 'unless does not take "else", please rewrite using "if"'> ]
}
rule statement_control:sym<while> {
:my $*CONTROL_USED := 0;
$<sym>=[while|until]\s
$<sym>=[while|until]
<xblock>
}
rule statement_control:sym<repeat> {
:my $*CONTROL_USED := 0;
<sym>\s
<sym>
[
| $<wu>=[while|until]\s <xblock>
| <pblock> $<wu>=[while|until]\s <EXPR>
| $<wu>=[while|until] <xblock>
| <pblock> $<wu>=[while|until] <EXPR>
]
}
rule statement_control:sym<for> {
:my $*CONTROL_USED := 0;
<sym>\s
<sym>
<xblock>
}
rule statement_control:sym<CATCH> { <sym>\s <block> }
rule statement_control:sym<CATCH> { <sym> <block> }
rule statement_control:sym<CONTROL> { <sym>\s <block> }
rule statement_control:sym<CONTROL> { <sym> <block> }
proto token statement_prefix { <...> }
token statement_prefix:sym<BEGIN> { <sym> <blorst> }
......@@ -821,6 +821,7 @@ grammar NQP::Grammar is HLL::Grammar {
token infix:sym«gt» { <sym> <O(|%relational, :op<isgt_s>)> }
token infix:sym«=:=» { <sym> <O(|%relational, :op<eqaddr>)> }
token infix:sym<~~> { <sym> <O(|%relational, :reducecheck<smartmatch>)> }
token infix:sym<!~~> { <sym> <O(|%relational, :reducecheck<smartmatch>)> }
token infix:sym<&&> { <sym> <O(|%tight_and, :op<if>)> }
......@@ -843,8 +844,8 @@ grammar NQP::Grammar is HLL::Grammar {
token infix:sym<,> { <sym> <O(|%comma, :op<list>)> }
token prefix:sym<make> { <sym> \s <O(|%list_prefix)> }
token term:sym<return> { <sym> [\s <EXPR>]? { $*RETURN_USED := 1 } }
token prefix:sym<make> { <sym> \s+ <O(|%list_prefix)> }
token term:sym<return> { <sym> [\s+ <EXPR>]? { $*RETURN_USED := 1 } }
method smartmatch($/) {
# swap rhs into invocant position
......
......@@ -25,7 +25,11 @@ role QAST::Children {
else {
nqp::push(@onto, nqp::x(' ', $indent));
nqp::push(@onto, '- ');
nqp::push(@onto, nqp::istype($_, NQPMu) ?? '(NQPMu)' !! ~$_);
nqp::istype($_, NQPMu)
?? nqp::push(@onto, '(NQPMu)')
!! $_.HOW.name($_) eq 'Sub' || $_.HOW.name($_) eq 'Regex'
?? nqp::push(@onto, $_.name)
!! nqp::push(@onto, ~$_ );
nqp::push(@onto, "\n");
}
}
......
......@@ -1368,6 +1368,9 @@ class NQPRegexMethod {
multi method ACCEPTS(NQPRegexMethod:D $self: $target) {
NQPMatch.parse($target, :rule(self))
}
multi method NOT-ACCEPTS(NQPRegexMethod:D $self: $target) {
nqp::isfalse(NQPMatch.parse($target, :rule(self)))
}
method name() {
nqp::getcodename($!code)
}
......@@ -1381,5 +1384,8 @@ class NQPRegex is NQPRegexMethod {
multi method ACCEPTS(NQPRegex:D $self: $target) {
NQPMatch.parse($target, :rule(self), :c(0))
}
multi method NOT-ACCEPTS(NQPRegex:D $self: $target) {
nqp::isfalse(NQPMatch.parse($target, :rule(self), :c(0)))
}
}
nqp::setinvokespec(NQPRegex, NQPRegexMethod, '$!code', nqp::null);
......@@ -22,50 +22,37 @@ class QRegex::Optimizer {
method all_subtypes($node, $type) {
my int $res := 0;
for $node {
if $node.rxtype eq $type {
$res++
} else {
return -1;
}
return -1 if $node.rxtype ne $type;
$res++;
}
return $res;
}
method first_non_concat_child($node) {
while nqp::elems(@($node)) >= 1 {
if nqp::istype($node, QAST::Regex) {
if $node.rxtype eq 'concat' {
if $node[0].rxtype eq 'qastnode' && $node[0].subtype eq 'declarative' {
# the debugger puts these all over our code; we should pretend we never saw them.
$node := $node[1];
} else {
$node := $node[0];
}
} else {
last;
}
} else {
last;
}
last unless nqp::istype($node, QAST::Regex);
last unless $node.rxtype eq 'concat';
$node := ($node[0].rxtype eq 'qastnode' && $node[0].subtype eq 'declarative')
?? $node[1] !! $node[0];
}
$node;
}
method dont_scan($node) {
while nqp::elems(@($node)) >= 1 {
if nqp::istype($node, QAST::Regex) {
if nqp::istype($node[0], QAST::Regex) && $node[0].rxtype eq 'scan' {
$node.shift;
last;
}
if $node.rxtype eq 'concat' {
$node := $node[0];
} else {
last;
}
last unless nqp::istype($node, QAST::Regex);
if nqp::istype($node[0], QAST::Regex) && $node[0].rxtype eq 'scan' {
$node.shift;
last;
}
if $node.rxtype eq 'concat' {
$node := $node[0];
} else {
last;
}
}
}
......@@ -152,45 +139,47 @@ class QRegex::Optimizer {
}
method visit_children($node) {
if nqp::isstr($node) {
return;
}
my int $i := 0;
unless nqp::isstr($node) {
my int $n := nqp::elems(@($node));
while $i < $n {
my $visit := $node[$i];
if nqp::istype($visit, QAST::Regex) {
my $type := $visit.rxtype;
if $type eq 'concat' {
$node[$i] := self.visit_concat($visit);
} elsif $type eq 'literal' {
} elsif $type eq 'quant' {
self.visit_children($visit);
} elsif $type eq 'subrule' {
$node[$i] := $!main_opt($node[$i]) if $!main_opt;
$node[$i] := self.simplify_assertion($visit);
} elsif $type eq 'qastnode' {
$node[$i] := $!main_opt($node[$i]) if $!main_opt;
} elsif $type eq 'anchor' {
} elsif $type eq 'enumcharlist' {
} elsif $type eq 'cclass' {
} elsif $type eq 'scan' {
} elsif $type eq 'charrange' {
} elsif $type eq 'dynquant' {
$node[$i] := $!main_opt($node[$i]) if $!main_opt;
} elsif $type eq 'pass' || $type eq 'fail' {
} else {
# alt, altseq, conjseq, conj, quant
self.visit_children($visit);
}
} elsif nqp::istype($visit, QAST::Block) {
@!outer.push($visit);
my int $n := nqp::elems(@($node));
while $i < $n {
my $visit := $node[$i];
if nqp::istype($visit, QAST::Regex) {
my $type := $visit.rxtype;
if $type eq 'concat' {
$node[$i] := self.visit_concat($visit);
} elsif $type eq 'literal' {
} elsif $type eq 'quant' {
self.visit_children($visit);
@!outer.pop();
}
else {
} elsif $type eq 'subrule' {
$node[$i] := $!main_opt($node[$i]) if $!main_opt;
$node[$i] := self.simplify_assertion($visit);
} elsif $type eq 'qastnode' {
$node[$i] := $!main_opt($node[$i]) if $!main_opt;
} elsif $type eq 'anchor' {
} elsif $type eq 'enumcharlist' {
} elsif $type eq 'cclass' {
} elsif $type eq 'scan' {
} elsif $type eq 'charrange' {
} elsif $type eq 'dynquant' {
$node[$i] := $!main_opt($node[$i]) if $!main_opt;
} elsif $type eq 'pass' || $type eq 'fail' {
} else {
# alt, altseq, conjseq, conj, quant
self.visit_children($visit);
}
$i := $i + 1;
} elsif nqp::istype($visit, QAST::Block) {
@!outer.push($visit);
self.visit_children($visit);
@!outer.pop();
}
else {
self.visit_children($visit);
}
$i := $i + 1;
}
}
}
......@@ -88,6 +88,11 @@ my class NQPMu {
nqp::istype($topic, self.WHAT)
}
proto method NOT-ACCEPTS($topic) { * }
multi method NOT-ACCEPTS(NQPMu:U $self: $topic) {
nqp::isfalse(nqp::istype($topic, self.WHAT))
}
method isa($type) {
self.HOW.isa(self, $type)
}
......@@ -114,7 +119,11 @@ nqp::sethllconfig('nqp', nqp::hash(
'list', NQPArray,
'slurpy_array', NQPArray,
'array_iter', NQPArrayIter,
'hash_iter', NQPHashIter
'hash_iter', NQPHashIter,
'foreign_transform_hash', -> $hash {
# BOOTHashes don't actually need transformation
nqp::ishash($hash) ?? $hash !! $hash.FLATTENABLE_HASH
},
));
my class NQPLabel { }
......@@ -19,10 +19,6 @@ knowhow NQPClassHOW {
has @!roles;
has $!default_parent;
# Vtable and mapping of method names to slots.
has @!vtable;
has %!method-vtable-slots;
# Have we been composed?
has $!composed;
......@@ -71,8 +67,6 @@ knowhow NQPClassHOW {
@!multi_methods_to_incorporate := nqp::list();
@!parents := nqp::list();
@!roles := nqp::list();
@!vtable := nqp::list();
%!method-vtable-slots := nqp::hash();
@!mro := nqp::list();
@!done := nqp::list();
@!BUILDALLPLAN := nqp::list();
......
......@@ -2078,10 +2078,6 @@ my %const_map := nqp::hash(
'PIPE_CAPTURE_ERR', 256,
'PIPE_MERGED_OUT_ERR', 512,
# could probably support a few more...
'SIG_INT', 2,
'SIG_KILL', 9,
'TYPE_CHECK_CACHE_DEFINITIVE', 0,
'TYPE_CHECK_CACHE_THEN_METHOD', 1,
'TYPE_CHECK_NEEDS_ACCEPTS', 2,
......@@ -2662,6 +2658,12 @@ QAST::OperationsJAST.map_classlib_core_op('setdebugtypename', $TYPE_OPS, 'setdeb
# defined - overridden by HLL, but by default same as .DEFINITE.
QAST::OperationsJAST.map_classlib_core_op('defined', $TYPE_OPS, 'isconcrete', [$RT_OBJ], $RT_INT, :tc);
# object ops that don't do the usual decontainerization
QAST::OperationsJAST.map_classlib_core_op('what_nd', $TYPE_OPS, 'what_nd', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('how_nd', $TYPE_OPS, 'how_nd', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('clone_nd', $TYPE_OPS, 'clone_nd', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('isconcrete_nd', $TYPE_OPS, 'isconcrete_nd', [$RT_OBJ], $RT_INT, :tc);
# container related
QAST::OperationsJAST.map_classlib_core_op('setcontspec', $TYPE_OPS, 'setcontspec', [$RT_OBJ, $RT_STR, $RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('iscont', $TYPE_OPS, 'iscont', [$RT_OBJ], $RT_INT);
......@@ -2813,6 +2815,7 @@ QAST::OperationsJAST.map_classlib_core_op('nfarunalt', $TYPE_OPS, 'nfarunalt', [
# process related opcodes
QAST::OperationsJAST.map_classlib_core_op('exit', $TYPE_OPS, 'exit', [$RT_INT], $RT_INT, :tc);
QAST::OperationsJAST.map_classlib_core_op('getsignals', $TYPE_IO_OPS, 'getsignals', [], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('sleep', $TYPE_OPS, 'sleep', [$RT_NUM], $RT_NUM);
QAST::OperationsJAST.map_classlib_core_op('getenvhash', $TYPE_OPS, 'getenvhash', [], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('getpid', $TYPE_OPS, 'getpid', [], $RT_INT, :tc);
......@@ -2857,6 +2860,8 @@ QAST::OperationsJAST.map_classlib_core_op('killprocasync', $TYPE_IO_OPS, 'killpr
QAST::OperationsJAST.map_classlib_core_op('cas', $TYPE_OPS, 'cas', [$RT_OBJ, $RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('atomicload', $TYPE_OPS, 'atomicload', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('atomicstore', $TYPE_OPS, 'atomicstore', [$RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('casattr', $TYPE_OPS, 'casattr', [$RT_OBJ, $RT_OBJ, $RT_STR, $RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('atomicbindattr', $TYPE_OPS, 'atomicbindattr', [$RT_OBJ, $RT_OBJ, $RT_STR, $RT_OBJ], $RT_OBJ, :tc);
# JVM-specific ops for compilation unit handling
QAST::OperationsJAST.map_classlib_core_op('compilejast', $TYPE_OPS, 'compilejast', [$RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
......
......@@ -31,6 +31,7 @@ public class AsyncProcessHandle implements IIOClosable {
private SixModelObject bufType;
private int outSeq = 0;
private int errSeq = 0;
private boolean procStarted = false;
public AsyncProcessHandle(ThreadContext tc, SixModelObject queue, SixModelObject argsObj,
String cwd, SixModelObject envObj, SixModelObject configObj) {
......@@ -52,6 +53,7 @@ public class AsyncProcessHandle implements IIOClosable {
public void run() {
try {
AsyncProcessHandle.this.proc = pb.start();
procStarted = true;
int pid = (int)getPID(AsyncProcessHandle.this.proc);
......@@ -77,7 +79,7 @@ public class AsyncProcessHandle implements IIOClosable {
send(done, boxInt(outcome << 8));
}
catch (Throwable t) {
SixModelObject message = boxError(t.getMessage());
SixModelObject message = boxError(t.toString());
SixModelObject error = config.get("error");
if (error != null)
......@@ -197,7 +199,7 @@ public class AsyncProcessHandle implements IIOClosable {
}
catch (Throwable t) {
send(callback, boxInt(-1), AsyncProcessHandle.this.hllConfig.strBoxType,
boxError(t.getMessage()));
boxError(t.toString()));
}
}
}).start();
......@@ -219,13 +221,18 @@ public class AsyncProcessHandle implements IIOClosable {
return Ops.box_i(value, this.hllConfig.intBoxType, this.tc);
}
public void writeBytes(ThreadContext tc, AsyncTaskInstance task, SixModelObject toWrite) {
public synchronized void writeBytes(ThreadContext tc, AsyncTaskInstance task, SixModelObject toWrite) {
ByteBuffer buffer = Buffers.unstashBytes(toWrite, tc);
OutputStream stream = this.proc.getOutputStream();
SixModelObject Array = this.hllConfig.listType;
SixModelObject result = Array.st.REPR.allocate(tc, Array.st);
result.push_boxed(tc, task.schedulee);
try {
/* wait up to one second for proc */
for (int counter = 0; !procStarted && counter < 100; counter++)
wait(10);
/* TODO: is it better to check if proc is null and
* throw an Exception with a fitting message? */
OutputStream stream = this.proc.getOutputStream();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
stream.write(bytes);
......@@ -234,7 +241,7 @@ public class AsyncProcessHandle implements IIOClosable {
}
catch (Throwable t) {
result.push_boxed(tc, this.hllConfig.strBoxType);
result.push_boxed(tc, boxError(t.getMessage()));
result.push_boxed(tc, boxError(t.toString()));
}
((ConcBlockingQueueInstance)task.queue).push_boxed(tc, result);
}
......
......@@ -50,11 +50,36 @@ public class AsyncServerSocketHandle implements IIOBindable, IIOCancelable {
final SixModelObject IOType = hllConfig.ioType;
final SixModelObject Array = hllConfig.listType;
final SixModelObject Null = hllConfig.nullValue;
final SixModelObject Int = hllConfig.intBoxType;
final SixModelObject Str = hllConfig.strBoxType;
@Override
public void completed(AsynchronousSocketChannel channel, AsyncTaskInstance task) {
listenChan.accept(task, this);
InetSocketAddress localAddress;
InetSocketAddress remoteAddress;
try {
localAddress = (InetSocketAddress) channel.getLocalAddress();
} catch (IOException e) {
throw ExceptionHandling.dieInternal(tc, e);
}
String socketHost = localAddress.getAddress().getHostAddress();
if (socketHost.equals("0:0:0:0:0:0:0:1"))
socketHost = "::1";
int socketPort = localAddress.getPort();
try {
remoteAddress = (InetSocketAddress) channel.getRemoteAddress();
} catch (IOException e) {
throw ExceptionHandling.dieInternal(tc, e);
}
String peerHost = remoteAddress.getAddress().getHostAddress();
if (peerHost.equals("0:0:0:0:0:0:0:1"))
peerHost = "::1";
int peerPort = localAddress.getPort();
ThreadContext curTC = tc.gc.getCurrentThreadContext();
AsyncSocketHandle handle = new AsyncSocketHandle(curTC, channel);
......@@ -66,6 +91,10 @@ public class AsyncServerSocketHandle implements IIOBindable, IIOCancelable {
result.push_boxed(curTC, task.schedulee);
result.push_boxed(curTC, ioHandle);
result.push_boxed(curTC, Null);
result.push_boxed(curTC, Ops.box_s(socketHost, Str, curTC));
result.push_boxed(curTC, Ops.box_i(socketPort, Int, curTC));
result.push_boxed(curTC, Ops.box_s(peerHost, Str, curTC));
result.push_boxed(curTC, Ops.box_i(peerPort, Int, curTC));
((ConcBlockingQueueInstance) task.queue).push_boxed(curTC, result);
}
......@@ -76,7 +105,7 @@ public class AsyncServerSocketHandle implements IIOBindable, IIOCancelable {
SixModelObject result = Array.st.REPR.allocate(curTC, Array.st);
result.push_boxed(curTC, task.schedulee);
result.push_boxed(curTC, IOType);
result.push_boxed(curTC, Ops.box_s(exc.getMessage(), Str, curTC));
result.push_boxed(curTC, Ops.box_s(exc.toString(), Str, curTC));
}
};
......
......@@ -7,6 +7,7 @@ import java.nio.CharBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.channels.ClosedChannelException;
import org.perl6.nqp.runtime.Buffers;
import org.perl6.nqp.runtime.ExceptionHandling;
......@@ -18,7 +19,7 @@ import org.perl6.nqp.sixmodel.reprs.AsyncTaskInstance;
import org.perl6.nqp.sixmodel.reprs.ConcBlockingQueueInstance;
import org.perl6.nqp.sixmodel.reprs.IOHandleInstance;
public class AsyncSocketHandle implements IIOClosable {
public class AsyncSocketHandle implements IIOClosable, IIOCancelable {
private AsynchronousSocketChannel channel;
public AsyncSocketHandle(ThreadContext tc) {
......@@ -42,6 +43,7 @@ public class AsyncSocketHandle implements IIOClosable {
HLLConfig hllConfig = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig;
final SixModelObject IOType = hllConfig.ioType;
final SixModelObject Array = hllConfig.listType;
final SixModelObject Int = hllConfig.intBoxType;
final SixModelObject Str = hllConfig.strBoxType;
@Override
......@@ -51,20 +53,33 @@ public class AsyncSocketHandle implements IIOClosable {
IOHandleInstance ioHandle = (IOHandleInstance) IOType.st.REPR.allocate(curTC,
IOType.st);
ioHandle.handle = task.handle;
callback(curTC, task, ioHandle, Str);
callback(curTC, task, ioHandle, Str,
Ops.box_s(host, Str, curTC),
Ops.box_i(port, Int, curTC),
Ops.box_s(host, Str, curTC), // TODO send socketHost
Ops.box_i(port, Int, curTC) // TODO send socketPort
);
}
@Override
public void failed(Throwable t, AsyncTaskInstance task) {
ThreadContext curTC = tc.gc.getCurrentThreadContext();
callback(curTC, task, IOType, Ops.box_s(t.toString(), Str, curTC));
callback(curTC, task, IOType,
Ops.box_s(t.toString(), Str, curTC), Str, Int, Str, Int);
}
protected void callback(ThreadContext tc, AsyncTaskInstance task, SixModelObject ioHandle, SixModelObject err) {
protected void callback(ThreadContext tc, AsyncTaskInstance task,
SixModelObject ioHandle, SixModelObject err,
SixModelObject peerHost, SixModelObject peerPort,
SixModelObject socketHost, SixModelObject socketPort) {
SixModelObject result = Array.st.REPR.allocate(tc, Array.st);
result.push_boxed(tc, task.schedulee);
result.push_boxed(tc, ioHandle);
result.push_boxed(tc, err);
result.push_boxed(tc, peerHost);
result.push_boxed(tc, peerPort);
result.push_boxed(tc, socketHost);
result.push_boxed(tc, socketPort);
((ConcBlockingQueueInstance) task.queue).push_boxed(tc, result);
}
};
......@@ -173,7 +188,8 @@ public class AsyncSocketHandle implements IIOClosable {
@Override
public void failed(Throwable t, AsyncTaskInstance task) {
ThreadContext curTC = tc.gc.getCurrentThreadContext();
SixModelObject err = (t instanceof AsynchronousCloseException)
SixModelObject err = (t instanceof AsynchronousCloseException
|| t instanceof ClosedChannelException)
? Str : Ops.box_s(t.toString(), Str, curTC);
callback(curTC, task, -1, Str, err);
}
......@@ -203,4 +219,9 @@ public class AsyncSocketHandle implements IIOClosable {
throw ExceptionHandling.dieInternal(tc, e);
}
}
@Override
public void cancel(ThreadContext tc) {
close(tc);
}
}
package org.perl6.nqp.runtime;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.perl6.nqp.io.AsyncProcessHandle;
import org.perl6.nqp.io.AsyncServerSocketHandle;
import org.perl6.nqp.io.AsyncSocketHandle;
......@@ -26,6 +35,120 @@ public final class IOOps {
new Object[] { Ops.box_i(signum, tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.intBoxType, tc) });
}
}
private static class SigProcess {
private static final int SIGNUM_HIGHEST = 32;
private static class SigSupported {
private static List<String> supported = Arrays.asList("SIGINT", "SIGKILL");
public static Map<String, Integer> build() {
Map<String, Integer> m = new HashMap<String, Integer>();
for ( String k : supported ) { m.put(k, 1); }
return m;
}
}
private static final Map<String, Integer> sigSupported = SigSupported.build();
public static final List<String> sigKeys = Arrays.asList(
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", "SIGABRT",
"SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS",
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGURG", "SIGSTOP", "SIGTSTP",
"SIGCONT", "SIGCHLD", "SIGTTIN", "SIGTTOU", "SIGIO", "SIGXCPU",
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH", "SIGINFO", "SIGUSR1",
"SIGUSR2", "SIGTHR", "SIGSTKFLT", "SIGPWR", "SIGBREAK"
);
private static String getNameFromVal(int signum) {
// Use sh kill builtin, seems most portable across MacOSX, and Linux and BSD variants
final String SH_ARG = "kill -l " + Integer.toString(signum);
ProcessBuilder pb = new ProcessBuilder("sh", "-c", SH_ARG);
try {
int retval = -1;
boolean finished = false;
Process process = pb.start();
do {
try {
retval = process.waitFor();
finished = true;
} catch (InterruptedException e) {
}
} while (!finished);
if (retval == 0) {
BufferedReader br = new BufferedReader(
new InputStreamReader( process.getInputStream() )
);
String s;
if ( (s = br.readLine()) != null ) {
return "SIG" + s.trim().toUpperCase();
}
}
} catch (IOException e) { }
return null;
}
private static void retrieveValsWin(Map<String, Integer> sigWanted) {
// Use same sigs defined for _WIN32 in MoarVM
sigWanted.put("SIGHUP", 1);
sigWanted.put("SIGKILL", 9);
sigWanted.put("SIGWINCH", 28);
}
private static void retrieveValsPosix(Map<String, Integer> sigWanted) {
String sigval = "";
int i = 1;
while (sigval != null && i <= SIGNUM_HIGHEST) {
sigval = getNameFromVal(i);
if (sigval != null && sigWanted.containsKey(sigval)) {
sigWanted.put(sigval, i);
}
i++;
}
}
public static Map<String, Integer> process() {
Map<String, Integer> sigWanted = new HashMap<String, Integer>();
for ( String k : sigKeys ) { sigWanted.put(k, 0); }
// Get available signals on host system
String os = System.getProperty("os.name").toLowerCase();
if ( os.indexOf("win") >= 0 ) {
retrieveValsWin(sigWanted);
} else {
retrieveValsPosix(sigWanted);
}
// Negate sigs not supported by backend
for (String sig : sigWanted.keySet()) {
int signum = sigWanted.get(sig);
int signumFinal = sigSupported.containsKey(sig) ? signum : -signum;
sigWanted.put(sig, signumFinal);
}
return sigWanted;
}
}
private static SixModelObject sigCache = null;
public static SixModelObject getsignals(ThreadContext tc) {
if (sigCache != null) return sigCache;
SixModelObject listType = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.listType;
SixModelObject strType = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.strBoxType;
SixModelObject intType = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.intBoxType;
SixModelObject res = listType.st.REPR.allocate(tc, listType.st);
Map<String, Integer> sigWanted = SigProcess.process();
// Box the list values for HLL
for (String sig : SigProcess.sigKeys) {
long signum = (long)sigWanted.get(sig);
res.push_boxed( tc, Ops.box_s(sig, strType, tc) );
res.push_boxed( tc, Ops.box_i(signum, intType, tc) );
}
sigCache = res;
return res;
}
public static SixModelObject signal(SixModelObject queue, SixModelObject schedulee,
long signalNum, SixModelObject asyncType, ThreadContext tc) {
switch((int)signalNum) {
......
......@@ -2461,9 +2461,15 @@ public final class Ops {
public static SixModelObject what(SixModelObject o, ThreadContext tc) {
return decont(o, tc).st.WHAT;
}
public static SixModelObject what_nd(SixModelObject o, ThreadContext tc) {
return o.st.WHAT;
}
public static SixModelObject how(SixModelObject o, ThreadContext tc) {
return decont(o, tc).st.HOW;
}
public static SixModelObject how_nd(SixModelObject o, ThreadContext tc) {
return o.st.HOW;
}
public static SixModelObject who(SixModelObject o, ThreadContext tc) {
return decont(o, tc).st.WHO;
}
......@@ -2491,9 +2497,15 @@ public final class Ops {
public static SixModelObject clone(SixModelObject obj, ThreadContext tc) {
return decont(obj, tc).clone(tc);
}
public static SixModelObject clone_nd(SixModelObject obj, ThreadContext tc) {
return obj.clone(tc);
}
public static long isconcrete(SixModelObject obj, ThreadContext tc) {
return obj == null || decont(obj, tc) instanceof TypeObject ? 0 : 1;
}
public static long isconcrete_nd(SixModelObject obj, ThreadContext tc) {
return obj == null || obj instanceof TypeObject ? 0 : 1;
}
public static SixModelObject knowhow(ThreadContext tc) {
return tc.gc.KnowHOW;
}
......@@ -3164,9 +3176,9 @@ public final class Ops {
throw ExceptionHandling.dieInternal(tc, "This is not a native str array");
return tc.native_s;
}
public static SixModelObject slice(SixModelObject arr, long start, long end, ThreadContext tc) {
public static SixModelObject slice(SixModelObject arr, long beginning, long end, ThreadContext tc) {
SixModelObject dest = arr.st.REPR.allocate(tc, arr.st);
return arr.slice(tc, dest, start, end);
return arr.slice(tc, dest, beginning, end);
}
public static SixModelObject splice(SixModelObject arr, SixModelObject from, long offset, long count, ThreadContext tc) {
arr.splice(tc, from, offset, count);
......
......@@ -121,7 +121,7 @@ public abstract class SixModelObject implements Cloneable {
public void shift_native(ThreadContext tc) {
throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not implement shift_native");
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not implement slice");
}
public void splice(ThreadContext tc, SixModelObject from, long offset, long count) {
......
......@@ -54,7 +54,7 @@ public class TypeObject extends SixModelObject {
public SixModelObject shift_boxed(ThreadContext tc) {
throw ExceptionHandling.dieInternal(tc, "Cannot do aggregate operation on a type object");
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
throw ExceptionHandling.dieInternal(tc, "Cannot do aggregate operation on a type object");
}
public void splice(ThreadContext tc, SixModelObject from, long offset, long count) {
......
......@@ -89,7 +89,7 @@ public abstract class MultiDimArrayInstanceBase extends SixModelObject {
public void shift_native(ThreadContext tc) {
throw ExceptionHandling.dieInternal(tc, "Cannot shift a fixed dimension array");
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
throw ExceptionHandling.dieInternal(tc, "Cannot slice a multidim array");
}
public void splice(ThreadContext tc, SixModelObject from, long offset, long count) {
......
......@@ -160,8 +160,8 @@ public class P6OpaqueBaseInstance extends SixModelObject {
public void shift_native(ThreadContext tc) {
posDelegate().shift_native(tc);
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
return posDelegate().slice(tc, dest, start, end);
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
return posDelegate().slice(tc, dest, beginning, end);
}
public void splice(ThreadContext tc, SixModelObject from, long offset, long count) {
posDelegate().splice(tc, from, offset, count);
......
......@@ -61,8 +61,8 @@ public class P6OpaqueDelegateInstance extends P6OpaqueBaseInstance {
public SixModelObject shift_boxed(ThreadContext tc) {
return delegate.shift_boxed(tc);
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
return delegate.slice(tc, dest, start, end);
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
return delegate.slice(tc, dest, beginning, end);
}
public void splice(ThreadContext tc, SixModelObject from, long offset, long count) {
delegate.splice(tc, from, offset, count);
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance extends VMArrayInstanceBase {
return result;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
dest.bind_pos_boxed(tc, i, this.at_pos_boxed(tc, start + i));
dest.bind_pos_boxed(tc, i, this.at_pos_boxed(tc, beginning + i));
}
}
return dest;
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance_i extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance_i16 extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance_i32 extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance_i8 extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance_n extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -174,17 +174,19 @@ public class VMArrayInstance_s extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -178,17 +178,19 @@ public class VMArrayInstance_u16 extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -178,17 +178,19 @@ public class VMArrayInstance_u32 extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -178,17 +178,19 @@ public class VMArrayInstance_u8 extends VMArrayInstanceBase {
elems--;
}
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long start, long end) {
start = start < 0 ? this.elems + start : start;
end = end < 0 ? this.elems + end : end;
if ( end < start || start < 0 || end < 0 || this.elems <= start || this.elems <= end ) {
public SixModelObject slice(ThreadContext tc, SixModelObject dest, long beginning, long end) {
beginning = beginning < 0 ? this.elems + beginning : beginning;
end = end < 0 ? this.elems + end : end;
if ( end < beginning || beginning < 0 || end < 0
|| this.elems <= beginning || this.elems <= end )
{
throw ExceptionHandling.dieInternal(tc, "VMArray: Slice index out of bounds");
}
long numWanted = end - start + 1;
long numWanted = end - beginning + 1;
if (0 < numWanted) {
for (long i = 0; i < numWanted; i++) {
this.at_pos_native(tc, start + i);
this.at_pos_native(tc, beginning + i);
dest.bind_pos_native(tc, i);
}
}
......
......@@ -639,7 +639,7 @@ my $chain_gen := sub ($qastcomp, $op) {
# Check if callee sub in name, if not first child is callee, not arg
my $arg_idx;
my &get_arg_idx := -> $cq { nqp::if( $cq.name, 0, 1 ) };
my &get_arg_idx := -> $cq { $cq.name ?? 0 !! 1 };
while nqp::istype($cqast, QAST::Op)
&& ($cqast.op eq 'chain' || $cqast.op eq 'chainstatic') {
......@@ -651,7 +651,6 @@ my $chain_gen := sub ($qastcomp, $op) {
my @ops;
my $regalloc := $*REGALLOC;
my $res_reg := $regalloc.fresh_register($MVM_reg_obj);
my $decont_reg := $regalloc.fresh_register($MVM_reg_obj);
my $endlabel := MAST::Label.new();
$cqast := nqp::pop(@clist);
......@@ -682,10 +681,8 @@ my $chain_gen := sub ($qastcomp, $op) {
:result($res_reg),
$acomp.result_reg, $bcomp.result_reg
));
push_op(@ops, 'decont', $decont_reg, $callee.result_reg);
$regalloc.release_register($callee.result_reg, $MVM_reg_obj);
$regalloc.release_register($decont_reg, $MVM_reg_obj);
$regalloc.release_register($acomp.result_reg, $MVM_reg_obj);
if @clist {
......@@ -2020,42 +2017,6 @@ my %const_map := nqp::hash(
'PIPE_CAPTURE_ERR', 256,
'PIPE_MERGED_OUT_ERR', 512,
'SIG_HUP', 1,
'SIG_INT', 2,
'SIG_QUIT', 3,
'SIG_ILL', 4,
'SIG_TRAP', 5,
'SIG_ABRT', 6,
'SIG_EMT', 7,
'SIG_FPE', 8,
'SIG_KILL', 9,
'SIG_BUS', 10,
'SIG_SEGV', 11,
'SIG_SYS', 12,
'SIG_PIPE', 13,
'SIG_ALRM', 14,
'SIG_TERM', 15,
'SIG_URG', 16,
'SIG_STOP', 17,
'SIG_TSTP', 18,
'SIG_CONT', 19,
'SIG_CHLD', 20,
'SIG_TTIN', 21,
'SIG_TTOU', 22,
'SIG_IO', 23,
'SIG_XCPU', 24,
'SIG_XFSZ', 25,
'SIG_VTALRM', 26,
'SIG_PROF', 27,
'SIG_WINCH', 28,
'SIG_INFO', 29,
'SIG_USR1', 30,
'SIG_USR2', 31,
'SIG_THR', 32,
'SIG_STKFLT', 116,
'SIG_PWR', 130,
'SIG_BREAK', 221,
'TYPE_CHECK_CACHE_DEFINITIVE', 0,
'TYPE_CHECK_CACHE_THEN_METHOD', 1,
'TYPE_CHECK_NEEDS_ACCEPTS', 2,
......@@ -2258,6 +2219,9 @@ QAST::MASTOperations.add_core_moarop_mapping('tonum_I', 'coerce_In');
QAST::MASTOperations.add_core_moarop_mapping('fromnum_I', 'coerce_nI');
QAST::MASTOperations.add_core_moarop_mapping('fromI_I', 'coerce_II');
QAST::MASTOperations.add_core_moarop_mapping('coerce_in', 'coerce_in');
QAST::MASTOperations.add_core_moarop_mapping('coerce_ni', 'coerce_ni');
# trig opcodes
QAST::MASTOperations.add_core_moarop_mapping('sin_n', 'sin_n');
QAST::MASTOperations.add_core_moarop_mapping('asin_n', 'asin_n');
......@@ -2497,6 +2461,7 @@ QAST::MASTOperations.add_core_moarop_mapping('multidimref_n', 'multidimref_n');
QAST::MASTOperations.add_core_moarop_mapping('multidimref_s', 'multidimref_s');
QAST::MASTOperations.add_core_moarop_mapping('atkey', 'atkey_o');
QAST::MASTOperations.add_core_moarop_mapping('atkey_i', 'atkey_i');
QAST::MASTOperations.add_core_moarop_mapping('atkey_u', 'atkey_u');
QAST::MASTOperations.add_core_moarop_mapping('atkey_n', 'atkey_n');