Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Refactoring and simplification to fixup event handling.
  • Loading branch information
jnthn committed Feb 13, 2012
1 parent 15cb1fe commit ad91b27
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 64 deletions.
48 changes: 14 additions & 34 deletions src/HLL/World.pm
Expand Up @@ -18,24 +18,6 @@
# serialization context.

class HLL::World {
# Represents an event that we need to handle when fixing up or deserializing.
my class Event {
# The PAST that we emit to perform the action if in deserialization mode.
has $!deserialize_past;
method deserialize_past() { $!deserialize_past }

# The PAST that we emit to do any fixups if we are in compile-n-run mode.
has $!fixup_past;
method fixup_past() { $!fixup_past }

method new(:$deserialize_past, :$fixup_past) {
my $node := nqp::create(self);
nqp::bindattr($node, Event, '$!deserialize_past', $deserialize_past);
nqp::bindattr($node, Event, '$!fixup_past', $fixup_past);
$node
}
}

# The serialization context that we're building.
has $!sc;

Expand All @@ -51,9 +33,10 @@ class HLL::World {
# List of PAST blocks that map to the code refs table, for use in
# building deserialization code.
has $!code_ref_blocks;

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

# List of PAST nodes specifying fixup tasks, either after deserialization
# or between compile time and run time.
has @!fixup_tasks;

# Address => slot mapping, so we can quickly look up existing objects
# in the context.
Expand All @@ -74,7 +57,7 @@ class HLL::World {
$!sc := pir::nqp_create_sc__PS($handle);
$!handle := $handle;
%!addr_to_slot := nqp::hash();
@!event_stream := nqp::list();
@!fixup_tasks := nqp::list();
$!sc.set_description($description);
$!precomp_mode := %*COMPILING<%?OPTIONS><target> eq 'pir';
$!num_code_refs := 0;
Expand Down Expand Up @@ -164,17 +147,14 @@ class HLL::World {
$!precomp_mode
}

# Add an event that may have an action to deserialize or fix up.
# Note that we can determine which one we need and just save the
# needed one.
method add_event(:$deserialize_past, :$fixup_past) {
# Add an event that we need to run at fixup time (after deserialization of
# between compilation and runtime).
method add_fixup_task(:$deserialize_past, :$fixup_past) {
if $!precomp_mode {
# Pre-compilation; only need deserialization PAST.
@!event_stream.push(Event.new(:deserialize_past($deserialize_past)));
@!fixup_tasks.push($deserialize_past) if $deserialize_past;
}
else {
# Presumably, going all the way to running, so just fixups.
@!event_stream.push(Event.new(:fixup_past($fixup_past)));
@!fixup_tasks.push($fixup_past) if $fixup_past;
}
}

Expand All @@ -200,7 +180,7 @@ class HLL::World {
my $handle := $sc.handle;
unless pir::exists(%!dependencies, $handle) {
%!dependencies{$handle} := $sc;
self.add_event(:deserialize_past(PAST::Op.new(
self.add_fixup_task(:deserialize_past(PAST::Op.new(
:pasttype('if'),
PAST::Op.new(
:pirop('isnull IP'),
Expand Down Expand Up @@ -229,9 +209,9 @@ class HLL::World {
$!handle
}

# Gets the event stream.
method event_stream() {
@!event_stream
# Gets the list of tasks to do at fixup time.
method fixup_tasks() {
@!fixup_tasks
}

# Serializes the SC to binary and a string heap. Then produces PAST to handle
Expand Down
59 changes: 29 additions & 30 deletions src/NQP/World.pm
Expand Up @@ -21,7 +21,7 @@ class NQP::World is HLL::World {

# Do load for pre-compiled situation.
if self.is_precompilation_mode() {
self.add_event(:deserialize_past(PAST::Stmts.new(
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
Expand All @@ -38,7 +38,7 @@ class NQP::World is HLL::World {
}
else {
# Needs fixup.
self.add_event(:fixup_past(PAST::Op.new(
self.add_fixup_task(:fixup_past(PAST::Op.new(
:pasttype('callmethod'), :name('set_outer_ctx'),
PAST::Var.new( :name('block'), :scope('register') ),
PAST::Op.new(
Expand All @@ -61,7 +61,7 @@ class NQP::World is HLL::World {

# Make sure we do the loading during deserialization.
if self.is_precompilation_mode() {
self.add_event(:deserialize_past(PAST::Stmts.new(
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
Expand Down Expand Up @@ -95,7 +95,7 @@ class NQP::World is HLL::World {
for @sym {
$path := PAST::Op.new(:pirop('nqp_get_package_through_who PPs'), $path, ~$_);
}
self.add_event(:deserialize_past(PAST::Op.new(
self.add_fixup_task(:deserialize_past(PAST::Op.new(
:pasttype('bind_6model'),
PAST::Var.new(
:scope('keyed'),
Expand Down Expand Up @@ -131,7 +131,7 @@ class NQP::World is HLL::World {
PAST::Val.new( :value($block), :returns('LexInfo' ))
)
);
self.add_event(:deserialize_past($fixup), :fixup_past($fixup));
self.add_fixup_task(:deserialize_past($fixup), :fixup_past($fixup));
}

# Adds a fixup to install a specified PAST::Block in a package under the
Expand All @@ -146,7 +146,7 @@ class NQP::World is HLL::World {
),
PAST::Val.new( :value($past_block) )
);
self.add_event(:deserialize_past($fixup), :fixup_past($fixup));
self.add_fixup_task(:deserialize_past($fixup), :fixup_past($fixup));
}

# Creates a meta-object for a package, adds it to the root objects and
Expand Down Expand Up @@ -174,7 +174,7 @@ class NQP::World is HLL::World {
if pir::defined($repr) {
$setup_call.push(PAST::Val.new( :value($repr), :named('repr') ));
}
self.add_event(:deserialize_past(
self.add_fixup_task(:deserialize_past(
self.add_object_to_cur_sc_past($slot, $setup_call)));
}

Expand Down Expand Up @@ -207,7 +207,7 @@ class NQP::World is HLL::World {
$create_call.push($lookup);
}
my $obj_slot_past := self.get_slot_past_for_object($obj);
self.add_event(:deserialize_past(PAST::Op.new(
self.add_fixup_task(:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name('add_attribute'),
PAST::Op.new( :pirop('get_how PP'), $obj_slot_past ),
$obj_slot_past,
Expand Down Expand Up @@ -294,7 +294,7 @@ class NQP::World is HLL::World {
));
# XXX and below bit for deserialization goes away...
my $slot_past := self.get_slot_past_for_object($obj);
self.add_event(
self.add_fixup_task(
:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name($meta_method_name),
PAST::Op.new( :pirop('get_how PP'), $slot_past ),
Expand All @@ -320,7 +320,7 @@ class NQP::World is HLL::World {
my $des := PAST::Op.new( :pirop('set_sub_multisig vPPP'),
PAST::Val.new( :value($routine) ), $types, $definednesses
);
self.add_event(:deserialize_past($des), :fixup_past($fixup));
self.add_fixup_task(:deserialize_past($des), :fixup_past($fixup));
}

# This handles associating the role body with a role declaration.
Expand Down Expand Up @@ -379,7 +379,7 @@ class NQP::World is HLL::World {
PAST::Val.new( :value($body_past) )
);

self.add_event(:deserialize_past($des), :fixup_past($fixups));
self.add_fixup_task(:deserialize_past($des), :fixup_past($fixups));
}

# Adds a parent or role to the meta-object, and stores an event for
Expand All @@ -391,7 +391,7 @@ class NQP::World is HLL::World {
# Emit code to add it when deserializing.
if self.is_precompilation_mode() && !$NEW_SER {
my $slot_past := self.get_slot_past_for_object($obj);
self.add_event(:deserialize_past(PAST::Op.new(
self.add_fixup_task(:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name($meta_method_name),
PAST::Op.new( :pirop('get_how PP'), $slot_past ),
$slot_past,
Expand All @@ -407,7 +407,7 @@ class NQP::World is HLL::World {
# Emit code to add it when deserializing.
if self.is_precompilation_mode() {
my $slot_past := self.get_slot_past_for_object($obj);
self.add_event(:deserialize_past(PAST::Op.new(
self.add_fixup_task(:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name('add_parrot_vtable_handler_mapping'),
PAST::Op.new( :pirop('get_how PP'), $slot_past ),
$slot_past,
Expand All @@ -424,7 +424,7 @@ class NQP::World is HLL::World {
# Emit code to do the composition when deserializing.
if self.is_precompilation_mode() && !$NEW_SER {
my $slot_past := self.get_slot_past_for_object($obj);
self.add_event(:deserialize_past(PAST::Op.new(
self.add_fixup_task(:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name('compose'),
PAST::Op.new( :pirop('get_how PP'), $slot_past ),
$slot_past
Expand All @@ -435,19 +435,12 @@ class NQP::World is HLL::World {
# 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() {
my $des := PAST::Stmts.new();
my $fix := PAST::Stmts.new();
for self.event_stream() {
$des.push(PAST::Stmt.new( $_.deserialize_past() )) if pir::defined($_.deserialize_past());
$fix.push(PAST::Stmt.new( $_.fixup_past() )) if pir::defined($_.fixup_past());
}
make PAST::Op.new(
:pasttype('if'),
PAST::Op.new(
:pirop('isnull IP'),
PAST::Op.new( :pirop('nqp_get_sc Ps'), self.handle() )
),
PAST::Stmts.new(
if self.is_precompilation_mode() {
my $des := PAST::Stmts.new();
for self.fixup_tasks() {
$des.push(PAST::Stmt.new($_));
}
return PAST::Stmts.new(
PAST::Op.new( :pirop('nqp_dynop_setup v') ),
PAST::Op.new( :pirop('nqp_bigint_setup v') ),
PAST::Op.new(
Expand All @@ -470,8 +463,14 @@ class NQP::World is HLL::World {
($NEW_SER ??
self.serialize_and_produce_deserialization_past() !!
PAST::Op.new( :pasttype('null') ))
),
$fix
);
);
}
else {
my $fix := PAST::Stmts.new();
for self.fixup_tasks() {
$fix.push(PAST::Stmt.new($_));
}
return $fix
}
}
}

0 comments on commit ad91b27

Please sign in to comment.