...
 
Commits (4)
......@@ -73,6 +73,7 @@ examples/webpacked/webpack.config.js
gen/js/.gitignore
gen/jvm/.gitignore
gen/moar/.gitignore
mbc.nqp
nqp-js-on-js/.gitignore
nqp-js-on-js/.npmignore
nqp-js-on-js/package.json
......@@ -166,6 +167,7 @@ src/vm/js/const_map.nqp
src/vm/js/nqp-loader/main.js
src/vm/js/nqp-loader/package.json
src/vm/js/nqp-runtime/BOOT.js
src/vm/js/nqp-runtime/as-int-n.js
src/vm/js/nqp-runtime/async-continuations.js
src/vm/js/nqp-runtime/bignum.js
src/vm/js/nqp-runtime/bootstrap.js
......@@ -214,10 +216,12 @@ src/vm/js/nqp-runtime/resolve-sourcemap.js
src/vm/js/nqp-runtime/runtime.js
src/vm/js/nqp-runtime/serialization-context.js
src/vm/js/nqp-runtime/serialization.js
src/vm/js/nqp-runtime/shared-io.js
src/vm/js/nqp-runtime/sixmodel.js
src/vm/js/nqp-runtime/static-ctx.js
src/vm/js/nqp-runtime/strip-marks.js
src/vm/js/nqp-runtime/tables/shiftjis.json
src/vm/js/nqp-runtime/tap-console.js
src/vm/js/nqp-runtime/unicode-data.js
src/vm/js/nqp-runtime/unicode-props.js
src/vm/jvm/HLL/Backend.nqp
......
nqp (2018.11+dfsg-1) unstable; urgency=medium
* New upstream version 2018.11+dfsg
* control: update moarvm-dev dep versions
-- Robert Lemmen <robertle@semistable.com> Sat, 01 Dec 2018 18:50:24 +0100
nqp (2018.10+dfsg-1) unstable; urgency=medium
* New upstream version 2018.10+dfsg
......
......@@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 9),
libjs-jquery,
libreadline-dev,
libtommath-dev (>= 0.42.0-1.2),
moarvm-dev (>= 2018.10),
moarvm-dev (>= 2018.11),
perl
Standards-Version: 4.1.4
Vcs-Browser: https://salsa.debian.org/perl6-team/nqp
......
This diff is collapsed.
......@@ -1268,6 +1268,9 @@ class NQP::Actions is HLL::Actions {
$*W.create_code($ast.ann('block_ast'), $name, 0);
};
}
elsif $<longname> eq 'box_target' {
make -> $m { $*DECLARAND_ATTR.set_box_target(1) };
}
else {
$/.panic("Trait '$<longname>' not implemented");
}
......
......@@ -412,6 +412,7 @@ grammar NQP::Grammar is HLL::Grammar {
<.newpad>
[ <?{ $*PKGDECL eq 'role' }> '[' ~ ']' <role_params> ]?
[ 'is' 'repr(' <repr=.quote_EXPR> ')' ]?
[ 'is' 'array_type(' <array_type=.typename> ')' ]?
{
# Construct meta-object for this package, adding it to the
......@@ -421,6 +422,10 @@ grammar NQP::Grammar is HLL::Grammar {
if $<repr> {
%args<repr> := ~$<repr><quote_delimited><quote_atom>[0];
}
%args<array_type> := NQPMu;
if $<array_type> {
%args<array_type> := $*W.find_sym([~$<array_type><name>]);
}
my $how := self.how($*PKGDECL);
my $INNER := $*W.cur_lexpad();
my $package := $*W.pkg_create_mo($how, |%args);
......
......@@ -369,12 +369,13 @@ class NQP::World is HLL::World {
# Creates a meta-object for a package, adds it to the root objects and
# stores an event for the action. Returns the created object.
method pkg_create_mo($how, :$name, :$repr) {
method pkg_create_mo($how, :$name, :$repr, :$array_type) {
# Create the meta-object and add to root objects.
my %args;
if nqp::defined($name) { %args<name> := $name; }
if nqp::defined($repr) { %args<repr> := $repr; }
my $mo := $how.new_type(|%args);
if !($array_type =:= NQPMu) { $mo.HOW.set_array_type($mo, $array_type) }
self.add_object($mo);
# Result is just the object.
......
......@@ -49,6 +49,10 @@ knowhow NQPAttribute {
$!has_default ?? $!default !! nqp::null()
}
method set_box_target($box_target) {
$!box_target := $box_target;
}
method set_positional_delegate($value) {
$!positional_delegate := $value;
}
......
......@@ -19,6 +19,10 @@ knowhow NQPClassHOW {
has @!roles;
has $!default_parent;
# Array type support.
has $!is_array_type;
has $!array_type;
# Have we been composed?
has $!composed;
......@@ -79,7 +83,7 @@ knowhow NQPClassHOW {
# Create a new meta-class instance, and then a new type object
# to go with it, and return that.
method new_type(:$name = '<anon>', :$repr = 'P6opaque') {
method new_type(:$name = '<anon>', :$repr = 'P6opaque', :$array_type) {
my $metaclass := self.new(:name($name));
nqp::setdebugtypename(
nqp::setwho(nqp::newtype($metaclass, $repr), {}),
......@@ -122,6 +126,19 @@ knowhow NQPClassHOW {
nqp::push(@!attributes, $meta_attr);
}
method is_array_type($obj) {
$!is_array_type
}
method array_type($obj) {
$!array_type
}
method set_array_type($obj, $type) {
$!is_array_type := 1;
$!array_type := $type;
}
method add_parent($obj, $parent) {
if $!composed {
nqp::die("NQPClassHOW does not support adding parents after being composed.");
......@@ -225,49 +242,59 @@ knowhow NQPClassHOW {
}
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;
nqp::push(@repr_info, @type_info);
# ...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);
for $type_obj.HOW.attributes($type_obj, :local) -> $attr {
my %attr_info;
%attr_info<name> := $attr.name;
%attr_info<type> := $attr.type;
if $attr.box_target {
# Merely having the key serves as a "yes".
%attr_info<box_target> := 1;
}
if nqp::can($attr, 'auto_viv_container') {
%attr_info<auto_viv_container> := $attr.auto_viv_container;
}
if $attr.positional_delegate {
%attr_info<positional_delegate> := 1;
}
if $attr.associative_delegate {
%attr_info<associative_delegate> := 1;
if self.is_array_type($obj) {
if self.attributes($obj) {
nqp::die("Cannot have attributes on an array representation");
}
nqp::composetype(nqp::decont($obj), nqp::hash('array',
nqp::hash('type', nqp::decont(self.array_type($obj)))));
}
else {
# 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;
nqp::push(@repr_info, @type_info);
# ...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);
for $type_obj.HOW.attributes($type_obj, :local) -> $attr {
my %attr_info;
%attr_info<name> := $attr.name;
%attr_info<type> := $attr.type;
if $attr.box_target {
# Merely having the key serves as a "yes".
%attr_info<box_target> := 1;
}
if nqp::can($attr, 'auto_viv_container') {
%attr_info<auto_viv_container> := $attr.auto_viv_container;
}
if $attr.positional_delegate {
%attr_info<positional_delegate> := 1;
}
if $attr.associative_delegate {
%attr_info<associative_delegate> := 1;
}
nqp::push(@attrs, %attr_info);
}
nqp::push(@attrs, %attr_info);
# ...followed by a list of immediate parents.
nqp::push(@type_info, $type_obj.HOW.parents($type_obj, :local));
}
# ...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;
nqp::composetype($obj, $info)
}
# Compose the representation using it.
my $info := nqp::hash();
$info<attribute> := @repr_info;
nqp::composetype($obj, $info)
}
method incorporate_multi_candidates($obj) {
......
......@@ -195,7 +195,7 @@ knowhow NQPParametricRoleHOW {
@attrs
}
method roles($obj) {
method roles($obj, :$transitive) {
@!roles
}
}
......@@ -2426,6 +2426,7 @@ QAST::OperationsJAST.map_classlib_core_op('scobjcount', $TYPE_OPS, 'scobjcount',
QAST::OperationsJAST.map_classlib_core_op('setobjsc', $TYPE_OPS, 'setobjsc', [$RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('getobjsc', $TYPE_OPS, 'getobjsc', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('serialize', $TYPE_OPS, 'serialize', [$RT_OBJ, $RT_OBJ], $RT_STR, :tc);
QAST::OperationsJAST.map_classlib_core_op('serializetobuf', $TYPE_OPS, 'serializetobuf', [$RT_OBJ, $RT_OBJ, $RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('deserialize', $TYPE_OPS, 'deserialize', [$RT_STR, $RT_OBJ, $RT_OBJ, $RT_OBJ, $RT_OBJ], $RT_STR, :tc);
QAST::OperationsJAST.map_classlib_core_op('wval', $TYPE_OPS, 'wval', [$RT_STR, $RT_INT], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('scwbdisable', $TYPE_OPS, 'scwbdisable', [], $RT_INT, :tc);
......
......@@ -5189,7 +5189,7 @@ public final class Ops {
((SCRefInstance)scRef).referencedSC,
stringHeap);
String serialized = sw.serialize();
String serialized = Base64.encode(sw.serialize());
int index = 0;
for (String s : stringHeap) {
......@@ -5203,6 +5203,31 @@ public final class Ops {
throw ExceptionHandling.dieInternal(tc, "serialize was not passed a valid SCRef");
}
}
public static SixModelObject serializetobuf(SixModelObject scRef, SixModelObject sh, SixModelObject type, ThreadContext tc) {
if (scRef instanceof SCRefInstance) {
ArrayList<String> stringHeap = new ArrayList<String>();
SerializationWriter sw = new SerializationWriter(tc,
((SCRefInstance)scRef).referencedSC,
stringHeap);
SixModelObject buf = type.st.REPR.allocate(tc, type.st);
byte[] serialized = sw.serialize().array();
Buffers.stashBytes(tc, buf, serialized);
int index = 0;
for (String s : stringHeap) {
tc.native_s = s;
sh.bind_pos_native(tc, index++);
}
return buf;
}
else {
throw ExceptionHandling.dieInternal(tc, "serialize was not passed a valid SCRef");
}
}
public static String deserialize(String blob, SixModelObject scRef, SixModelObject sh, SixModelObject cr, SixModelObject conflict, ThreadContext tc) throws IOException {
if (scRef instanceof SCRefInstance) {
SerializationContext sc = ((SCRefInstance)scRef).referencedSC;
......
......@@ -8,7 +8,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.perl6.nqp.runtime.Base64;
import org.perl6.nqp.runtime.CallFrame;
import org.perl6.nqp.runtime.CodeRef;
import org.perl6.nqp.runtime.ExceptionHandling;
......@@ -104,7 +103,7 @@ public class SerializationWriter {
this.contextsListPos = 0;
}
public String serialize() {
public ByteBuffer serialize() {
/* Initialize string heap so first entry is the NULL string. */
sh.add(null);
......@@ -402,7 +401,7 @@ public class SerializationWriter {
}
/* Concatenates the various output segments into a single binary string. */
private String concatenateOutputs() {
private ByteBuffer concatenateOutputs() {
int output_size = 0;
int offset = 0;
......@@ -518,8 +517,7 @@ public class SerializationWriter {
if (offset != output_size)
throw new RuntimeException("Serialization sanity check failed: offset != output_size");
/* Base 64 encode and return. */
return Base64.encode(output);
return output;
}
/* This handles the serialization of an object, which largely involves a
......
......@@ -113,18 +113,21 @@ class HLL::Backend::MoarVM {
$escaped_squote := q{\\'};
}
my int $new-id-counter := 0;
my int $new-id-counter := -1;
my $id_remap := nqp::hash();
my $id_to_thing := nqp::hash();
my %type-info := nqp::hash();
my int $node-id-counter := -1;
sub post_process_call_graph_node($node) {
my $this-node-id := ++$node-id-counter;
try {
if nqp::existskey($id_remap, $node<id>) {
$node<id> := $id_remap{$node<id>};
} else {
my str $newkey := ~($new-id-counter++);
my str $newkey := ~(++$new-id-counter);
$id_remap{$node<id>} := $newkey;
$node<id> := $newkey;
}
......@@ -134,7 +137,7 @@ class HLL::Backend::MoarVM {
if nqp::existskey($id_remap, %alloc_info<id>) {
%alloc_info<id> := $id_remap{%alloc_info<id>};
} else {
my str $newkey := ~($new-id-counter++);
my str $newkey := ~(++$new-id-counter);
$id_remap{%alloc_info<id>} := $newkey;
%alloc_info<id> := $newkey;
}
......@@ -190,6 +193,7 @@ class HLL::Backend::MoarVM {
note(nqp::getmessage($!));
}
}
$node<highest_child_id> := $node-id-counter;
}
sub to_json($obj) {
......@@ -365,7 +369,8 @@ class HLL::Backend::MoarVM {
}
for $obj -> $thread {
my $thisprof := nqp::list;
$thisprof[3] := "NULL";
$thisprof[4] := "NULL";
$thisprof[5] := ~$thread<start_time>;
for $thread -> $k {
my $v := $thread{$k};
if $k eq 'total_time' {
......@@ -388,9 +393,12 @@ class HLL::Backend::MoarVM {
nqp::push_s($pieces, nqp::join(',', @g) ~ ");\n");
}
}
elsif $k eq 'parent' {
$thisprof[3] := ~$v;
}
elsif $k eq 'call_graph' {
my %call_rec_depth;
$thisprof[3] := ~$node_id;
$thisprof[4] := ~$node_id;
sub collect_calls(str $parent_id, %call_graph) {
my str $call_id := ~$node_id;
$node_id++;
......@@ -401,6 +409,8 @@ class HLL::Backend::MoarVM {
my str $routine_id := ~%call_graph<id>;
%call_rec_depth{$routine_id} := 0 unless %call_rec_depth{$routine_id};
nqp::push_s(@call, ~%call_rec_depth{$routine_id});
nqp::push_s(@call, ~%call_graph<first_entry_time>);
nqp::push_s(@call, ~%call_graph<highest_child_id>);
nqp::push_s($pieces, 'INSERT INTO calls VALUES (');
nqp::push_s($pieces, nqp::join(',', @call) ~ ");\n");
if %call_graph<allocations> {
......@@ -493,8 +503,8 @@ class HLL::Backend::MoarVM {
$profile_fh.say('CREATE TABLE types(id INTEGER PRIMARY KEY ASC, name TEXT, extra_info JSON, type_links JSON);');
$profile_fh.say('CREATE TABLE routines(id INTEGER PRIMARY KEY ASC, name TEXT, line INT, file TEXT);');
$profile_fh.say('CREATE TABLE gcs(time INT, retained_bytes INT, promoted_bytes INT, gen2_roots INT, full INT, responsible INT, cleared_bytes INT, start_time INT, sequence_num INT, thread_id INT);');
$profile_fh.say('CREATE TABLE calls(id INTEGER PRIMARY KEY ASC, parent_id INT, routine_id INT, osr INT, spesh_entries INT, jit_entries INT, inlined_entries INT, inclusive_time INT, exclusive_time INT, entries INT, deopt_one INT, deopt_all INT, rec_depth INT, FOREIGN KEY(routine_id) REFERENCES routines(id));');
$profile_fh.say('CREATE TABLE profile(total_time INT, spesh_time INT, thread_id INT, root_node INT, FOREIGN KEY(root_node) REFERENCES calls(id));');
$profile_fh.say('CREATE TABLE calls(id INTEGER PRIMARY KEY ASC, parent_id INT, routine_id INT, osr INT, spesh_entries INT, jit_entries INT, inlined_entries INT, inclusive_time INT, exclusive_time INT, entries INT, deopt_one INT, deopt_all INT, rec_depth INT, first_entry_time INT, highest_child_id INT, FOREIGN KEY(routine_id) REFERENCES routines(id));');
$profile_fh.say('CREATE TABLE profile(total_time INT, spesh_time INT, thread_id INT, parent_thread_id INT, root_node INT, first_entry_time INT, FOREIGN KEY(root_node) REFERENCES calls(id));');
$profile_fh.say('CREATE TABLE allocations(call_id INT, type_id INT, spesh INT, jit INT, count INT, PRIMARY KEY(call_id, type_id), FOREIGN KEY(call_id) REFERENCES calls(id), FOREIGN KEY(type_id) REFERENCES types(id));');
to_sql($data);
$profile_fh.say('END;');
......
......@@ -105,46 +105,36 @@ $ops.add_hll_op('nqp', 'falsey', -> $qastcomp, $op {
my $regalloc := $*REGALLOC;
if $val.result_kind == $MVM_reg_int64 {
my $not_reg := $regalloc.fresh_register($MVM_reg_int64);
my @ins := $val.instructions;
push_op(@ins, 'not_i', $not_reg, $val.result_reg);
MAST::InstructionList.new(@ins, $not_reg, $MVM_reg_int64)
MAST::Op.new(:op<not_i>, $not_reg, $val.result_reg);
MAST::InstructionList.new($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)
MAST::Op.new(:op<extend_i32>, $not_reg, $val.result_reg);
MAST::Op.new(:op<not_i>, $not_reg, $not_reg);
MAST::InstructionList.new($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);
my @ins := $val.instructions;
push_op(@ins, 'decont', $dc, $val.result_reg);
push_op(@ins, 'isfalse', $not_reg, $dc);
MAST::Op.new(:op<decont>, $dc, $val.result_reg);
MAST::Op.new(:op<isfalse>, $not_reg, $dc);
$regalloc.release_register($dc, $MVM_reg_obj);
MAST::InstructionList.new(@ins, $not_reg, $MVM_reg_int64)
MAST::InstructionList.new($not_reg, $MVM_reg_int64)
}
elsif $val.result_kind == $MVM_reg_str {
my $not_reg := $regalloc.fresh_register($MVM_reg_int64);
my @ins := $val.instructions;
push_op(@ins, 'isfalse_s', $not_reg, $val.result_reg);
MAST::InstructionList.new(@ins, $not_reg, $MVM_reg_int64)
MAST::Op.new(:op<isfalse_s>, $not_reg, $val.result_reg);
MAST::InstructionList.new($not_reg, $MVM_reg_int64)
}
elsif $val.result_kind == $MVM_reg_num64 {
my $tmp_reg := $regalloc.fresh_register($MVM_reg_num64);
my $res_reg := $regalloc.fresh_register($MVM_reg_int64);
my @ins := $val.instructions;
push_op(@ins, 'const_n64', $tmp_reg, MAST::NVal.new( :value(0.0) ));
push_op(@ins, 'eq_n', $res_reg, $val.result_reg, $tmp_reg);
MAST::InstructionList.new(@ins, $res_reg, $MVM_reg_int64)
MAST::Op.new(:op<const_n64>, $tmp_reg, 0.0);
MAST::Op.new(:op<eq_n>, $res_reg, $val.result_reg, $tmp_reg);
MAST::InstructionList.new($res_reg, $MVM_reg_int64)
}
else {
nqp::die("This case of nqp falsey op NYI");
}
});
sub push_op(@dest, str $op, *@args) {
nqp::push(@dest, MAST::Op.new_with_operand_array( :$op, @args ));
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.