Skip to content

Commit

Permalink
Basic implementation of NQP dispatchers
Browse files Browse the repository at this point in the history
For now, these don't take care of NQP's multiple dispatch.
  • Loading branch information
jnthn committed Jun 23, 2021
1 parent d2c3437 commit ef939e0
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/core/NQPMu.nqp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ my class NQPMu {
}
}

# A few bits when we're bootstrapping everything 6model-style
# An NQP array, which is the standard array representation with a few methods
# added.
my class NQPArray is repr('VMArray') {
method push($value) { nqp::push(self, $value) }
method pop() { nqp::pop(self) }
Expand All @@ -107,6 +108,8 @@ my class NQPArray is repr('VMArray') {
}
nqp::setboolspec(NQPArray, 8, nqp::null());
nqp::settypehllrole(NQPArray, 4);

# Iterator types.
my class NQPArrayIter is repr('VMIter') { }
nqp::setboolspec(NQPArrayIter, 7, nqp::null());
my class NQPHashIter is repr('VMIter') {
Expand All @@ -115,6 +118,8 @@ my class NQPHashIter is repr('VMIter') {
method Str() { nqp::iterkey_s(self) }
}
nqp::setboolspec(NQPHashIter, 7, nqp::null());

# NQP HLL configuration.
nqp::sethllconfig('nqp', nqp::hash(
'list', NQPArray,
'slurpy_array', NQPArray,
Expand All @@ -124,6 +129,10 @@ nqp::sethllconfig('nqp', nqp::hash(
# BOOTHashes don't actually need transformation
nqp::ishash($hash) ?? $hash !! $hash.FLATTENABLE_HASH
},
#?if moar
'call_dispatcher', 'nqp-call',
'call_method_dispatcher', 'nqp-meth-call',
#?endif
));

my class NQPLabel { }
66 changes: 66 additions & 0 deletions src/core/dispatchers.nqp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#?if moar
nqp::dispatch('boot-syscall', 'dispatcher-register', 'nqp-meth-call', -> $capture {
# Try to find the method; complain if there's none found.
my $obj := nqp::captureposarg($capture, 0);
my str $name := nqp::captureposarg_s($capture, 1);
my $meth := $obj.HOW.find_method($obj, $name);
unless nqp::isconcrete($meth) {
nqp::die("Method '$name' not found for invocant of class '{$obj.HOW.name($obj)}'");
}

# Establish a guard on the invocant type and method name (however the name
# may well be a literal, in which case this is free).
nqp::dispatch('boot-syscall', 'dispatcher-guard-type',
nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0));
nqp::dispatch('boot-syscall', 'dispatcher-guard-literal',
nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1));

# Drop the first two arguments, which are the decontainerized invocant
# and the method name. Then insert the resolved method and delegate to
# nqp-call to invoke it.
my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg',
nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0),
0);
my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj',
$args, 0, $meth);
nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'nqp-call', $delegate);
});

nqp::dispatch('boot-syscall', 'dispatcher-register', 'nqp-call', -> $capture {
# Guard on the type of the callee.
my $track-callee := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0);
nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-callee);

# Go by callee type to decide how to invoke it.
my $callee := nqp::captureposarg($capture, 0);
if nqp::istype($callee, NQPRoutine) {
# Routine, maybe multi.
# TODO multi
my $track-do := nqp::dispatch('boot-syscall', 'dispatcher-track-attr',
$track-callee, NQPRoutine, '$!do');
my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0);
my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg',
$args, 0, $track-do);
nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant',
$delegate);
}
elsif nqp::istype($callee, NQPRegex) {
# Regex, just unwrap the code handle and delegate.
my $track-do := nqp::dispatch('boot-syscall', 'dispatcher-track-attr',
$track-callee, NQPRegex, '$!do');
my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0);
my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg',
$args, 0, $track-do);
nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant',
$delegate);
}
elsif nqp::iscoderef($callee) {
# VM-level code handle.
nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant',
$capture);
}
else {
nqp::die("Cannot invoke object of type '{$callee.HOW.name($callee)}'");
}
});
#?endif
1 change: 1 addition & 0 deletions tools/templates/Makefile-common.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ CORE_SETTING_SOURCES = \
@nfp(src/core/Hash.nqp)@ \
@nfp(src/core/NQPLock.nqp)@ \
@nfp(src/core/testing.nqp)@ \
@nfp(src/core/dispatchers.nqp)@ \
@nfp(src/core/YOUAREHERE.nqp)@ \

CORE_SETTING_COMBINED = NQPCORE.setting
Expand Down

0 comments on commit ef939e0

Please sign in to comment.