Commit 8f199c35 authored by Robert Lemmen's avatar Robert Lemmen

New upstream version 2018.10+dfsg

parent cfdda17f
......@@ -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:
......
{
"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)
......