Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Separate out things that need to happen (like dependency loading) bef…
…ore we deserialize the SC, and fixups that should happen afterwards.
  • Loading branch information
jnthn committed Feb 13, 2012
1 parent ad91b27 commit 5eab84b
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 36 deletions.
26 changes: 24 additions & 2 deletions src/HLL/World.pm
Expand Up @@ -34,6 +34,11 @@ class HLL::World {
# building deserialization code.
has $!code_ref_blocks;

# List of PAST nodes specifying dependency loading related tasks. These
# are done before the deserialization of the current context, or if in
# immediate run mode before any of the other fixup tasks.
has @!load_dependency_tasks;

# List of PAST nodes specifying fixup tasks, either after deserialization
# or between compile time and run time.
has @!fixup_tasks;
Expand All @@ -58,6 +63,7 @@ class HLL::World {
$!handle := $handle;
%!addr_to_slot := nqp::hash();
@!fixup_tasks := nqp::list();
@!load_dependency_tasks := nqp::list();
$!sc.set_description($description);
$!precomp_mode := %*COMPILING<%?OPTIONS><target> eq 'pir';
$!num_code_refs := 0;
Expand Down Expand Up @@ -147,6 +153,17 @@ class HLL::World {
$!precomp_mode
}

# Add an event that we want to run before deserialization or before any
# other fixup.
method add_load_dependency_task(:$deserialize_past, :$fixup_past) {
if $!precomp_mode {
@!load_dependency_tasks.push($deserialize_past) if $deserialize_past;
}
else {
@!load_dependency_tasks.push($fixup_past) if $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) {
Expand Down Expand Up @@ -209,14 +226,19 @@ class HLL::World {
$!handle
}

# Gets the list of load dependency tasks to do.
method load_dependency_tasks() {
@!load_dependency_tasks
}

# 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
# the deserialization.
method serialize_and_produce_deserialization_past() {
method serialize_and_produce_deserialization_past($sc_reg) {
# Serialize.
my $sh := pir::new__Ps('ResizableStringArray');
my $serialized := pir::nqp_serialize_sc__SPP($!sc, $sh);
Expand Down Expand Up @@ -250,7 +272,7 @@ class HLL::World {
' $S0 = binary:"' ~ pir::escape__SS($serialized) ~ '"',
' %r = box $S0'
) ),
PAST::Op.new( :pirop('nqp_create_sc Ps'), 'XXX-' ~ $!handle ),
PAST::Var.new( :name($sc_reg), :scope('register') ),
$sh_past, $cr_past)
}
}
6 changes: 4 additions & 2 deletions src/ModuleLoader.pm
Expand Up @@ -40,7 +40,7 @@ knowhow ModuleLoader {
$*CTXSAVE := 0;
}

method load_module($module_name, $cur_GLOBALish) {
method load_module($module_name, *@global_merge_target) {
# If we didn't already do so, load the module and capture
# its mainline. Otherwise, we already loaded it so go on
# with what we already have.
Expand Down Expand Up @@ -70,7 +70,9 @@ knowhow ModuleLoader {
# Merge any globals.
my $UNIT := pir::getattribute__PPs($module_ctx, 'lex_pad');
unless pir::isnull($UNIT<GLOBALish>) {
merge_globals($cur_GLOBALish, $UNIT<GLOBALish>);
if +@global_merge_target {
merge_globals(@global_merge_target[0], $UNIT<GLOBALish>);
}
}
}

Expand Down
103 changes: 71 additions & 32 deletions src/NQP/World.pm
Expand Up @@ -21,20 +21,38 @@ class NQP::World is HLL::World {

# Do load for pre-compiled situation.
if self.is_precompilation_mode() {
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
PAST::Op.new(
:pasttype('callmethod'), :name('set_outer_ctx'),
PAST::Var.new( :name('block'), :scope('register') ),
PAST::Op.new(
:pasttype('callmethod'), :name('load_setting'),
PAST::Var.new( :name('ModuleLoader'), :namespace([]), :scope('package') ),
$setting_name
)
)
)));
if $NEW_SER {
self.add_load_dependency_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
PAST::Op.new(
:pasttype('callmethod'), :name('set_outer_ctx'),
PAST::Var.new( :name('block'), :scope('register') ),
PAST::Op.new(
:pasttype('callmethod'), :name('load_setting'),
PAST::Var.new( :name('ModuleLoader'), :namespace([]), :scope('package') ),
$setting_name
)
)
)));
}
else {
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
PAST::Op.new(
:pasttype('callmethod'), :name('set_outer_ctx'),
PAST::Var.new( :name('block'), :scope('register') ),
PAST::Op.new(
:pasttype('callmethod'), :name('load_setting'),
PAST::Var.new( :name('ModuleLoader'), :namespace([]), :scope('package') ),
$setting_name
)
)
)));
}
}
else {
# Needs fixup.
Expand All @@ -61,16 +79,29 @@ class NQP::World is HLL::World {

# Make sure we do the loading during deserialization.
if self.is_precompilation_mode() {
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
PAST::Op.new(
:pasttype('callmethod'), :name('load_module'),
PAST::Var.new( :name('ModuleLoader'), :namespace([]), :scope('package') ),
$module_name,
self.get_slot_past_for_object($cur_GLOBALish)
))));
if $NEW_SER {
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
PAST::Op.new(
:pasttype('callmethod'), :name('load_module'),
PAST::Var.new( :name('ModuleLoader'), :namespace([]), :scope('package') ),
$module_name
))));
}
else {
self.add_fixup_task(:deserialize_past(PAST::Stmts.new(
PAST::Op.new(
:pirop('load_bytecode vs'), 'ModuleLoader.pbc'
),
PAST::Op.new(
:pasttype('callmethod'), :name('load_module'),
PAST::Var.new( :name('ModuleLoader'), :namespace([]), :scope('package') ),
$module_name,
self.get_slot_past_for_object($cur_GLOBALish)
))));
}
}

return pir::getattribute__PPs($module, 'lex_pad');
Expand Down Expand Up @@ -436,9 +467,13 @@ class NQP::World is HLL::World {
# it doesn't exist, and fix it up if it already does.
method to_past() {
if self.is_precompilation_mode() {
my $des := PAST::Stmts.new();
my $load_tasks := PAST::Stmts.new();
for self.load_dependency_tasks() {
$load_tasks.push(PAST::Stmt.new($_));
}
my $fixup_tasks := PAST::Stmts.new();
for self.fixup_tasks() {
$des.push(PAST::Stmt.new($_));
$fixup_tasks.push(PAST::Stmt.new($_));
}
return PAST::Stmts.new(
PAST::Op.new( :pirop('nqp_dynop_setup v') ),
Expand All @@ -459,18 +494,22 @@ class NQP::World is HLL::World {
PAST::Var.new( :name('cur_sc'), :scope('register') ),
self.sc.description
),
$des,
$load_tasks,
($NEW_SER ??
self.serialize_and_produce_deserialization_past() !!
PAST::Op.new( :pasttype('null') ))
self.serialize_and_produce_deserialization_past('cur_sc') !!
PAST::Op.new( :pasttype('null') )),
$fixup_tasks
);
}
else {
my $fix := PAST::Stmts.new();
my $tasks := PAST::Stmts.new();
for self.load_dependency_tasks() {
$tasks.push(PAST::Stmt.new($_));
}
for self.fixup_tasks() {
$fix.push(PAST::Stmt.new($_));
$tasks.push(PAST::Stmt.new($_));
}
return $fix
return $tasks
}
}
}

0 comments on commit 5eab84b

Please sign in to comment.