Hello community, here is the log from the commit of package nqp for openSUSE:Factory checked in at 2017-08-22 11:10:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nqp (Old) and /work/SRC/openSUSE:Factory/.nqp.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nqp" Tue Aug 22 11:10:41 2017 rev:22 rq:518006 version:2017.08 Changes: -------- --- /work/SRC/openSUSE:Factory/nqp/nqp.changes 2017-07-30 11:27:25.485016111 +0200 +++ /work/SRC/openSUSE:Factory/.nqp.new/nqp.changes 2017-08-22 11:10:43.459118133 +0200 @@ -1,0 +2,21 @@ +Mon Aug 21 23:05:32 CEST 2017 - [email protected] + +- Remove nqp-fix-ll-exception.diff - included in upstream release +- update to version 2017.08 + * Fix serious security hole - tried to load modules from current working + directory + * support hardware_concurrency op from moar and implement for jvm + * match renamed opcode "cpucores" in moar + * Fix --ll-exception trying to print a NULL + * Add nqp::codes to QASTOperationsMAST.nqp + * Add a &dies-ok to the setting so that it can be shared across tests + * Add eqatim and indexim ops. Fix a bug when using ignoremark + * Correct setup of $sharedclass in regex compiler. + * Map the low level nativecallinvoke op + * output .sql profiler data if template.html not found + * Map new atomic ops on MoarVM backend. + * Add constant mapping atomic integer type. + * Add nqp::hasuniprop op to QASTOperationsMAST.nqp + * Add support for %*ENV<NQP_LIB> to MoarVM and JS ModuleLoaders + +------------------------------------------------------------------- Old: ---- nqp-2017.07.tar.gz nqp-fix-ll-exception.diff New: ---- nqp-2017.08.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nqp.spec ++++++ --- /var/tmp/diff_new_pack.c7O52d/_old 2017-08-22 11:10:44.490972841 +0200 +++ /var/tmp/diff_new_pack.c7O52d/_new 2017-08-22 11:10:44.502971152 +0200 @@ -17,16 +17,15 @@ Name: nqp -Version: 2017.07 +Version: 2017.08 Release: 1.1 Summary: Not Quite Perl License: Artistic-2.0 Group: Development/Languages/Other Url: http://rakudo.org/ Source: nqp-%{version}.tar.gz -Patch1: nqp-fix-ll-exception.diff BuildRequires: moarvm-devel -Requires: moarvm >= 2017.07 +Requires: moarvm >= 2017.08 BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -35,7 +34,6 @@ %prep %setup -q -%patch1 -p1 %build perl Configure.pl --backends=moar --libdir=%{_libdir} --prefix=%{_usr} --with-moar=/usr/bin/moar ++++++ nqp-2017.07.tar.gz -> nqp-2017.08.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/MANIFEST new/nqp-2017.08/MANIFEST --- old/nqp-2017.07/MANIFEST 2017-07-15 22:48:08.000000000 +0200 +++ new/nqp-2017.08/MANIFEST 2017-08-21 17:10:40.000000000 +0200 @@ -578,6 +578,7 @@ t/moar/07-eqatic.t t/moar/08-indexic.t t/moar/09-concat.t +t/moar/10-eqatim.t t/moar/50-jit-register-alloc.t t/moar/51-jit-div_i.t t/nativecall/01-basic.t @@ -688,6 +689,7 @@ t/nqp/108-vmhash.t t/nqp/109-coercions.t t/nqp/110-normalization.t +t/nqp/111-spawnprocasync.t t/nqp/19-readline.txt t/nqp/19-setinputlinesep.txt t/p5regex/01-p5regex.t diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/VERSION new/nqp-2017.08/VERSION --- old/nqp-2017.07/VERSION 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/VERSION 2017-08-21 17:03:13.000000000 +0200 @@ -1 +1 @@ -2017.07 +2017.08 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/docs/ops.markdown new/nqp-2017.08/docs/ops.markdown --- old/nqp-2017.07/docs/ops.markdown 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/docs/ops.markdown 2017-08-21 17:01:35.000000000 +0200 @@ -302,6 +302,17 @@ - [asyncreadbytes](#asyncreadbytes) - [spawnprocasync](#spawnprocasync) - [killprocasync](#killprocasync) +- [Atomic Operations](#-atomic-operations) + - [cas](#cas) + - [cas_i](#cas_i)) + - [atomicinc_i](#atomicinc_i) + - [atomicdec_i](#atomicdec_i) + - [atomicadd_i](#atomicadd_i) + - [atomicload](#atomicload) + - [atomicload_i](#atomicload_i) + - [atomicstore](#atomicstore) + - [atomicstore_i](#atomicstore_i) + - [barrierfull](#barrierfull) # NQP Opcodes @@ -382,6 +393,7 @@ * [Miscellaneous Opcodes](#misc) * [Native Call / Interoperability Opcodes](#nativecall) * [Asynchronous operations](#async) +* [Atomic operations](#atomic) # <a id="arithmetic"></a> Arithmetic Opcodes @@ -2010,6 +2022,8 @@ If the object has a method of the given name, return 1. Otherwise, return 0. +Returns 1 if ``$obj`` object has FALLBACK method. + ## clone * `clone(Mu $obj)` @@ -2569,3 +2583,88 @@ ## killprocasync `moar` * `killprocasync($handle, $signal)` + +# <a id="atomic"></a> Atomic Operations + +## cas `moar` +* `cas(ObjectContainer $cont, Mu $expected, Mu $new)` + +Takes an object which has a container spec set on it that knows how to do an +atomic compare and swap, and performs an atomic compare and swap operation. +The operation atomically compares the `$expected` object with what is currently +held in the container. If they are the same object, then it replaces it with +`$new`. If not, no change takes place. The original object stored in the +container is returned, which can be used with `eqaddr` to check if it is the +same as the `$expected` object. The container may perform type checks on the +`$new` object before it attempts the operation. + +## cas_i `moar` +* `cas_i(NativeIntRef $i, int64 $expected, int64 $new)` + +Takes an object with the `NativeRef` representation, which must point to an +integer of the machine's atomic operation size. Casts the expected and new +parameters to the machine's atomic operation size, and then uses them to +perform an atomic compare and swap operation on the referenced integer. The +operation atomically compares the `$expected` value with the value currently +at the referenced location. If they are equal, it replaces the value with +`$new`. If they are not equal, nothing happens. The operation evaluates to the +value originally at the location (which can be compared with `$expected` to +see if the operation was a success). + +## atomicinc_i `moar` +* `atomicinc_i(NativeIntRef $i)` + +Takes an object with the `NativeRef` representation, which must point to an +integer of the machine's atomic operation size. Performs an atomic increment +of the referenced integer. Returns the value **before** it was incremented. + +## atomicdec_i `moar +* `atomicdec_i(NativeIntRef $i)` + +Takes an object with the `NativeRef` representation, which must point to an +integer of the machine's atomic operation size. Performs an atomic decrement +of the referenced integer. Returns the value **before** it was decremented. + +## atomicadd_i `moar` +* `atomicadd_i(NativeIntRef $i, int $value)` + +Takes an object with the `NativeRef` representation, which must point to an +integer of the machine's atomic operation size. Performs an atomic addition of +the provided value, which will be cast to the machine's atomic operation size +before the operation is performed. Returns the value at the memory location +**before** the addition was performed. + +## atomicload `moar` +* `atomicload(ObjectContainer $c)` + +Takes an object which has a container spec set on it that knows how to do an +atomic load (that is, with appropriate barriering to ensure the latest value +is read). Performs the atomic load, and returns the loaded object. + +## atomicload_i `moar` +* `atomicload_i(NativeIntRef $i)` + +Takes an object with the `NativeRef` representation, which must point to an +integer of the machine's atomic operation size. Performs an atomic load (that +is, with appropriate barriering to ensure the latest value is read). + +## atomicstore `moar` +* `atomicstore(ObjectContainer $c, Mu $value)` + +Takes an object which has a container spec set on it that knows how to do an +atomic load. Performs the atomic store, which may fail if the value being +stored does not, for example, meet type constraints. Evaluates to the stored +value. The store performs appropriate barriering to ensure the changed value +is "published". + +## atomicstore_i `moar` +* `atomicstore_i(NativeIntRef $i, int64 $value)` + +Takes an object with the `NativeRef` representation, which must point to an +integer of the machine's atomic operation size. Performs an atomic store (that +is, with appropriate barriering to ensure the changed value is "published"). + +## barrierfull `moar` +* `barrierfull()` + +Performs a full memory barrier. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/examples/rubyish/t/interpolation.t new/nqp-2017.08/examples/rubyish/t/interpolation.t --- old/nqp-2017.07/examples/rubyish/t/interpolation.t 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/examples/rubyish/t/interpolation.t 2017-08-21 17:01:35.000000000 +0200 @@ -10,7 +10,7 @@ puts %Q{ok #{a*=3} - expression - side affect} puts %Q{ok #{(a+=2)-1} - expression - side affect} puts "#{if a==8 then 'ok' else 'nok' end} #{a} - nested statement" -puts "#{'#{tst}' == '#' '{' 'tst}'? 'ok' : 'nok'} 9 - nested starters / stoppers" +puts "#{'#{tst}' eq '#' '{' 'tst}'? 'ok' : 'nok'} 9 - nested starters / stoppers" puts "ok #{ x = 4; x+= 1 x+5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/package.json new/nqp-2017.08/package.json --- old/nqp-2017.07/package.json 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/package.json 2017-08-21 17:01:35.000000000 +0200 @@ -4,12 +4,7 @@ "url:": "https://github.com/perl6/nqp/issues", "email": "[email protected]" }, - "licenses": [ - { - "type": "Artistic 2", - "url": "http://opensource.org/licenses/Artistic-2.0" - } - ], + "license": "Artistic-2.0", "private": true, "repository": "http://github.com/perl6/nqp/", "devDependencies": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/HLL/Compiler.nqp new/nqp-2017.08/src/HLL/Compiler.nqp --- old/nqp-2017.07/src/HLL/Compiler.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/HLL/Compiler.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -328,8 +328,9 @@ if %adverbs<ll-exception> || !nqp::can(self, 'handle-exception') { my $err := stderr(); my $message := nqp::getmessage($error); - if nqp::isnull($message) && nqp::can($error, 'message') { - $message := $error.message; + my $payload := nqp::getpayload($error); + if nqp::isnull_s($message) && nqp::can($payload, 'message') { + $message := $payload.message; } $err.say($message); $err.say(nqp::join("\n", nqp::backtracestrings($error))); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/QRegex/Cursor.nqp new/nqp-2017.08/src/QRegex/Cursor.nqp --- old/nqp-2017.07/src/QRegex/Cursor.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/QRegex/Cursor.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -659,6 +659,7 @@ if !nqp::isnull($actions) && nqp::can($actions, $name); } + method !shared_type() { ParseShared } method !shared() { $!shared } method !braid() { $!braid } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/core/testing.nqp new/nqp-2017.08/src/core/testing.nqp --- old/nqp-2017.07/src/core/testing.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/core/testing.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -49,4 +49,18 @@ } } +sub dies-ok($code, $description, :$message) { + my $died := 0; + my $got-message := ''; + try { $code(); CATCH { $died := 1; $got-message := nqp::getmessage($_); } } + ok($died, $description); + if $message { + if nqp::isstr($message) { + is($got-message, $message, 'got correct exception message'); + } else { + ok($got-message ~~ $message, 'exception message matches'); + } + } +} + # vim: ft=perl6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/Compiler.nqp new/nqp-2017.08/src/vm/js/Compiler.nqp --- old/nqp-2017.07/src/vm/js/Compiler.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/Compiler.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -408,12 +408,17 @@ } } + my $pos_slurpy := 0; + my $pos_required := 0; + my $pos_optional := 0; + for @params -> $param { if $param.slurpy { if $param.named { set_variable($param, "nqp.slurpyNamed(_NAMED, {known_named(@*KNOWN_NAMED)})"); } else { + $pos_slurpy := 1; set_variable($param, "nqp.slurpyArray({quote_string($*HLL)}, Array.prototype.slice.call(arguments,{+@sig}))"); } } @@ -453,6 +458,7 @@ my str $tmp := self.unique_var('param'); @sig.push($tmp); if $param.default { + $pos_optional := $pos_optional + 1; my $default_value := self.as_js($param.default, :want($T_OBJ)); @setup.push(Chunk.void( "if (arguments.length < {+@sig}) \{\n", @@ -461,6 +467,7 @@ )); } else { + $pos_required := $pos_required + 1; @setup.push($set ~ $tmp ~ ";\n"); } } @@ -468,6 +475,7 @@ my str $name := $*BLOCK.mangle_var($param); if $param.default { + $pos_optional := $pos_optional + 1; # Overwriting a parameter makes the v8 optimizer bail out so to avoid that we introduce a new variable my str $tmp := self.unique_var($name~'_'); @@ -482,6 +490,7 @@ } else { + $pos_required := $pos_required + 1; @sig.push($name); } } @@ -491,6 +500,15 @@ } } + if ($pos_required) { + @setup.push("if (arguments.length < {$pos_required+2}) nqp.tooFewPos(arguments.length, $pos_required);"); + } + + if (!$pos_slurpy) { + my $max := $pos_required + $pos_optional + 2; + @setup.push("if (arguments.length > $max) nqp.tooManyPos(arguments.length, $max);"); + } + Chunk.new($T_NONVAL, nqp::join(',', @sig), @setup); } @@ -1041,7 +1059,7 @@ %*USED_CTXS{$*CTX} := 0; - my $sig := self.compile_sig($*BLOCK.params); + my $sig := $node.custom_args ?? Chunk.new($T_NONVAL, 'caller_ctx') !! self.compile_sig($*BLOCK.params); my str $first_time_marker := $*BLOCK.maybe_first_time_marker; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/HLL/Backend.nqp new/nqp-2017.08/src/vm/js/HLL/Backend.nqp --- old/nqp-2017.07/src/vm/js/HLL/Backend.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/HLL/Backend.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -37,7 +37,11 @@ $read_all := 1; } - nqp::spawnprocasync($queue, $command, nqp::cwd(), nqp::getenvhash(), $config); + my $task := nqp::spawnprocasync($queue, $command, nqp::cwd(), nqp::getenvhash(), $config); + + if $stdout { + nqp::permit($task, 1, -1); + } while !$done || !$read_all { if nqp::shift($queue) -> $task { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/ModuleLoader.nqp new/nqp-2017.08/src/vm/js/ModuleLoader.nqp --- old/nqp-2017.07/src/vm/js/ModuleLoader.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/ModuleLoader.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -26,10 +26,10 @@ # nqp::push(@search_paths, $_) # } } - - # Add CWD and blib. - nqp::push(@search_paths, '.'); - nqp::push(@search_paths, 'blib'); + my %env := nqp::getenvhash(); + if nqp::existskey(%env, 'NQP_LIB') { + nqp::push(@search_paths, %env<NQP_LIB>); + } @search_paths } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/Operations.nqp new/nqp-2017.08/src/vm/js/Operations.nqp --- old/nqp-2017.07/src/vm/js/Operations.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/Operations.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -1690,6 +1690,8 @@ add_simple_op('spawnprocasync', $T_OBJ, [$T_OBJ, $T_OBJ, $T_STR, $T_OBJ, $T_OBJ], :ctx, :side_effects); add_simple_op('killprocasync', $T_OBJ, [$T_OBJ, $T_INT], :side_effects); + add_simple_op('permit', $T_OBJ, [$T_OBJ, $T_INT, $T_INT], :side_effects); + add_simple_op('semacquire', $T_OBJ, [$T_OBJ], :side_effects); add_simple_op('semtryacquire', $T_INT, [$T_OBJ], :side_effects); add_simple_op('semrelease', $T_OBJ, [$T_OBJ], :side_effects); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/nqp-runtime/core.js new/nqp-2017.08/src/vm/js/nqp-runtime/core.js --- old/nqp-2017.07/src/vm/js/nqp-runtime/core.js 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/nqp-runtime/core.js 2017-08-21 17:01:35.000000000 +0200 @@ -294,7 +294,7 @@ var whereCounter = 0; op.where = function(obj) { - if (obj._STable || obj instanceof CodeRef) { // HACK + if (obj._STable || obj instanceof CodeRef || obj === Null) { // HACK if (!obj._WHERE) { obj._WHERE = ++whereCounter; } @@ -457,6 +457,8 @@ function fromJS(obj) { if (typeof obj === 'function') { return new WrappedFunction(obj); + } else if (obj === undefined) { + return Null; } else { return obj; } @@ -483,7 +485,17 @@ class JavaScriptCompiler extends NQPObject { eval(ctx, _NAMED, self, code) { - return fromJS(eval(code)); + return fromJS(eval(nqp.toStr(code, ctx))); + } + + compile(ctx, _NAMED, self, code) { + const evaled = '(function(ctx) {return ' + nqp.toStr(code, ctx) + '})'; + const closure = eval(evaled); + const codeRef = new CodeRef(); + codeRef.$$call = function(ctx, _NAMED) { + return fromJS(closure(ctx)); + }; + return codeRef; } }; @@ -758,13 +770,20 @@ let fibers = require('fibers'); -function runTagged(tag, fiber, val) { - var control = fiber.run(val); +function runTagged(tag, fiber, val, ctx) { + let arg = val; while (1) { + let control = fiber.run(arg); if (control.tag == tag || control.tag === Null) { - return control.value; + if (control.value) { + return control.value; + } else { + const cont = new Cont(tag, fiber); + let value = control.closure.$$call(ctx, null, cont); + return value; + } } else { - fibers.yield(control); + arg = fibers.yield(control); } } } @@ -786,22 +805,24 @@ op.continuationreset = function(ctx, tag, block) { if (block instanceof Cont) { - return runTagged(tag, block.fiber, Null); + return runTagged(tag, block.fiber, Null, ctx); } else { - return runTagged(tag, fibers(function() { + const fiber = fibers(function() { return {value: block.$$call(ctx, null), tag: tag}; - }), Null); + }); + fiber.tag = tag; + return runTagged(tag, fiber, Null, ctx); } }; op.continuationcontrol = function(ctx, protect, tag, closure) { - return fibers.yield({value: closure.$$call(ctx, null, new Cont(tag, fibers.current)), tag: tag}); + return fibers.yield({closure: closure, tag: tag}); }; op.continuationinvoke = function(ctx, cont, inject) { var val = inject.$$call(ctx, null); - return runTagged(cont.tag, cont.fiber, val); + return runTagged(cont.tag, cont.fiber, val, ctx); }; var generator = Math; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/nqp-runtime/io.js new/nqp-2017.08/src/vm/js/nqp-runtime/io.js --- old/nqp-2017.07/src/vm/js/nqp-runtime/io.js 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/nqp-runtime/io.js 2017-08-21 17:01:35.000000000 +0200 @@ -412,18 +412,20 @@ }; -class Stdin extends StdHandle { - $$filenofh() { - return process.stdin.fd; +let stdin; +op.getstdin = function() { + if (!stdin) { + let fd; + try { + fd = fs.openSync('/dev/stdin', 'rs'); + } catch(e) { + /* this should work on Windows, we need to test it tho */ + fd = 0; + }; + stdin = new FileHandle(fd); } - $$isttyfh() { - return (process.stdin.isTTY ? 1 : 0); - } -}; - -op.getstdin = function() { - return new Stdin(); + return stdin; }; op.exit = function(code) { @@ -524,3 +526,8 @@ config.content.get('done').$$call(ctx, null, result.status << 8); } }; + +op.permit = function(handle, channel, permits) { + // TODO Implement permit handling properly + return handle; +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/nqp-runtime/multicache.js new/nqp-2017.08/src/vm/js/nqp-runtime/multicache.js --- old/nqp-2017.07/src/vm/js/nqp-runtime/multicache.js 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/nqp-runtime/multicache.js 2017-08-21 17:01:35.000000000 +0200 @@ -58,10 +58,10 @@ op.multicachefind = function(ctx, cache, capture) { if (!(cache instanceof MultiCache)) return Null; var arity = capture.pos.length; - var hasNamed = capture.named ? true : false; + if (capture.named) return Null; if (arity == 0) { - if (!hasNamed && cache.zeroArity) { + if (cache.zeroArity) { return cache.zeroArity; } else { return Null; @@ -78,7 +78,6 @@ for (var j = 0; j < arityCache[i].types.length; j++) { if (arityCache[i].types[j] !== types[j]) continue CANDIDATES; } - if (arityCache[i].hasNamed !== hasNamed) continue CANDIDATES; return arityCache[i].result; } @@ -87,13 +86,11 @@ op.multicacheadd = function(ctx, cache, capture, result) { var c = cache instanceof MultiCache ? cache : new MultiCache(); + if (c.named) return c; var arity = capture.pos.length; - var hasNamed = capture.named ? true : false; if (arity == 0) { - if (!hasNamed) { - c.zeroArity = result; - } + c.zeroArity = result; return c; } @@ -101,7 +98,7 @@ return c; } - c.cache[arity - 1].push({types: posTypes(ctx, capture), hasNamed: hasNamed, result: result}); + c.cache[arity - 1].push({types: posTypes(ctx, capture), result: result}); return c; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/nqp-runtime/package.json new/nqp-2017.08/src/vm/js/nqp-runtime/package.json --- old/nqp-2017.07/src/vm/js/nqp-runtime/package.json 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/nqp-runtime/package.json 2017-08-21 17:01:35.000000000 +0200 @@ -6,12 +6,7 @@ "url:": "https://github.com/perl6/nqp/issues", "email": "[email protected]" }, - "licenses": [ - { - "type": "Artistic 2", - "url": "http://opensource.org/licenses/Artistic-2.0" - } - ], + "license": "Artistic-2.0", "repository": "http://github.com/perl6/nqp/", "main": "runtime.js", "dependencies": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/js/nqp-runtime/runtime.js new/nqp-2017.08/src/vm/js/nqp-runtime/runtime.js --- old/nqp-2017.07/src/vm/js/nqp-runtime/runtime.js 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/js/nqp-runtime/runtime.js 2017-08-21 17:01:35.000000000 +0200 @@ -219,6 +219,7 @@ function numToStr(num) { if (num === Infinity) return 'Inf'; if (num === -Infinity) return '-Inf'; + if (num === 0 && 1/num === -Infinity) return '-0'; return num.toString(); } @@ -503,3 +504,11 @@ exports.NativeRef = require('./reprs.js').NativeRef; exports.getHLL = hll.getHLL; + +exports.tooFewPos = function(got, expected) { + throw new NQPException(`Too few positionals passed; expected ${expected} arguments but got ${got-2}`); +}; + +exports.tooManyPos = function(got, expected) { + throw new NQPException(`Too many positionals passed; expected ${expected} arguments but got ${got-2}`); +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/jvm/ModuleLoader.nqp new/nqp-2017.08/src/vm/jvm/ModuleLoader.nqp --- old/nqp-2017.07/src/vm/jvm/ModuleLoader.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/jvm/ModuleLoader.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -29,10 +29,6 @@ nqp::push(@search_paths, $_) } - # Add CWD and blib. - nqp::push(@search_paths, '.'); - nqp::push(@search_paths, 'blib'); - @search_paths } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/jvm/QAST/Compiler.nqp new/nqp-2017.08/src/vm/jvm/QAST/Compiler.nqp --- old/nqp-2017.07/src/vm/jvm/QAST/Compiler.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/jvm/QAST/Compiler.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -2064,6 +2064,7 @@ 'C_TYPE_LONGLONG', -5, 'C_TYPE_SIZE_T', -6, 'C_TYPE_BOOL', -7, + 'C_TYPE_ATOMIC_INT', -8, 'C_TYPE_FLOAT', -1, 'C_TYPE_DOUBLE', -2, 'C_TYPE_LONGDOUBLE', -3, @@ -2769,6 +2770,7 @@ QAST::OperationsJAST.map_classlib_core_op('semtryacquire', $TYPE_OPS, 'semtryacquire', [$RT_OBJ], $RT_INT, :tc); QAST::OperationsJAST.map_classlib_core_op('semrelease', $TYPE_OPS, 'semrelease', [$RT_OBJ], $RT_OBJ, :tc); QAST::OperationsJAST.map_classlib_core_op('queuepoll', $TYPE_OPS, 'queuepoll', [$RT_OBJ], $RT_OBJ, :tc); +QAST::OperationsJAST.map_classlib_core_op('cpucores', $TYPE_OPS, 'cpucores', [], $RT_INT, :tc); # asynchrony related ops QAST::OperationsJAST.map_classlib_core_op('timer', $TYPE_OPS, 'timer', [$RT_OBJ, $RT_OBJ, $RT_INT, $RT_INT, $RT_OBJ], $RT_OBJ, :tc); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java new/nqp-2017.08/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java --- old/nqp-2017.07/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java 2017-08-21 17:01:35.000000000 +0200 @@ -5493,6 +5493,10 @@ return thread; } + public static long cpucores(ThreadContext tc) { + return Runtime.getRuntime().availableProcessors(); + } + public static SixModelObject lock(SixModelObject lock, ThreadContext tc) { if (lock instanceof ReentrantMutexInstance) ((ReentrantMutexInstance)lock).lock.lock(); @@ -5624,7 +5628,6 @@ } public static SixModelObject permit(SixModelObject handle, long channel, long permits, ThreadContext tc) { - AsyncTaskInstance task = (AsyncTaskInstance) handle; // TODO Implement permit handling properly return handle; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/moar/HLL/Backend.nqp new/nqp-2017.08/src/vm/moar/HLL/Backend.nqp --- old/nqp-2017.07/src/vm/moar/HLL/Backend.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/moar/HLL/Backend.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -84,7 +84,7 @@ $filename := 'profile-' ~ nqp::time_n() ~ '.html'; } note("Writing profiler output to $filename"); - my $profile_fh := open($filename, :w); + my $profile_fh; my $want_json := nqp::eqat($filename, '.json', -5); my $want_sql := nqp::eqat($filename, '.sql', -4); @@ -350,6 +350,29 @@ nqp::unshift($data, $id_to_thing); + # First make sure the template file exists if we want html + # if it doesn't exist, just spit out json instead. + my str $template; + + if !$want_json && !$want_sql { + my $temppath := nqp::backendconfig()<prefix> ~ '/share/nqp/lib/profiler/template.html'; + $template := try slurp('src/vm/moar/profiler/template.html'); + unless $template { + $template := try slurp($temppath); + } + unless $template { + note("Could not locate profiler/template.html; should have been at $temppath; outputting sql data instead"); + $want_sql := 1; + $filename := literal_subst($filename, ".html", ".sql"); + unless nqp::eqat($filename, '.sql', -4) { + $filename := $filename ~ '.sql'; + } + note("Writing profiler output to $filename"); + } + } + + $profile_fh := open($filename, :w); + if $want_json { to_json($data); $profile_fh.print(nqp::join('', @pieces)); @@ -368,10 +391,6 @@ else { # Get profiler template, split it in half, and write those either # side of the JSON itself. - my $template := try slurp('src/vm/moar/profiler/template.html'); - unless $template { - $template := slurp(nqp::backendconfig()<prefix> ~ '/share/nqp/lib/profiler/template.html'); - } my @tpl_pieces := nqp::split('{{{PROFILER_OUTPUT}}}', $template); $profile_fh.print(@tpl_pieces[0]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/moar/ModuleLoader.nqp new/nqp-2017.08/src/vm/moar/ModuleLoader.nqp --- old/nqp-2017.07/src/vm/moar/ModuleLoader.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/moar/ModuleLoader.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -11,10 +11,10 @@ if !nqp::isnull($explicit) && nqp::defined($explicit) { nqp::push(@search_paths, $explicit); } - - # Add CWD and blib. - nqp::push(@search_paths, '.'); - nqp::push(@search_paths, 'blib'); + my %env := nqp::getenvhash(); + if nqp::existskey(%env, 'NQP_LIB') { + nqp::push(@search_paths, %env<NQP_LIB>); + } @search_paths } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/moar/QAST/QASTOperationsMAST.nqp new/nqp-2017.08/src/vm/moar/QAST/QASTOperationsMAST.nqp --- old/nqp-2017.07/src/vm/moar/QAST/QASTOperationsMAST.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/moar/QAST/QASTOperationsMAST.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -1990,6 +1990,7 @@ 'C_TYPE_LONGLONG', -5, 'C_TYPE_SIZE_T', -6, 'C_TYPE_BOOL', -7, + 'C_TYPE_ATOMIC_INT', -8, 'C_TYPE_FLOAT', -1, 'C_TYPE_DOUBLE', -2, 'C_TYPE_LONGDOUBLE', -3, @@ -2184,6 +2185,7 @@ # string opcodes QAST::MASTOperations.add_core_moarop_mapping('chars', 'chars'); +QAST::MASTOperations.add_core_moarop_mapping('codes', 'codes_s'); QAST::MASTOperations.add_core_moarop_mapping('uc', 'uc'); QAST::MASTOperations.add_core_moarop_mapping('lc', 'lc'); QAST::MASTOperations.add_core_moarop_mapping('tc', 'tc'); @@ -2204,6 +2206,7 @@ QAST::MASTOperations.add_core_moarop_mapping('ordbaseat', 'ordbaseat'); QAST::MASTOperations.add_core_moarop_mapping('indexfrom', 'index_s'); QAST::MASTOperations.add_core_moarop_mapping('indexic', 'indexic_s'); +QAST::MASTOperations.add_core_moarop_mapping('indexim', 'indexim_s'); QAST::MASTOperations.add_core_moarop_mapping('indexicim', 'indexicim_s'); QAST::MASTOperations.add_core_moarop_mapping('rindexfrom', 'rindexfrom'); QAST::MASTOperations.add_core_moarop_mapping('substr_s', 'substr_s'); @@ -2248,6 +2251,7 @@ QAST::MASTOperations.add_core_moarop_mapping('eqat', 'eqat_s'); QAST::MASTOperations.add_core_moarop_mapping('eqatic', 'eqatic_s'); +QAST::MASTOperations.add_core_moarop_mapping('eqatim', 'eqatim_s'); QAST::MASTOperations.add_core_moarop_mapping('eqaticim', 'eqaticim_s'); @@ -2281,6 +2285,7 @@ # unicode properties QAST::MASTOperations.add_core_moarop_mapping('unipropcode', 'unipropcode'); QAST::MASTOperations.add_core_moarop_mapping('unipvalcode', 'unipvalcode'); +QAST::MASTOperations.add_core_moarop_mapping('hasuniprop', 'hasuniprop'); QAST::MASTOperations.add_core_moarop_mapping('getuniname', 'getuniname'); QAST::MASTOperations.add_core_moarop_mapping('getuniprop_str', 'getuniprop_str'); QAST::MASTOperations.add_core_moarop_mapping('getuniprop_bool', 'getuniprop_bool'); @@ -2778,7 +2783,7 @@ # native call ops QAST::MASTOperations.add_core_moarop_mapping('initnativecall', 'no_op'); QAST::MASTOperations.add_core_moarop_mapping('buildnativecall', 'nativecallbuild', 0); -QAST::MASTOperations.add_core_moarop_mapping('nativecall', 'nativecallinvoke'); +QAST::MASTOperations.add_core_moarop_mapping('nativecallinvoke', 'nativecallinvoke'); QAST::MASTOperations.add_core_op('nativecall', -> $qastcomp, $op { proto decont_all(@args) { my int $i := 0; @@ -2839,6 +2844,7 @@ QAST::MASTOperations.add_core_moarop_mapping('semtryacquire', 'semtryacquire'); QAST::MASTOperations.add_core_moarop_mapping('semrelease', 'semrelease'); QAST::MASTOperations.add_core_moarop_mapping('queuepoll', 'queuepoll'); +QAST::MASTOperations.add_core_moarop_mapping('cpucores', 'cpucores'); # asynchrony related ops QAST::MASTOperations.add_core_moarop_mapping('timer', 'timer'); @@ -2856,6 +2862,18 @@ QAST::MASTOperations.add_core_moarop_mapping('spawnprocasync', 'spawnprocasync'); QAST::MASTOperations.add_core_moarop_mapping('killprocasync', 'killprocasync', 1); +# Atomic ops +QAST::MASTOperations.add_core_moarop_mapping('cas', 'cas_o', :decont(1,2)); +QAST::MASTOperations.add_core_moarop_mapping('cas_i', 'cas_i'); +QAST::MASTOperations.add_core_moarop_mapping('atomicinc_i', 'atomicinc_i'); +QAST::MASTOperations.add_core_moarop_mapping('atomicdec_i', 'atomicdec_i'); +QAST::MASTOperations.add_core_moarop_mapping('atomicadd_i', 'atomicadd_i'); +QAST::MASTOperations.add_core_moarop_mapping('atomicload', 'atomicload_o'); +QAST::MASTOperations.add_core_moarop_mapping('atomicload_i', 'atomicload_i'); +QAST::MASTOperations.add_core_moarop_mapping('atomicstore', 'atomicstore_o', 1, :decont(1)); +QAST::MASTOperations.add_core_moarop_mapping('atomicstore_i', 'atomicstore_i', 1); +QAST::MASTOperations.add_core_moarop_mapping('barrierfull', 'barrierfull'); + # MoarVM-specific compilation ops QAST::MASTOperations.add_core_moarop_mapping('masttofile', 'masttofile', 2); QAST::MASTOperations.add_core_moarop_mapping('masttocu', 'masttocu'); @@ -2876,6 +2894,9 @@ # MoarVM-specific GC ops QAST::MASTOperations.add_core_moarop_mapping('force_gc', 'force_gc'); +# MoarVM-specific coverage ops +QAST::MASTOperations.add_core_moarop_mapping('coveragecontrol', 'coveragecontrol'); + sub resolve_condition_op($kind, $negated) { return $negated ?? $kind == $MVM_reg_int64 ?? 'unless_i' !! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/src/vm/moar/QAST/QASTRegexCompilerMAST.nqp new/nqp-2017.08/src/vm/moar/QAST/QASTRegexCompilerMAST.nqp --- old/nqp-2017.07/src/vm/moar/QAST/QASTRegexCompilerMAST.nqp 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/src/vm/moar/QAST/QASTRegexCompilerMAST.nqp 2017-08-21 17:01:35.000000000 +0200 @@ -114,7 +114,6 @@ @!rxjumps := nqp::list($donelabel); my $shared := $!regalloc.fresh_o(); - my $sharedclass := $!regalloc.fresh_o(); my $i19 := $!regalloc.fresh_i(); # yes, I know, inheriting the name from ancestor method my $i0 := $!regalloc.fresh_i(); @@ -131,6 +130,7 @@ call($method, [ $Arg::obj ], :result($cur), $self ) ]; + my $sharedclass; my int $has_cursor_type := $node.has_cursor_type(); if $has_cursor_type { $!cursor_type := $node.cursor_type(); @@ -142,8 +142,14 @@ ival(nqp::hintfor($!cursor_type, '$!shared'))) ]); $!regalloc.release_register($wval.result_reg, $MVM_reg_obj); + + my $shared_wval := $!qastcomp.as_mast( + QAST::WVal.new( :value($!cursor_type.'!shared_type'()) )); + merge_ins(@ins, $shared_wval.instructions); + $sharedclass := $shared_wval.result_reg; } else { + $sharedclass := $!regalloc.fresh_o(); merge_ins(@ins, [ op('findmeth', $shared, $self, sval('!shared')), call($shared, [ $Arg::obj ], :result($shared), $self ), @@ -987,9 +993,10 @@ nqp::push(@ins, op('eq_i', $ireg0, %!reg<pos>, %!reg<negone>)); $!regalloc.release_register($lit, $MVM_reg_str); } - elsif $node.list && ($node.subtype eq 'ignorecase'|| $node.subtype eq 'ignorecase+ignoremark') { + elsif $node.list && ($node.subtype eq 'ignorecase' || $node.subtype eq 'ignorecase+ignoremark' || $node.subtype eq 'ignoremark') { my $lit := $!regalloc.fresh_s(); - my $op := $node.subtype eq 'ignorecase' ?? 'indexic_s' !! 'indexicim_s'; + my $op := $node.subtype eq 'ignorecase' ?? 'indexic_s' !! + $node.subtype eq 'ignoremark' ?? 'indexim_s' !! 'indexicim_s'; nqp::push(@ins, op('const_s', $lit, sval($node[0]))); nqp::push(@ins, op($op, %!reg<pos>, %!reg<tgt>, $lit, %!reg<pos>)); nqp::push(@ins, op('eq_i', $ireg0, %!reg<pos>, %!reg<negone>)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/hll/06-sprintf.t new/nqp-2017.08/t/hll/06-sprintf.t --- old/nqp-2017.07/t/hll/06-sprintf.t 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/t/hll/06-sprintf.t 2017-08-21 17:01:35.000000000 +0200 @@ -22,30 +22,28 @@ } } -plan(284); +plan(286); is(nqp::sprintf('Walter Bishop', []), 'Walter Bishop', 'no directives' ); is(nqp::sprintf('Peter %s', ['Bishop']), 'Peter Bishop', 'one %s directive' ); is(nqp::sprintf('%s %s', ['William', 'Bell']), 'William Bell', 'two %s directives' ); -dies_ok({ nqp::sprintf('%s %s', ['Dr.', 'William', 'Bell']) }, 'arguments > directives' ); -is($die_message, 'Your printf-style directives specify 2 arguments, but 3 arguments were supplied', - 'arguments > directives error message' ); - -dies_ok({ nqp::sprintf('%s %s %s', ['Olivia', 'Dunham']) }, 'directives > arguments' ); -is($die_message, 'Your printf-style directives specify 3 arguments, but 2 arguments were supplied', - 'directives > arguments error message' ); - -dies_ok({ nqp::sprintf('%s %s', []) }, 'directives > 0 arguments' ); -is($die_message, 'Your printf-style directives specify 2 arguments, but no argument was supplied', - 'directives > 0 arguments error message' ); +dies-ok({ nqp::sprintf('%s %s', ['Dr.', 'William', 'Bell']) }, 'arguments > directives', + :message('Your printf-style directives specify 2 arguments, but 3 arguments were supplied')); + +dies-ok({ nqp::sprintf('%s %s', ['Dr.', 'William', 'Bell']) }, 'arguments > directives', + :message('Your printf-style directives specify 2 arguments, but 3 arguments were supplied')); + +dies-ok({ nqp::sprintf('%s %s %s', ['Olivia', 'Dunham']) }, 'directives > arguments', + :message('Your printf-style directives specify 3 arguments, but 2 arguments were supplied')); + +dies-ok({ nqp::sprintf('%s %s', []) }, 'directives > 0 arguments', + :message('Your printf-style directives specify 2 arguments, but no argument was supplied')); is(nqp::sprintf('%% %% %%', []), '% % %', '%% escape' ); -dies_ok({ nqp::sprintf('%a', 'Science') }, 'unknown directive' ); -is($die_message, "'a' is not valid in sprintf format sequence '%a'", - 'unknown directive error message' ); +dies-ok({ nqp::sprintf('%a', 'Science') }, 'unknown directive', :message("'a' is not valid in sprintf format sequence '%a'")); my class SprintfHandler { method mine($x) { try nqp::reprname($x) eq "P6bigint" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/moar/01-continuations.t new/nqp-2017.08/t/moar/01-continuations.t --- old/nqp-2017.07/t/moar/01-continuations.t 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/t/moar/01-continuations.t 2017-08-21 17:01:35.000000000 +0200 @@ -2,7 +2,7 @@ # continuations. -plan(19); +plan(24); { # unique objects @@ -130,6 +130,31 @@ ok($B_in_invoke == 20, 'invoke also sees the invocation context'); } +{ + my $log := ''; + + my $next; + nqp::continuationreset(nqp::null(), { + $log := $log ~ 1; + nqp::continuationcontrol(0, nqp::null(), -> $cont { $next := $cont }); + $log := $log ~ 2; + nqp::continuationcontrol(0, nqp::null(), -> $cont { $next := $cont }); + $log := $log ~ 3; + nqp::continuationcontrol(0, nqp::null(), -> $cont { $next := $cont }); + $log := $log ~ 4; + 777; + }); + + is($log, '1', 'passing a continuation to nqp::continuationreset 1/4'); + nqp::continuationreset(nqp::null(), $next); + is($log, '12', 'passing a continuation to nqp::continuationreset 2/4'); + nqp::continuationreset(nqp::null(), $next); + is($log, '123', 'passing a continuation to nqp::continuationreset 3/4'); + my $ret := nqp::continuationreset(nqp::null(), $next); + is($log, '1234', 'passing a continuation to nqp::continuationreset 4/4'); + is($ret, 777, 'passing a continuation to nqp::continuationreset - correct return value'); +} + # gather/take example { my $SENTINEL := []; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/moar/10-eqatim.t new/nqp-2017.08/t/moar/10-eqatim.t --- old/nqp-2017.07/t/moar/10-eqatim.t 1970-01-01 01:00:00.000000000 +0100 +++ new/nqp-2017.08/t/moar/10-eqatim.t 2017-08-21 17:01:35.000000000 +0200 @@ -0,0 +1,44 @@ +#!/usr/bin/env nqp +## TODO XXX need MORE tests to check failures, not just succeses +plan(110); +ok(!nqp::eqatim('b', 'bb', 0), "MVM index/equatic bug"); +ok(!nqp::eqatim('á', '`a`a', 0)); +ok(!nqp::eqatim('á', 'aassssssss', 0)); +ok(!nqp::eqatim('a', 'aasAsssss', 0)); +ok( nqp::eqatim('abcdef', 'bcd', 1)); +# With ligatures that expand under casefolding +ok( nqp::eqatim('aaaaa', 'a', 2) ); +ok( nqp::eqatim('aaáaa', 'a', 2) ); +ok( nqp::eqatim('aaaaa', 'á', 2) ); +ok( nqp::eqatim('aaaaaz', 'z', 5) ); +ok( nqp::eqatim('aaazaa', 'z', 3) ); +ok( nqp::eqatim('aaaa', 'á', 3) ); +ok( nqp::eqatim('aaaa', 'á', 0) ); +ok( nqp::eqatim('á', 'a', 0) ); +ok( nqp::eqatim('a', 'á', 0) ); +ok( nqp::eqatim('aaaaa', 'á', 4) ); +ok( nqp::eqatim('AAAAa', 'á', 4) ); +test-it('a', 'á', 20, 1); +test-it('a', 'á', 20, 0); +test-it('á', 'a', 20, 1); +test-it('á', 'a', 20, 0); +# Without codepoint which expand when casefolded +for (0,1,2,3,4,5,6) -> $val { + my str $letter := nqp::chr($val + nqp::ord('A')); + my str $haystack := 'ABCDEFG'; + ok( nqp::eqatim($haystack, $letter, $val), "nqp::eqatim('$haystack', '$letter', $val)"); + $haystack := nqp::lc($haystack); + ok( !nqp::eqatim($haystack, $letter, $val), "!nqp::eqatim('$haystack', '$letter', $val)"); + +} + +sub test-it ($needle, $text, $max, $opt) { + my int $i := 0; + while ($i < $max) { + my str $str := nqp::x('a', $max - $i); + $str := $str ~ $text; + $str := $str ~ nqp::x('b', $i) if $opt; + ok( nqp::eqatim($str, $needle, $max - $i), "eqatim haystack = '$str' needle = '$needle' $i"); + $i++ + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/nqp/102-multidim.t new/nqp-2017.08/t/nqp/102-multidim.t --- old/nqp-2017.07/t/nqp/102-multidim.t 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/t/nqp/102-multidim.t 2017-08-21 17:01:35.000000000 +0200 @@ -13,15 +13,6 @@ } ok($ok, "$description - correct dimensions"); } -sub dies-ok($code, $description, :$message) { - my $died := 0; - my $got-message := ''; - try { $code(); CATCH { $died := 1; $got-message := nqp::getmessage($_); } } - ok($died, $description); - if $message { - ok($got-message ~~ /$message/, "Exception message contained '$message'"); - } -} # Normal dynamic array has a single element, irrespective of type or contents. ok(nqp::numdimensions([]) == 1, 'numdimensions on normal array (1)'); @@ -292,11 +283,11 @@ { my $test_1d := nqp::create($array_type_1d); nqp::setdimensions($test_1d, nqp::list_i(3)); - dies-ok({ nqp::pop($test_1d) }, :message('pop'), 'popping dies'); - dies-ok({ nqp::push($test_1d, 1) }, :message('push'), 'pushing dies'); - dies-ok({ nqp::shift($test_1d) }, :message('shift'), 'shifting dies'); - dies-ok({ nqp::unshift($test_1d, 1) }, :message('unshift'), 'unshifting dies'); - dies-ok({ nqp::splice($test_1d, [], 0, 3) }, :message('splice'), 'splicing dies'); + dies-ok({ nqp::pop($test_1d) }, :message(/pop/), 'popping dies'); + dies-ok({ nqp::push($test_1d, 1) }, :message(/push/), 'pushing dies'); + dies-ok({ nqp::shift($test_1d) }, :message(/shift/), 'shifting dies'); + dies-ok({ nqp::unshift($test_1d, 1) }, :message(/unshift/), 'unshifting dies'); + dies-ok({ nqp::splice($test_1d, [], 0, 3) }, :message(/splice/), 'splicing dies'); } # can use normal array access ops on a 1D multi-dimensioned array (this makes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/nqp/109-coercions.t new/nqp-2017.08/t/nqp/109-coercions.t --- old/nqp-2017.07/t/nqp/109-coercions.t 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/t/nqp/109-coercions.t 2017-08-21 17:01:35.000000000 +0200 @@ -1,4 +1,4 @@ -plan(8); +plan(10); my sub isnan($n) { nqp::isnanorinf($n) && $n != nqp::inf() && $n != nqp::neginf(); @@ -12,3 +12,6 @@ is(~nqp::nan(), 'NaN', 'stringifing nqp::nan'); is(~nqp::inf(), 'Inf', 'stringifing nqp::inf'); is(~nqp::neginf(), '-Inf', 'stringifing nqp::neginf'); + +is(~(1/nqp::neginf()), '-0', 'stringifing -0'); +is(~(1/nqp::inf()), '0', 'stringifing -0'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/nqp/111-spawnprocasync.t new/nqp-2017.08/t/nqp/111-spawnprocasync.t --- old/nqp-2017.07/t/nqp/111-spawnprocasync.t 1970-01-01 01:00:00.000000000 +0100 +++ new/nqp-2017.08/t/nqp/111-spawnprocasync.t 2017-08-21 17:01:35.000000000 +0200 @@ -0,0 +1,71 @@ +plan(2); + +my $tmp-file := "tmp"; +spew($tmp-file, "\n"); +my $is-windows := nqp::stat($tmp-file, nqp::const::STAT_FILESIZE) == 2; +nqp::unlink($tmp-file); + +my $args := $is-windows ?? nqp::list(nqp::getenvhash()<CompSpec>, '/c', 'echo aardvarks') !! nqp::list('/bin/sh', '-c', 'echo aardvarks'); + +my sub create_buf($type) { + my $buf := nqp::newtype(nqp::null(), 'VMArray'); + nqp::composetype($buf, nqp::hash('array', nqp::hash('type', $type))); + nqp::setmethcache($buf, nqp::hash('new', method () {nqp::create($buf)})); + $buf; +} + +my $done := 0; + +my class Queue is repr('ConcBlockingQueue') { } +my $queue := nqp::create(Queue); + +my @stdout_bytes; +my $read_all := 0; + +my $called_ready := 0; + + +my $config := nqp::hash( + 'done', -> $status { + $done := $done + 1; + }, + 'ready', -> $stdin?, $stdout? { + $called_ready := $called_ready + 1; + }, + 'stdout_bytes', -> $seq, $data, $err { + if nqp::isconcrete($data) { + @stdout_bytes[$seq] := $data; + } + else { + $read_all := 1; + } + }, + 'buf_type', create_buf(uint8) +); + + +my $task := nqp::spawnprocasync($queue, $args, nqp::cwd(), nqp::getenvhash(), $config); + +nqp::permit($task, 1, -1); + +while !$done || !$read_all { + if nqp::shift($queue) -> $task { + if nqp::list($task) { + my $code := nqp::shift($task); + $code(|$task); + } else { + $task(); + } + } +} + +my class VMDecoder is repr('Decoder') {} +my $dec := nqp::create(VMDecoder); +nqp::decoderconfigure($dec, 'utf8', nqp::hash()); + +is($called_ready, 1, 'called the ready callback once'); + +for @stdout_bytes -> $bytes { + nqp::decoderaddbytes($dec, $bytes); +} +ok(nqp::decodertakeallchars($dec) ~~ /^aardvarks\s*$/, 'got the correct output'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/t/qast/01-qast.t new/nqp-2017.08/t/qast/01-qast.t --- old/nqp-2017.07/t/qast/01-qast.t 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/t/qast/01-qast.t 2017-08-21 17:01:35.000000000 +0200 @@ -1,6 +1,6 @@ use QAST; -plan(147); +plan(149); # Following a test infrastructure. sub compile_qast($qast) { @@ -2373,3 +2373,51 @@ is($called, '1', 'called the lexical_handler_not_found_error handler - with throwpayloadlex'); is($got_cat, nqp::const::CONTROL_RETURN, '...got right category of handler'); } + +{ + my $no_custom_args := QAST::Block.new( + QAST::Var.new( :name('arg1'), :scope('lexical'), :decl('param')), + QAST::SVal.new( :value('survived') ) + ); + + my $custom_args := QAST::Block.new( + QAST::SVal.new( :value('survived') ) + ); + + $custom_args.custom_args(1); + + is_qast( + QAST::CompUnit.new( + QAST::Block.new( + QAST::Op.new( + :op('handle'), + QAST::Op.new( + :op('call'), + QAST::Op.new(:op<takeclosure>, # needed for JVM + $no_custom_args, + ), + ), + 'CATCH', QAST::SVal.new( :value('died') ) + ) + ) + ), + 'died', 'wrong number of arguments dies without custom_args'); + + is_qast( + QAST::CompUnit.new( + QAST::Block.new( + QAST::Op.new( + :op('handle'), + QAST::Op.new( + :op('call'), + QAST::Op.new(:op<takeclosure>, # needed for JVM + $custom_args, + ), + QAST::SVal.new( :value('arg') ) + ), + 'CATCH', QAST::SVal.new( :value('died') ) + ) + ) + ), + 'survived', 'wrong number of arguments lives with custom_args'); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nqp-2017.07/tools/build/MOAR_REVISION new/nqp-2017.08/tools/build/MOAR_REVISION --- old/nqp-2017.07/tools/build/MOAR_REVISION 2017-07-15 22:38:41.000000000 +0200 +++ new/nqp-2017.08/tools/build/MOAR_REVISION 2017-08-21 17:03:13.000000000 +0200 @@ -1 +1 @@ -2017.07 +2017.08.1
