Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Various fixes and tweaks. This gets us actually doing an initial call…
… to the SC builder during the compile, though of course it's a drop in the ocean. Turns out that there's going to be quite some yaks to shave before this can really come into use.
  • Loading branch information
jnthn committed Feb 18, 2011
1 parent 9d84745 commit f115e3e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 14 deletions.
38 changes: 35 additions & 3 deletions src/HLL/SerializationContextBuilder.pm
Expand Up @@ -47,9 +47,22 @@ class HLL::Compiler::SerializationContextBuilder {
pir::get_addr__IP($obj)
}

# The event stream that builds them.
# The event stream that builds or fixes up objects.
has @!event_stream;

# XXX Fix BUILD...
method new() {
my $obj := self.CREATE();
$obj.BUILD();
$obj
}

method BUILD() {
@!root_objects := pir::new('ResizablePMCArray');
%!addr_to_slot := pir::new('Hash');
@!event_stream := pir::new('ResizablePMCArray');
}

# Gets the slot for a given object. Dies if it is not in the context.
method slot_for_object($obj) {
my $slot := %!addr_to_slot{addr($obj)};
Expand All @@ -70,7 +83,7 @@ class HLL::Compiler::SerializationContextBuilder {

# Utility sub to wrap PAST with slot setting.
sub set_slot_past($slot, $past_to_set) {
return PAST::Op.new( :pirop('nqp_set_sc_object vPP'), $slot, $past_to_set );
return PAST::Op.new( :pirop('nqp_set_sc_object viP'), $slot, $past_to_set );
}

# Adds an object to the root set, along with a mapping.
Expand All @@ -81,6 +94,12 @@ class HLL::Compiler::SerializationContextBuilder {
$idx
}

method add_event(:$deserialize_past, :$fixup_past) {
@!event_stream.push(HLL::Compiler::SerializationContextBuilder::Event.new(
:deserialize_past($deserialize_past), :fixup_past($fixup_past)
));
}

# 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) {
Expand All @@ -93,7 +112,7 @@ class HLL::Compiler::SerializationContextBuilder {

# Add an event. There's no fixup to do, just a type object to create
# on deserialization.
my @how_ns := pir::split('::', $mo.HOW.HOW.name($mo.HOW));
my @how_ns := pir::split('::', $how.HOW.name($how));
my $how_name := @how_ns.pop();
my $setup_call := PAST::Op.new(
:pasttype('callmethod'), :name('new_type'),
Expand Down Expand Up @@ -126,6 +145,13 @@ class HLL::Compiler::SerializationContextBuilder {

# Composes the package, and stores an event for this action.
method pkg_compose($obj) {
my $slot_past := get_slot_past_for_object($obj);
self.add_event(:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name('compose'),
PAST::Op.new( :pirop('get_how PP'), $slot_past ),
$slot_past
)));
$obj
}

# Gets the root object graph for the serialization context, which can
Expand All @@ -137,6 +163,12 @@ class HLL::Compiler::SerializationContextBuilder {
# Generates a series of PAST operations that will build this context if
# it doesn't exist, and fix it up if it already does.
method to_past() {
# XXX For now we always deserialize, just to get things working.
my $ds := PAST::Stmts.new();
for @!event_stream {
$ds.push($_.deserialize_past());
}
$ds
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/NQP/Actions.pm
Expand Up @@ -49,12 +49,19 @@ sub colonpair_str($ast) {
method comp_unit($/) {
my $mainline := $<statementlist>.ast;
my $unit := @BLOCK.shift;

# Unit needs to have a load-init holding the deserialization or
# fixup code for this compilation unit.
# XXX Apart from ENOTYET, because we still violate the "can't
# declare a meta-object in the same compilation unit as it
# gets used" rule
#$unit.loadinit().push($*SC.to_past());

# If our caller wants to know the mainline ctx, provide it here.
# (CTXSAVE is inherited from HLL::Actions.)
$unit.push( self.CTXSAVE() );

# Need to load the nqp-rx dynops/dympmcs.
# Need to load the NQP dynops/dympmcs.
$unit.loadlibs('nqp_group', 'nqp_ops');
$unit.unshift(PAST::Op.new( :pirop('nqp_dynop_setup v') ));

Expand Down
15 changes: 9 additions & 6 deletions src/NQP/Grammar.pm
Expand Up @@ -2,6 +2,7 @@ grammar NQP::Grammar is HLL::Grammar;


method TOP() {
# Language braids.
my %*LANG;
%*LANG<Regex> := NQP::Regex;
%*LANG<Regex-actions> := NQP::RegexActions;
Expand All @@ -21,6 +22,11 @@ method TOP() {
my $*DEFAULT-METAATTR := 'NQPAttribute';
my %*HOW-METAATTR;
%*HOW-METAATTR<knowhow> := 'KnowHOWAttribute';

# Serialization context builder - keeps track of objects that
# cross the compile-time/run-time boundary that are associated
# with this compilation unit.
my $*SC := HLL::Compiler::SerializationContextBuilder.new();

my $*SCOPE := '';
my $*MULTINESS := '';
Expand Down Expand Up @@ -318,17 +324,14 @@ rule package_def {
[ 'is' 'repr(' <repr=.quote_EXPR> ')' ]?

{
# Construct meta-object for this package.
my $mo := %*HOW{$*PKGDECL};
# Construct meta-object for this package, adding it to the
# serialization context for this compilation unit.
my %args;
%args<name> := ~$<name>;
if $<repr> {
%args<repr> := ~$<repr>[0];
}
if pir::can($mo, 'parametric') && $mo.parametric($mo) {
%args<body_block> := -> $c { };
}
$*PKGMETA := $mo.new_type(|%args);
$*PKGMETA := $*SC.pkg_create_mo(%*HOW{$*PKGDECL}, |%args);
}

[ 'is' <parent=.name> ]?
Expand Down
12 changes: 8 additions & 4 deletions src/metamodel/serialization_context.c
Expand Up @@ -29,8 +29,10 @@ static void setup_sc_stores(PARROT_INTERP) {
PMC * SC_get_sc_object(PARROT_INTERP, INTVAL idx) {
/* Locate the SC root list for this bytecode segment. */
INTVAL addr = (INTVAL)interp->code;
INTVAL scs = VTABLE_elements(interp, sc_index_lookup);
INTVAL i;
INTVAL scs, i;
if (!sc_index_lookup)
setup_sc_stores(interp);
scs = VTABLE_elements(interp, sc_index_lookup);
for (i = 0; i < scs; i++) {
if (VTABLE_get_integer_keyed_int(interp, sc_index_lookup, i) == addr) {
/* Found it; grab object we're looking for. */
Expand All @@ -48,9 +50,11 @@ PMC * SC_get_sc_object(PARROT_INTERP, INTVAL idx) {
void SC_set_sc_object(PARROT_INTERP, INTVAL idx, PMC *object) {
/* Locate the SC root list for this bytecode segment. */
INTVAL addr = (INTVAL)interp->code;
INTVAL scs = VTABLE_elements(interp, sc_index_lookup);
PMC * sc_root = PMCNULL;
INTVAL i;
INTVAL scs, i;
if (!sc_index_lookup)
setup_sc_stores(interp);
scs = VTABLE_elements(interp, sc_index_lookup);
for (i = 0; i < scs; i++) {
if (VTABLE_get_integer_keyed_int(interp, sc_index_lookup, i) == addr) {
sc_root = VTABLE_get_pmc_keyed_int(interp, sc_root_objects, i);
Expand Down

0 comments on commit f115e3e

Please sign in to comment.