...
 
Commits (5)
......@@ -211,6 +211,13 @@ MAIN: {
sorry($options{'ignore-errors'}, "You don't have node.js. Please install node.js.");
}
my $node_version = `node --version`;
my ($major, $minor, $path) = $node_version =~ /v(\d+)\.(\d+)\.(\d+)/;
unless ($major > 10 || $major == 10 && $minor >= 10) {
chomp($node_version);
sorry($options{'ignore-errors'}, "Need at least node.js v10.10.0 (got $node_version)");
}
fill_template_file(
'gen/js/Makefile-JS.in',
$MAKEFILE,
......
......@@ -220,11 +220,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Portions Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
......@@ -105,7 +105,7 @@ scratch.
=head2 JavaScript backend
The best thing before playing with it/hacking on it is to contact pmurias via IRC at #perl6 on irc.freenode.org.
It's recommended that you use node 7.10.0 as it's the version of node.js the JavaScript backend is developed with.
We depend on node.js at least 10.10.0
Building the JavaScript backend currently requires building the moar backend:
......
nqp (2018.10+dfsg-1) unstable; urgency=medium
* New upstream version 2018.10+dfsg
* control: update moarvm-dev dep versions
* fix debian/patches/skip-dubious-tests
-- Robert Lemmen <robertle@semistable.com> Thu, 15 Nov 2018 18:44:31 +0100
nqp (2018.09+dfsg-1) unstable; urgency=medium
* New upstream version 2018.09+dfsg
......
......@@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 9),
libjs-jquery,
libreadline-dev,
libtommath-dev (>= 0.42.0-1.2),
moarvm-dev (>= 2018.09),
moarvm-dev (>= 2018.10),
perl
Standards-Version: 4.1.4
Vcs-Browser: https://salsa.debian.org/perl6-team/nqp
......
......@@ -6,16 +6,13 @@ Forwarded: no
Author: dod
--- a/t/concurrency/01-thread.t
+++ b/t/concurrency/01-thread.t
@@ -1,7 +1,7 @@
#! nqp
@@ -1,4 +1,4 @@
-plan(24);
+plan(22);
# 2 tests
{
@@ -125,7 +125,7 @@
@@ -125,7 +125,7 @@ plan(24);
# Sibling child threads case for threadyield()
# This test intentionally does not use proper synchronization primitives,
# so that threadyield can be tested independently of locks/condvars/etc.
......
{
"version": "0.4.0",
"version": "0.15.0",
"name": "nqp-js-on-js",
"bin": {
"nqp-js-on-js": "nqp-bootstrapped.js"
......@@ -14,6 +14,6 @@
}
],
"dependencies": {
"nqp-runtime": "0.2.0"
"nqp-runtime": "0.15.0"
}
}
......@@ -19,7 +19,7 @@ class HLL::Actions {
nqp::chr($ints.made);
}
}
method CTXSAVE() {
QAST::Stmts.new(
QAST::Op.new(
......@@ -45,7 +45,7 @@ class HLL::Actions {
QAST::Var.new( :name('ctxsave'), :scope('local')
)))))
}
method SET_BLOCK_OUTER_CTX($block) {
my $outer_ctx := %*COMPILING<%?OPTIONS><outer_ctx>;
if nqp::defined($outer_ctx) {
......
......@@ -264,8 +264,12 @@ class HLL::Compiler does HLL::Backend::Default {
my $*LIBPATH;
if %adverbs<libpath> {
$*LIBPATH := nqp::split('|||', %adverbs<libpath>);
nqp::getcomp('JavaScript').eval('(function(paths) {nqp.libpath(paths.array)})')($*LIBPATH);
my $split := nqp::split('|||', %adverbs<libpath>);
$*LIBPATH := nqp::list_s();
for $split -> $str {
nqp::push_s($*LIBPATH, $str);
}
nqp::getcomp('JavaScript').eval('return (function(paths) {nqp.libpath(paths)})')($*LIBPATH);
}
my $*EXECNAME;
......
class QAST::CompUnit is QAST::Node does QAST::Children {
# The serialization context for the compilation unit.
has $!sc;
# Code reference block list for the serialization context.
has $!code_ref_blocks;
# Are we in compilation mode?
has int $!compilation_mode;
# Tasks we should run prior to deserialization (or, in the non-precompiled
# case, just before everything else in this compilation unit).
has @!pre_deserialize;
......@@ -15,17 +15,17 @@ class QAST::CompUnit is QAST::Node does QAST::Children {
# Tasks we should run after deserialization (or, in the non-precompiled
# case, right after the pre-deserialize tasks).
has @!post_deserialize;
# Call to the repossession conflict resolution mechanism, to be invoked
# on deserialization.
has $!repo_conflict_resolver;
# The HLL name.
has $!hll;
# What to run at the point the compilation unit is loaded.
has $!load;
# What to run if this is the main entry point.
has $!main;
......@@ -38,12 +38,12 @@ class QAST::CompUnit is QAST::Node does QAST::Children {
$node.set(%options) if %options;
$node
}
method sc($value = NO_VALUE) { $!sc := $value unless $value =:= NO_VALUE; $!sc }
method hll($value = NO_VALUE) { $!hll := $value unless $value =:= NO_VALUE; $!hll }
method load($value = NO_VALUE) { $!load := $value unless $value =:= NO_VALUE; $!load }
method main($value = NO_VALUE) { $!main := $value unless $value =:= NO_VALUE; $!main }
method compilation_mode($value = NO_VALUE) {
$!compilation_mode := $value unless $value =:= NO_VALUE; $!compilation_mode
}
......
# Composed or mixed in to any node that also has a compile-time known value.
role QAST::CompileTimeValue {
has $!compile_time_value;
method has_compile_time_value() {
1
}
method compile_time_value() {
$!compile_time_value
}
method set_compile_time_value($value) {
$!compile_time_value := $value
}
......
......@@ -20,7 +20,7 @@ class QAST::Regex is QAST::Node does QAST::Children {
has int $!negate;
has int $!min;
has int $!max;
method new(str :$rxtype, str :$subtype, *@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr_i($node, QAST::Node, '$!flags', 0);
......@@ -38,7 +38,7 @@ class QAST::Regex is QAST::Node does QAST::Children {
}
method subtype($value = NO_VALUE) {
$!subtype := $value unless $value =:= NO_VALUE;
!nqp::isnull_s($!subtype) ?? $!subtype !! ""
!nqp::isnull_s($!subtype) ?? $!subtype !! ""
}
method backtrack($value = NO_VALUE) {
$!backtrack := $value unless $value =:= NO_VALUE;
......@@ -47,15 +47,14 @@ class QAST::Regex is QAST::Node does QAST::Children {
method negate($value = NO_VALUE) { $!negate := $value unless $value =:= NO_VALUE; $!negate }
method min($value = NO_VALUE) { $!min := $value unless $value =:= NO_VALUE; $!min }
method max($value = NO_VALUE) { $!max := $value unless $value =:= NO_VALUE; $!max }
method dump_extra_node_info() {
":rxtype($!rxtype)" ~ (!nqp::isnull_s($!subtype) ?? " :subtype($!subtype)" !! "") ~ ($!negate ?? ' (negated)' !! '') ~ (nqp::defined($!name) ?? " :name($!name)" !! '')
}
method has_cursor_type() { 0 }
method cursor_type($type) {
self.HOW.mixin(self, QAST::RegexCursorType);
self.cursor_type($type);
}
}
......@@ -11,7 +11,7 @@ class QAST::SVal is QAST::Node {
}
method value($value = NO_VALUE) { $!value := $value unless $value =:= NO_VALUE; $!value }
method count_inline_placeholder_usages(@usages) { }
method substitute_inline_placeholders(@fillers) {
......
......@@ -3,7 +3,7 @@ my class NO_VALUE { }
role QAST::SpecialArg {
has $!named;
has int $!flat;
method named($value = NO_VALUE) {
$!named := $value unless $value =:= NO_VALUE;
$!named
......
class QAST::VM is QAST::Node does QAST::Children {
has %!alternatives;
method new(*@children, *%alternatives) {
my $obj := nqp::create(self);
nqp::bindattr_i($obj, QAST::Node, '$!flags', 0);
......@@ -8,18 +8,18 @@ class QAST::VM is QAST::Node does QAST::Children {
nqp::bindattr($obj, QAST::VM, '%!alternatives', %alternatives);
$obj
}
method supports($option) {
method supports($option) {
nqp::existskey(%!alternatives, $option)
}
method alternative($option) {
nqp::atkey(%!alternatives, $option)
}
method dump_children(int $indent, @onto) {
for sorted_keys(%!alternatives) -> $k {
my $v := %!alternatives{$k};
my $v := %!alternatives{$k};
nqp::push(@onto, nqp::x(' ', $indent));
nqp::push(@onto, '[');
nqp::push(@onto, $k);
......
class QAST::VarWithFallback is QAST::Var {
has $!fallback;
method fallback($value = NO_VALUE) { $!fallback := $value unless $value =:= NO_VALUE; $!fallback }
method fallback($value = NO_VALUE) {
$!fallback := $value unless $value =:= NO_VALUE;
$!fallback
}
method extra_children() {
$!fallback ?? ['fallback', [$!fallback]] !! [];
......
......@@ -24,7 +24,7 @@ class QAST::WVal is QAST::Node does QAST::CompileTimeValue {
}
method dump_extra_node_info() {
CATCH { return "?" }
CATCH { return "?" }
my $v := self.compile_time_value();
my $info := $v.HOW.name($v);
if self.ann('past_block') -> $qast {
......
class QRegex::P5Regex::Compiler is HLL::Compiler {
}
class QRegex::P5Regex::Compiler is HLL::Compiler { }
my $p5regex := QRegex::P5Regex::Compiler.new();
$p5regex.language('QRegex::P5Regex');
......
class QRegex::P6Regex::Compiler is HLL::Compiler {
}
class QRegex::P6Regex::Compiler is HLL::Compiler { }
my $p6regex := QRegex::P6Regex::Compiler.new();
$p6regex.language('QRegex::P6Regex');
......
......@@ -12,7 +12,7 @@ my class NQPCapture {
@!array := nqp::list();
%!hash := nqp::hash();
}
method list() { @!array }
method hash() { %!hash }
......
......@@ -18,13 +18,23 @@ my module EXPORTHOW {
nqp::scwbenable();
}
#?if js
my native int is repr('P6int') is nativesize(32) { }
#?endif
#?if !js
my native int is repr('P6int') { }
#?endif
my native int64 is repr('P6int') is nativesize(64) { }
my native int32 is repr('P6int') is nativesize(32) { }
my native int16 is repr('P6int') is nativesize(16) { }
my native int8 is repr('P6int') is nativesize( 8) { }
#?if js
my native uint is repr('P6int') is nativesize(32) is unsigned { }
#?endif
#?if !js
my native uint is repr('P6int') is unsigned { }
#?endif
my native uint64 is repr('P6int') is nativesize(64) is unsigned { }
my native uint32 is repr('P6int') is nativesize(32) is unsigned { }
my native uint16 is repr('P6int') is nativesize(16) is unsigned { }
......
......@@ -6,18 +6,18 @@ my knowhow Archetypes {
# Can this serve as a nominal type? Implies memoizability
# amongst other things.
has $!nominal;
# If it's not nominal, does it know how to provide a nominal
# type part of itself?
has $!nominalizable;
# Can this be inherited from?
has $!inheritable;
# If it's not inheritable, does it know how to produce something
# that is?
has $!inheritalizable;
# Can this be composed (either with flattening composition, or used
# as a mixin)?
has $!composable;
......@@ -25,7 +25,7 @@ my knowhow Archetypes {
# If it's not composable, does it know how to produce something
# that is?
has $!composalizable;
# Is it generic, in the sense of "we don't know what type this is
# yet"? Note that a parametric type would not be generic - even if
# it has missing parts, it defines a type. A type variable is generic,
......@@ -33,27 +33,27 @@ my knowhow Archetypes {
# delayed) reification. In some contexts, an unresolved generic is
# fatal.
has $!generic;
# Is it a parametric type - that is, it has missing bits that need
# to be filled out before it can be used? Unlike generic, something
# that is parametric does define a type - though we may need the gaps
# filled it before it's useful in some way.
has $!parametric;
method new(:$nominal, :$inheritable, :$composable, :$parametric) {
my $arch := nqp::create(self);
$arch.BUILD(:nominal($nominal), :inheritable($inheritable),
:composable($composable), :parametric($parametric));
$arch
}
method BUILD(:$nominal, :$inheritable, :$composable, :$parametric) {
$!nominal := $nominal;
$!inheritable := $inheritable;
$!composable := $composable;
$!parametric := $parametric;
}
method nominal() { nqp::ifnull($!nominal, 0) }
method nominalizable() { nqp::ifnull($!nominalizable, 0) }
method inheritable() { nqp::ifnull($!inheritable, 0) }
......
......@@ -32,11 +32,11 @@ knowhow NQPAttribute {
method type() {
$!has_type ?? $!type !! nqp::null()
}
method has_accessor() {
0
}
method build_closure() {
0
}
......@@ -44,23 +44,23 @@ knowhow NQPAttribute {
method box_target() {
!nqp::isnull($!box_target) && $!box_target ?? 1 !! 0
}
method auto_viv_container() {
$!has_default ?? $!default !! nqp::null()
}
method set_positional_delegate($value) {
$!positional_delegate := $value;
}
method set_associative_delegate($value) {
$!associative_delegate := $value;
}
method positional_delegate() {
!nqp::isnull($!positional_delegate) && $!positional_delegate ?? 1 !! 0
}
method associative_delegate() {
!nqp::isnull($!associative_delegate) && $!associative_delegate ?? 1 !! 0
}
......
......@@ -27,7 +27,7 @@ knowhow NQPClassHOW {
# Full list of roles that we do.
has @!done;
# Cached values, which are thrown away if the class changes. We don't ever
# mutate the %!caches hash, but instead clone/mutate/replace; additions
# are rare compared to lookups, and this beats locking.
......@@ -38,11 +38,11 @@ knowhow NQPClassHOW {
has $!trace;
has $!trace_depth;
has @!trace_exclude;
# Build plan.
has @!BUILDALLPLAN;
has @!BUILDPLAN;
my $archetypes := Archetypes.new( :nominal(1), :inheritable(1) );
method archetypes() {
$archetypes
......@@ -136,11 +136,11 @@ knowhow NQPClassHOW {
}
nqp::push(@!parents, $parent);
}
method set_default_parent($obj, $parent) {
$!default_parent := $parent;
}
# Changes the object's parent. Conditions: it has exactly one parent, and that
# parent has no attributes, and nor does the new one.
method reparent($obj, $new_parent) {
......@@ -212,23 +212,23 @@ knowhow NQPClassHOW {
# Create BUILDPLAN.
self.create_BUILDPLAN($obj);
# Compose the representation.
unless $!composed {
self.compose_repr($obj);
}
# Mark as composed.
$!composed := 1;
$obj
}
method compose_repr($obj) {
# Use any attribute information to produce attribute protocol
# data. The protocol consists of an array...
my @repr_info;
# ...which contains an array per MRO entry...
for @!mro -> $type_obj {
my @type_info;
......@@ -236,7 +236,7 @@ knowhow NQPClassHOW {
# ...which in turn contains the current type in the MRO...
nqp::push(@type_info, $type_obj);
# ...then an array of hashes per attribute...
my @attrs;
nqp::push(@type_info, @attrs);
......@@ -259,11 +259,11 @@ knowhow NQPClassHOW {
}
nqp::push(@attrs, %attr_info);
}
# ...followed by a list of immediate parents.
nqp::push(@type_info, $type_obj.HOW.parents($type_obj, :local));
}
# Compose the representation using it.
my $info := nqp::hash();
$info<attribute> := @repr_info;
......@@ -429,7 +429,7 @@ knowhow NQPClassHOW {
nqp::settypecache($obj, @tc)
}
sub reverse(@in) {
my @out;
for @in { nqp::unshift(@out, $_) }
......@@ -478,7 +478,7 @@ knowhow NQPClassHOW {
# First, we'll create the build plan for just this class.
my @plan;
my @attrs := $obj.HOW.attributes($obj, :local(1));
# Does it have its own BUILD?
my $build := $obj.HOW.method_table($obj)<BUILD>;
if nqp::defined($build) {
......@@ -497,7 +497,7 @@ knowhow NQPClassHOW {
nqp::push(@plan, [$sigop, $obj, $attr_name, $name]);
}
}
# Check if there's any default values to put in place.
for @attrs {
if nqp::can($_, 'build') {
......@@ -507,10 +507,10 @@ knowhow NQPClassHOW {
}
}
}
# Install plan for this class.
@!BUILDPLAN := @plan;
# Now create the full plan by getting the MRO, and working from
# least derived to most derived, copying the plans.
my @all_plan;
......@@ -525,11 +525,11 @@ knowhow NQPClassHOW {
}
@!BUILDALLPLAN := @all_plan;
}
method BUILDPLAN($obj) {
@!BUILDPLAN
}
method BUILDALLPLAN($obj) {
@!BUILDALLPLAN
}
......@@ -541,7 +541,7 @@ knowhow NQPClassHOW {
method parents($obj, :$local = 0) {
$local ?? @!parents !! @!mro
}
method mro($obj) {
@!mro
}
......@@ -672,7 +672,7 @@ knowhow NQPClassHOW {
?? %!caches{$key}
!! self.cache_add($obj, $key, $value_generator())
}
method flush_cache($obj) {
nqp::scwbdisable();
%!caches := {} unless nqp::isnull(%!caches);
......@@ -696,7 +696,7 @@ knowhow NQPClassHOW {
##
## Mix-ins
##
##
has @!mixin_cache;
method set_is_mixin($obj) { $!is_mixin := 1 }
method is_mixin($obj) { $!is_mixin }
......@@ -714,14 +714,14 @@ knowhow NQPClassHOW {
}
}
}
# Create and cache mixin-type if needed.
unless $found {
# Flush its cache as promised, otherwise outdated NFAs will stick around.
self.flush_cache($obj) if !nqp::isnull($obj) || self.is_mixin($obj);
# Work out a type name for the post-mixed-in role.
my $new_name := self.name($obj) ~ '+{' ~ $role.HOW.name($role) ~ '}';
# Create new type, derive it from ourself and then add
# all the roles we're mixing it.
$new_type := self.new_type(:name($new_name), :repr($obj.REPR));
......@@ -729,7 +729,7 @@ knowhow NQPClassHOW {
$new_type.HOW.add_parent($new_type, $obj.WHAT);
$new_type.HOW.add_role($new_type, $role);
$new_type.HOW.compose($new_type);
# Store the type.
nqp::scwbdisable();
@!mixin_cache := [] if nqp::isnull(@!mixin_cache);
......@@ -738,14 +738,14 @@ knowhow NQPClassHOW {
nqp::scwbenable();
1;
}
# If the original object was concrete, change its type by calling a
# low level op. Otherwise, we just return the new type object
nqp::isconcrete($obj) ??
nqp::rebless($obj, $new_type) !!
$new_type
}
##
## Tracing
##
......
......@@ -157,7 +157,7 @@ knowhow NQPConcreteRoleHOW {
method roles($obj) {
@!roles
}
method role_typecheck_list($obj) {
@!role_typecheck_list
}
......
knowhow NQPCurriedRoleHOW {
has $!curried_role;
has @!pos_args;
my $archetypes := Archetypes.new( :nominal(1), :composable(1), :parametric(1) );
method archetypes() {
$archetypes
}
method new(:$curried_role!, :@pos_args!) {
my $obj := nqp::create(self);
$obj.BUILD(:$curried_role, :@pos_args);
......@@ -17,16 +17,16 @@ knowhow NQPCurriedRoleHOW {
$!curried_role := $curried_role;
@!pos_args := @pos_args;
}
method new_type($curried_role!, *@pos_args) {
my $meta := self.new(:curried_role($curried_role), :pos_args(@pos_args));
nqp::newtype($meta, 'Uninstantiable');
}
method specialize($obj, $class_arg) {
$!curried_role.HOW.specialize($!curried_role, $class_arg, |@!pos_args);
}
method name($obj) {
$!curried_role.HOW.name($!curried_role)
}
......@@ -35,7 +35,7 @@ knowhow NQPCurriedRoleHOW {
my @parts := nqp::split('::', self.name($obj) // '');
@parts ?? @parts[nqp::elems(@parts) - 1] !! '<anon>'
}
method curried_role($obj) {
$!curried_role
}
......
knowhow NQPModuleHOW {
has $!name;
has $!composed;
my $archetypes := Archetypes.new( );
method archetypes() {
$archetypes
......@@ -44,7 +44,7 @@ knowhow NQPModuleHOW {
nqp::setmethcacheauth($obj, 1);
$!composed := 1;
}
method find_method($obj, $name, *%opts) {
nqp::null()
}
......
......@@ -8,7 +8,7 @@ knowhow NQPNativeHOW {
method archetypes() {
$archetypes
}
method new(:$name) {
my $obj := nqp::create(self);
$obj.BUILD(:name($name));
......@@ -68,11 +68,11 @@ knowhow NQPNativeHOW {
method nativesize($obj) {
$!nativesize
}
method set_unsigned($obj, $unsigned) {
$!unsigned := $unsigned ?? 1 !! 0
}
method unsigned($obj) {
$!unsigned
}
......
......@@ -61,7 +61,7 @@ knowhow NQPParametricRoleHOW {
nqp::setwho(nqp::newtype($metarole, 'Uninstantiable'), {}),
$name);
}
method set_body_block($obj, $body_block) {
$!body_block := $body_block;
}
......@@ -117,7 +117,7 @@ knowhow NQPParametricRoleHOW {
method parametric($obj) {
1
}
# Curries this parametric role with arguments.
method curry($obj, *@args) {
NQPCurriedRoleHOW.new_type($obj, |@args)
......
......@@ -6,6 +6,7 @@ import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
......@@ -14,8 +15,6 @@ import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.nio.charset.CharacterCodingException;
import org.perl6.nqp.runtime.CallSiteDescriptor;
import org.perl6.nqp.runtime.ExceptionHandling;
import org.perl6.nqp.runtime.Ops;
......@@ -29,22 +28,25 @@ public class AsyncFileHandle implements IIOClosable, IIOEncodable, IIOAsyncReada
public AsyncFileHandle(ThreadContext tc, String filename, String mode) {
try {
Path p = new File(filename).toPath();
if (mode.equals("r")) {
chan = AsynchronousFileChannel.open(p, StandardOpenOption.READ);
}
else if (mode.equals("w")) {
chan = AsynchronousFileChannel.open(p, StandardOpenOption.WRITE,
StandardOpenOption.CREATE);
}
else if (mode.equals("wa")) {
chan = AsynchronousFileChannel.open(p, StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND);
}
else {
ExceptionHandling.dieInternal(tc, "Unhandled file open mode '" + mode + "'");
final Path p = new File(filename).toPath();
switch (mode) {
case "r":
chan = AsynchronousFileChannel.open(p, StandardOpenOption.READ);
break;
case "w":
chan = AsynchronousFileChannel.open(p,
StandardOpenOption.WRITE, StandardOpenOption.CREATE);
break;
case "wa":
chan = AsynchronousFileChannel.open(p,
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
break;
default:
ExceptionHandling.dieInternal(tc, "Unhandled file open mode '" + mode + "'");
break;
}
setEncoding(tc, Charset.forName("UTF-8"));
} catch (IOException e) {
throw ExceptionHandling.dieInternal(tc, e);
......@@ -179,7 +181,7 @@ public class AsyncFileHandle implements IIOClosable, IIOEncodable, IIOAsyncReada
final boolean chomp, final LinkedBlockingQueue<SixModelObject> queue,
final SixModelObject done, final SixModelObject error) {
final LinesState ls = new LinesState();
ls.lineChunks = new ArrayList<ByteBuffer>();
ls.lineChunks = new ArrayList<>();
ls.readBuffer = ByteBuffer.allocate(32768);
ls.total = 0;
ls.position = 0;
......@@ -262,9 +264,7 @@ public class AsyncFileHandle implements IIOClosable, IIOEncodable, IIOAsyncReada
ls.position += bytes;
ls.readBuffer = ByteBuffer.allocate(32768);
chan.read(ls.readBuffer, ls.position, ls, this);
} catch (IOException e) {
failed(e, ls);
} catch (InterruptedException e) {
} catch (IOException | InterruptedException e) {
failed(e, ls);
}
}
......
......@@ -1581,7 +1581,7 @@ public final class Ops {
}
curFrame = curFrame.caller;
}
throw ExceptionHandling.dieInternal(tc, "Dyanmic variable '" + name + "' not found");
throw ExceptionHandling.dieInternal(tc, "Dynamic variable '" + name + "' not found");
}
public static SixModelObject getlexdyn(String name, ThreadContext tc) {
CallFrame curFrame = tc.curFrame.caller;
......
......@@ -296,7 +296,7 @@ class HLL::Backend::MoarVM {
}
nqp::push_s($pieces, ')');
}
elsif nqp::isstr($obj) {
elsif nqp::isstr($obj) {
if nqp::index($obj, '\\') {
$obj := literal_subst($obj, '\\', '\\\\');
}
......
my $ops := QAST::MASTCompiler.operations();
my int $MVM_reg_int32 := 3;
my int $MVM_reg_int64 := 4;
my int $MVM_reg_num64 := 6;
my int $MVM_reg_str := 7;
......@@ -108,6 +109,14 @@ $ops.add_hll_op('nqp', 'falsey', -> $qastcomp, $op {
push_op(@ins, 'not_i', $not_reg, $val.result_reg);
MAST::InstructionList.new(@ins, $not_reg, $MVM_reg_int64)
}
elsif $val.result_kind == $MVM_reg_int32 {
my $not_reg := $regalloc.fresh_register($MVM_reg_int64);
my @ins := $val.instructions;
push_op(@ins, 'extend_i32', $not_reg, $val.result_reg);
push_op(@ins, 'not_i', $not_reg, $not_reg);
MAST::InstructionList.new(@ins, $not_reg, $MVM_reg_int64)
}
elsif $val.result_kind == $MVM_reg_obj {
my $not_reg := $regalloc.fresh_register($MVM_reg_int64);
my $dc := $regalloc.fresh_register($MVM_reg_obj);
......
......@@ -504,6 +504,13 @@ my class MASTCompilerInstance {
elsif $got == $MVM_reg_void {
push_op($il, 'const_n64', $res_reg, MAST::NVal.new( :value(0) ));
}
elsif $got == $MVM_reg_int32 || $got == $MVM_reg_int16 || $got == $MVM_reg_int8 || $got == $MVM_reg_uint32 || $got == $MVM_reg_uint16 || $got == $MVM_reg_uint8 {
my $int64 := self.coercion($res, $MVM_reg_int64);
$il := $int64.instructions;
$reg := $int64.result_reg;
$release_type := $int64.result_kind;
push_op($il, 'coerce_in', $res_reg, $reg);
}
else {
nqp::die("Unknown coercion case for num; got: "~$got);
}
......@@ -512,6 +519,13 @@ my class MASTCompilerInstance {
if $got == $MVM_reg_int64 {
push_op($il, 'coerce_is', $res_reg, $reg);
}
elsif $got == $MVM_reg_int32 {
my $int64 := self.coercion($res, $MVM_reg_int64);
$il := $int64.instructions;
$reg := $int64.result_reg;
$release_type := $int64.result_kind;
push_op($il, 'coerce_is', $res_reg, $reg);
}
elsif $got == $MVM_reg_num64 {
push_op($il, 'coerce_ns', $res_reg, $reg);
}
......@@ -537,6 +551,13 @@ my class MASTCompilerInstance {
if $got == $MVM_reg_int64 {
push_op($il, 'trunc_i32', $res_reg, $reg);
}
elsif $got == $MVM_reg_num64 {
my $int64 := self.coercion($res, $MVM_reg_int64);
$il := $int64.instructions;
$reg := $int64.result_reg;
$release_type := $int64.result_kind;
push_op($il, 'trunc_i32', $res_reg, $reg);
}
else {
nqp::die("Unknown coercion case for int32; got: " ~ $got);
}
......
......@@ -3069,6 +3069,8 @@ QAST::MASTOperations.add_core_op('speshresolve', -> $qastcomp, $op {
QAST::MASTOperations.add_core_moarop_mapping('hllbool', 'hllbool');
QAST::MASTOperations.add_core_moarop_mapping('hllboolfor', 'hllboolfor');
QAST::MASTOperations.add_core_moarop_mapping('decodelocaltime', 'decodelocaltime');
QAST::MASTOperations.add_core_moarop_mapping('fork', 'fork');
sub push_op(@dest, str $op, *@args) {
nqp::push(@dest, MAST::Op.new_with_operand_array( :$op, @args ));
}
......
#! nqp
plan(24);
# 2 tests
......
#! nqp
plan(15);
my class Lock is repr('ReentrantMutex') { }
......
#! nqp
plan(12);
my class Semaphore is repr('Semaphore') { }
......
#! nqp
plan(3);
my $i := 2;
......
#! nqp
my @*vms := nqp::list('jvm', 'moar', 'js');
my %documented_ops := find_documented_opcodes();
......
#! nqp
# Do all the documented opcodes have tests? ... is the question we want to
# ask. This test asks "does the opcode appear in nqp::" form in the
# test suite.
......
#!/usr/bin/env nqp
use NQPHLL;
plan(2);
......
#! nqp
say("1..0 # Skipped: design changes, need re-work");
# plan(4);
......
#! nqp
say("1..0 # Skipped: design changes (EXPORT now lexical), need re-work");
#plan(8);
......
#! nqp
say("1..0 # Skipped: design changes (EXPORT now lexical), need re-work");
#plan(3);
......
#! nqp
plan(31);
use NQPHLL;
......
#! nqp
my $die_message := 'unset';
sub dies_ok(&callable, $description) {
......
#! nqp
# continuations.
plan(14);
......
plan(3);
plan(4);
my $comp := nqp::getcomp('JavaScript');
my $helloworld := $comp.eval('"Hello " + "World"');
my $helloworld := $comp.eval('return "Hello " + "World"');
ok($helloworld eq 'Hello World',"getting a simple string from JavaScript");
my $square := $comp.eval('(function(num) {return num*num})');
my $square := $comp.eval('return (function(num) {return num*num})');
ok($square(4) == 16, "passing integers to a js func");
my $twice := $comp.eval('(function(func) {return function(x) {return func(func(x))}})');
my $twice := $comp.eval('return (function(func) {return function(x) {return func(func(x))}})');
my $twiced := $twice(sub ($x) {"[$x]"})("abc");
ok($twiced eq '[[abc]]', 'passing and calling a NQP function on the JavaScript side');
my $get_second := $comp.eval('return function(array) {return array[1]}');
is($get_second(nqp::list_s('First', 'Second', 'Third')), 'Second', 'passing list_s to js');
#! nqp
# continuations.
plan(22);
......
#! nqp
# continuations.
plan(24);
......
......@@ -91,7 +91,7 @@ $str_boxer.HOW.add_attribute($str_boxer, NQPAttribute.new(
));
$str_boxer.HOW.add_parent($str_boxer, NQPMu);
$str_boxer.HOW.add_method($str_boxer, 'twice', method () {
nqp::getattr_s(self, $str_boxer, '$!value') * 2;
nqp::getattr_s(self, $str_boxer, '$!value') * 2;
});
$str_boxer.HOW.compose($str_boxer);
......
#! nqp
# Test line reading operations.
plan(18);
......@@ -10,21 +8,21 @@ my $test-file := 'line-seps-test-file';
my $wfh := open($test-file, :w);
$wfh.print('abc|def>ghi');
close($wfh);
my $rfh := open($test-file, :r, :!chomp);
$rfh.set-nl-in(nqp::list('|', '>'));
ok($rfh.get eq "abc|", 'first separator used');
ok($rfh.get eq "def>", 'second separator used');
ok($rfh.get eq "ghi", 'final read to end of file worked');
close($rfh);
$rfh := open($test-file, :r);
$rfh.set-nl-in(nqp::list('|', '>'));
ok($rfh.get eq "abc", 'first separator used and chomped');
ok($rfh.get eq "def", 'second separator used and chomped');
ok($rfh.get eq "ghi", 'final read to end of file worked');
close($rfh);
nqp::unlink($test-file);
}
......@@ -32,21 +30,21 @@ my $test-file := 'line-seps-test-file';
my $wfh := open($test-file, :w);
$wfh.print('abc|def||ghi>jkl>>mno');
close($wfh);
my $rfh := open($test-file, :r, :!chomp);
$rfh.set-nl-in(nqp::list('||', '>>'));
ok($rfh.get eq "abc|def||", 'first multi-char separator used');
ok($rfh.get eq "ghi>jkl>>", 'second multi-char separator used');
ok($rfh.get eq "mno", 'final read to end of file worked');
close($rfh);
$rfh := open($test-file, :r);
$rfh.set-nl-in(nqp::list('||', '>>'));
ok($rfh.get eq "abc|def", 'first multi-char separator used and chomped');
ok($rfh.get eq "ghi>jkl", 'second multi-char separator used and chomped');
ok($rfh.get eq "mno", 'final read to end of file worked');
close($rfh);
nqp::unlink($test-file);
}
......
# t/moar/argument-truncation.t
plan(8);
sub pos8(int8 $i) {
......@@ -35,4 +33,3 @@ named8(:i(42));
named16(:i(42));
named32(:i(42));
named64(:i(42));
#!/usr/bin/env nqp
## TODO XXX need MORE tests to check failures, not just succeses
plan(103);
ok(!nqp::eqatic('b', 'bb', 0), "MVM index/eqatic bug");
......
#!/usr/bin/env nqp
plan(119 * 2 + 4 * 3);
ok(nqp::indexic('hi', '', 2) == 2, 'nqp::indexic finds empty string after last index');
ok(nqp::indexic('hi', '', 0) == 0, 'nqp::indexic finds empty string at start');
......
#!/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");
......
# This can be moved when *conf ops are added to jvm and others
# XXX This can be moved when *conf ops are added to jvm and others
use nqpmo;
plan(9);
......
#! nqp
plan(2);
my @a := nqp::decodelocaltime(nqp::time_i());
......
#!/usr/bin/env nqp
# Test case for even-moar-jit register allocator.
# This only demonstrates something when run under MVM_JIT_EXPR_ENABLE=1
......@@ -56,4 +54,3 @@ while $i < 301 {
}
$i := $i + 1;
}
#!/usr/bin/env nqp-m
nqp::say("1..12");
sub foo(int $i, int $j) {
my int $x := nqp::div_i($i, $j);
......
#!/usr/bin/env nqp
# Tests for extending the MoarVM specializer to guard on new kinds of things
# from NQP.
# from NQP.
plan(66);
......
#! nqp
# nqp::buildnativecall($target, $libname, $symbol, $convention, $arguments, $returns)
#
# Build a call descriptor into $target (which must be NativeCall REPRd or have
......@@ -30,7 +28,7 @@
# $returns is a hash of the same kind used in $arguments
#
# nqp::nativecall($returns, $call, $arguments)
#
#
# Actually calls the foreign function. $returns is the type object for the
# return type (or null, for void functions), $call is the descriptor build
# with nqp::buildnativecall, and $arguments the arguments passed.
......
#! nqp
# check literals
say('1..9');
......
#! nqp
# check control structure 'if'
say('1..6');
......
#! nqp
# check control structure 'if ... else'
say('1..14');
......
#! nqp
# check control structure 'unless'
say('1..6');
......@@ -22,4 +20,3 @@ say("ok 5 # postfix statement modifier form (false)") unless 0;
print("not ") unless 1;
say("ok 6 # postfix statement modifier form (true)");
#! nqp
# check comments
say('1..16');
......
#! nqp
# check blocks and statement enders
say('1..7');
......@@ -30,4 +28,3 @@ say('1..7');
}; {
say("7 # blocks following an end brace must be separated by a semicolon")
}
#! nqp
# check comparisons
say('1..19');
......
#! nqp
# check '||', '&&', and '//'
plan(17);
......
......@@ -49,4 +49,3 @@ ok( !0.0 );
ok( (1 +| 3) == 3, 'Checking 1 +| 3' );
ok( (3 +& 2) == 2, 'Checking 3 +& 2' );
ok( (3 +^ 3) == 0, 'Checking 3 +^ 3' );
......@@ -18,4 +18,3 @@ is( $a, 'yes' );
my $d := 0 ?? ( $a := 'no' ) !! 'yes';
is( $d, 'yes' );
is( $a, 'yes' );
#! nqp
# check positional subscripting
plan(7);
......@@ -20,4 +18,3 @@ say(@l[0]);
@l[10] := 'ok 7 # automatic expansion';
say(@l[10]);
#! nqp
# implicit and explicit returns from subs
plan(5);
......@@ -18,7 +16,7 @@ sub baz() {
}
sub nested() {
if (1) {
if (1) {
my $try_to_stop_the_nested_block_from_being_optimized_out := 4;
return $try_to_stop_the_nested_block_from_being_optimized_out;
}
......
#! nqp
# Tests for contextual variables
plan(31);
......
#!/usr/bin/env nqp
# test optional arguments and parameters
plan(7);
......
#! nqp
# test named parameters and arguments
plan(11);
......
#! nqp
# check module
plan(3);
......@@ -16,4 +14,3 @@ module XYZ {
XYZ::foo('ok 3');
XYZ::sayfoo();
#! nqp
# method ops (just method calls for now)
plan(5);
......
......@@ -22,7 +22,7 @@ class Foo {
};
method quat() {
for 2,3 -> $a {
for 2,3 -> $a {
ok($a + $!abc, 'Can access attribute within lexical block');
}
}
......
#! nqp
# class inheritance
plan(9);
......
#! nqp
# Tests for 'make' builtin.
plan(2);
......@@ -15,5 +13,3 @@ our sub foo() {
foo();
say($/.ast);
#! nqp
# Test grammars and regexes
plan(18);
......
#! nqp
# test protoregexes in grammars
plan(7);
......@@ -31,6 +29,3 @@ ok( !$/ , 'successfully failed protoregex match' );
$/ := ABC.parse('xxx', :rule<symbols>);
ok( !$/ , 'successfully failed protoregex match' );
#! nqp
# Test INIT blocks
INIT plan(4);
......@@ -19,5 +17,3 @@ $foo := 3;
INIT ok($foo++, 'after first INIT but before mainline');
ok($foo == 3, 'After everything else');
#! nqp
plan(13);
grammar ABC {
......
#! nqp
# interpolating quotes
plan(17);
......
#! nqp
plan(7);
my $count := 1;
......