.sub foo :immediate
$I0 = loadlib "XXX"
.end
With this:
.loadlib "XXX"
This might be done as part of vsoni's IMCC refactoring, or as a lexer
action that loads the
library as soon as this directive is seen. In any case, this will
let dependency checkers
have a much easier time to figure out what dynamic libraries a .pir
file is loading, without
actually have to invoke Parrot themselves.
Thanks,
Audrey
Done, r13262.
Actually loading libs matching /ops/ *was* already performed at
compile time. This hack is now removed too.
Thanks for the proposal,
leo
Which leaves us with :immediate for the rare cases when you really want
to load a library at compile time.
Allison
This might not seem totally related (but it is somewhat related)...
The perl6 compiler has a custom string type, currently called
"Perl6Str". What's the canonically correct mechanism for creating
an object of that type?
$P0 = new 'Perl6Str'
$P0 = new .Perl6Str
$P0 = new [ 'Perl6Str' ]
At different stages of Parrot development I've seen different
answers to this question, so it'd be helpful to know what's "correct".
(Also, if the answer is somehow different for Parrot's "built-in"
types, such as Undef or Integer, I'd like to know that.)
Pm
> The perl6 compiler has a custom string type, currently called
> "Perl6Str". What's the canonically correct mechanism for creating
> an object of that type?
>
> $P0 = new 'Perl6Str'
> $P0 = new .Perl6Str
> $P0 = new [ 'Perl6Str' ]
>
> At different stages of Parrot development I've seen different
> answers to this question, so it'd be helpful to know what's "correct".
I tend to use:
.local int str_type
str_type = find_type [ 'Perl6Str' ]
.local pmc p6str
p6str = new str_type
-- c
Well, there was already one very legitimate usage of compile time
loadlib, which is now using C<.loadlib> for that:
.loadlib "opcode_lib"
The library is needed immediately in the compiler to be able to
proceed parsing (e.g. to check the amount and types of freshly loaded
opcodes). There was a crude hack that accomplished this, which is now
removed, because it's cleanly covered by C<.loadlib>.
See also t/dynoplibs/*.t
Another usage of compile time C<.loadlib> could be:
.loadlib "my_pmcs"
...
$P0 = new .MyInt
I.e. some custom PMC loading, w/o defining a HLL language.
There might be other cases, where :init time is early enough, though.
> Allison
leo
=item Class name IDs
... will require a dot in front
$P0 = new Integer => $P0 = new .Integer
according to P6&PE, 2nd edition, PMC variables section (p.188):
Unlike PASM, PIR doesn't use a dot in front of the class name.
P0 = new PerlString # same as new P0, .PerlString
i have no point/counterpoint for the bracketed syntax.
hope that provides some history, context, clarification, or confusion.
~jerry
Along similar lines...
- If another HLL wants to create a Perl6Str, how does it do it?
- If another HLL wants to create a subclass of Perl6Str...?
Pm
Correct are all three, but:
1) and 3) are totally the same
(bracketed syntax just containing a single string constant just
yields that string concstant as a result)
thusly, 3) is containing some syntax overkill :-)
1) works always, but defers the type lookup to runtime. It's a
more efficient version of:
$I0 = find_type 'Perl6Str'
$P0 = new $I0
..., which takes one more opcode dispatch
2) only works, *if* the lib, which defines that type is already
loaded (via :immediate/loadlib or .loadlib), because it's
translated to new_p_ic, i.e. the type name is converted to
a type number at compile time, which speeds up run time
object creation.
A remark WRT:
$P0 = new Integer # bare word 'Integer'
this currently works with a lexer hack (and special code for 'new' IIRC)
but it's deprecated in favour of the much more explicit C<.Integer>,
which is indicating some macroish replacement.
> Pm
leo
AFAIK there is no answer for this at present.
(1) POSSIBLE KLUDGE
In the very short term we could introduce a simple hack that would allow
the user to specify the root namespace for the creation of the new class,
defaulting to the HLL root:
.HLL "evillang"
.sub foo
$P0 = get_hll_namespace # ['evillang']
$P1 = newclass ['Perl6Str'], $P0 # Not a Perl 6 string, but an incredible simulation
...
(2) ELEGANT DIRECTION FOR THE FUTURE
[to be determined]
Seriously: Allison's busy (as am I) with nailing namespaces to the wall, so
I wouldn't ask her to decide this. I do have ... not so much an idea, but
an approach, which I'll suggest when the time comes:
At present, newclass creates a class object and a namespace, both of which
have the same name. That must change once we stop depending on typed
namespaces. Assuming a single namespace object can represent a single class
in future -- which is good for class manipulation and introspection -- I
think we'd want to stop having 'newclass' futz with namespaces at all,
leaving it up to the user to give it a name ... if any. Yes, Virginia,
there are anonymous classes. :-)
So it might look like:
.HLL "evillang"
.sub foo
$P0 = newclass
...
set_hll_global ['Perl6Str'], $P0 # Not a Perl 6 string, but an incredible simulation
...
--
Chip Salzenberg <ch...@pobox.com>
We certainly need both compile-time and runtime loading of libraries.
So, it's just a question of which syntax to use for which case.
chromatic suggests .include for "load this library at compile and run
time". The .include directive is currently being used to mean "inline
the entire source code for this file here". But, I've always thought of
that as a hack we put in before we had library loading working. Any
thoughts?
That would leave us the consistency of the loadlib opcode and the
.loadlib directive both meaning "load this library at runtime".
Allison
> Leopold Toetsch wrote:
>> Well, there was already one very legitimate usage of compile time
>> loadlib, which is now using C<.loadlib> for that:
>
> We certainly need both compile-time and runtime loading of
> libraries. So, it's just a question of which syntax to use for
> which case.
>
> chromatic suggests .include for "load this library at compile and
> run time". The .include directive is currently being used to mean
> "inline the entire source code for this file here". But, I've
> always thought of that as a hack we put in before we had library
> loading working. Any thoughts?
>
I would prefer .include to maintain its current meaning. Not
everything you .include is a complete PIR program.
> That would leave us the consistency of the loadlib opcode and
> the .loadlib directive both meaning "load this library at runtime".
>
How does this relate to leo's previous statement that .loadlib now
does both compile & runtime loads?
> Allison
>
--
Will "Coke" Coleda
wi...@coleda.com
I think I'm confused by or totally misunderstanding the proposal.
I think we have two very different sorts of "library" at play here:
dynamic libraries (with a .so extension on my system), and libraries
of parrot code (with .pir, .pbc, and .pasm extensions).
IIUC, the loadlib opcode (and the new .loadlib directive) are used
strictly for dynamic libraries -- on my system those are files with .so
extensions. loadlib and .loadlib aren't used for .pbc files...
that's the domain of the load_bytecode opcode. load_bytecode can
be used for loading .pbc/.pir files at runtime, at load-time via :load,
or at compile-time with :immediate.
.include is currently compile-time only, and only works with .pir/.pasm
files (i.e., one cannot "include" a .pbc). In addition, any
.included source honors the current .HLL and
.namespace settings, which isn't true for files (.pir/.pbc) that are
obtained via load_bytecode opcode.
So, if the proposal is that ".include" means load a .pbc/.pir library
whenever the including file is compiled or loaded in a manner analogous
to load_bytecode, then I'm still wanting a way to get source files
that are compile-only and honor any .namespace directives.
But as I said, I think I must be misunderstanding what is being said,
so feel free to re-explain or correct my misunderstanding.
Pm
That's a rather complicated :-) way of expressing the one-liner above.
> Along similar lines...
>
> - If another HLL wants to create a Perl6Str, how does it do it?
loadlib 'perl6' # or load_bytecode or whatever
$P0 = new 'Perl6Str'
> - If another HLL wants to create a subclass of Perl6Str...?
loadlib 'perl6' # or load_bytecode or whatever
clas = subclass 'Perl6Str', 'MyStr'
> Pm
leo
On Wed, Jul 12, 2006 at 01:27:24PM -0500, Patrick R. Michaud wrote:
> The perl6 compiler has a custom string type, currently called
> "Perl6Str". What's the canonically correct mechanism for creating
> an object of that type?
>
> $P0 = new 'Perl6Str'
> $P0 = new .Perl6Str
> $P0 = new [ 'Perl6Str' ]
>
> At different stages of Parrot development I've seen different
> answers to this question, so it'd be helpful to know what's "correct".
Correct are all three, but . . .
2) only works, *if* the lib, which defines that type is already
loaded (via :immediate/loadlib or .loadlib), because it's
translated to new_p_ic, i.e. the type name is converted to
a type number at compile time, which speeds up run time
object creation.
So the type is bound to a number in the .pbc? Isn't this dangerous for
types that are not built in? Couldn't this number mean something
different if libraries happen to get loaded in a different order?
-- Bob Rogers
http://rgrjr.dyndns.org/
C<.include> and C<loadlib> are really very different. It's like #include
and dlopen(3) in the C language. But I can see, what is leading to this
argument: loading arbitrary bytecode within .include, which should better
be done with C<load_bytecode>.
This means, we'd have:
.include "file.pasm/.pir" ... load macros or constants (no code)
load_bytecode "file.pbc" ... load a "module"
$P0 = loadlib "file" ... load a shared lib (pmc or ops)
.loadlib "file" ... same during compilation
> That would leave us the consistency of the loadlib opcode and the
> .loadlib directive both meaning "load this library at runtime".
Not really.
> Allison
leo
IIUC, the type is bound to a number in the .pbc only for the second
form (.Perl6Str). And yes, it is dangerous for the non-built-in types,
which is why I think the note in DEPRECATED.pod is likewise dangerous:
=item Class name IDs
... will require a dot in front
$P0 = new Integer => $P0 = new .Integer
AFAICT, the only safe form for the non-builtin types is to use
a string, a key, or the separate find_type lookup...which is what
prompted my original question in this thread about which form
is canonically (and operationally) correct.
Pm
> So the type is bound to a number in the .pbc? Isn't this dangerous for
> types that are not built in? Couldn't this number mean something
> different if libraries happen to get loaded in a different order?
The declaration order of PMC libs is recorded in the HLL_info
structure. When the .pbc is loaded, PMCs are initialized in that
very same order, so that type numbers *should* match in the .pbc
again.
> -- Bob Rogers
leo
I think the most common case at the moment is stitching together .pir
files generated by PGE/TGE. Which is useful.
Allison
Yes, the suggestion is an extreme reuse of existing syntax. Something
that's good to avoid on general design principles.
Allison
I just realized that I misinterpreted these questions. I thought that the
first question was asking how some random HLL can create its own class that
also has the name 'Perl6Str' -- i.e. a name collision question -- and that
the second question was adding on by asking how the new name-collided class
could coexist with (for example, derive from) the original.
I'll be happy to answer the actual questions precisely, but I need to know
more:
Frst: Is this about now or the eventual future? Do you want the answer for
when the full name of Perl6Str is ['parrot';'Perl6Str'], as I think it is
today, or ['perl6';'Perl6Str'], as it should be eventually?
Second: Does the derived class have to be named ['myhll','Perl6Str'], or can
it have a new basename like ['myhll','MyPerl6Str']?
--
Chip Salzenberg <ch...@pobox.com>
The 5 parameters are runtime vs. compile-time, C library vs.
.pasm/.pir/.pbc, and "inline a file".
The .include directive doesn't actually load a library, it just inlines
a file. (The reason it respects .HLL directives and such is not because
it's incredibly smart, but because it's incredibly stupid. If you have
.namespace directive in the inlined file, it will apply that namespace
to any code in the original file that follows the .include directive.) I
like .inline better than .include for this, but I also don't see any
urgent need to change the name of the directive.
I like .loadlib (for C libraries) as long as it's both compile and run
time. That's the most common case of all, and so deserves the best
syntax. And, the loadlib opcode is a clear parallel for the runtime
variant. For the extremely rare case when you want to load a C library
at compile-time but not at runtime, you can still use the loadlib opcode
inside a :immediate sub.
load_bytecode is good for runtime loading of PASM/PIR/PBC. A logical but
unexplored option is compile-time loading of PASM/PIR/PBC. Some things
that are currently being done with .include could be better expressed by
a compile-and-run-time .load_bytecode directive.
Allison
> load_bytecode is good for runtime loading of PASM/PIR/PBC.
Except for the misleading name.
I wonder if there could be a variant that evaluates the code with the
appropriate compiler, too:
load_{something} 'file', 'compiler_name'
load_{something} 'file', compiler_pmc
-- c
Oh, you mean the fact that much of the time it's not loading bytecode at
all? It has crossed my mind, but the irritation hasn't been great enough
to make it worth changing the name of an existing opcode that didn't
otherwise need changing.
> I wonder if there could be a variant that evaluates the code with the
> appropriate compiler, too:
>
> load_{something} 'file', 'compiler_name'
> load_{something} 'file', compiler_pmc
Hmmm... a compile-and-runtime version of that could potentially compile
the source to bytecode at compile-time, and then load the bytecode at
runtime.
Not urgent, but there is long-term potential there.
Allison
On Wed, Jul 12, 2006 at 10:25:43AM -0700, Allison Randal wrote:
Oddly enough, while :init is obviously a good thing, it does not exist.
Yet.
--
Chip Salzenberg <ch...@pobox.com>
However, as discussed briefly at Sunday's hackathon, it would be
really nice if we had some sort of pragma (I propose :init) that
indicates a subroutine is to be executed whenever the sub is loaded,
whether that occurs via a load_bytecode or because a module is
being run directly from parrot.
Background: Currently we have :main, :load, and :immediate pragmas.
A sub marked ":main" is executed when a .pir or .pbc file is called
directly from the parrot command line, but are not automatically
called when that file is obtained via load_bytecode. A sub marked
":load" is executed when a .pir or .pbc file is called via load_bytecode,
but not when the .pir/.pbc is loaded from the command line.
I'd like there to be an :init pragma to mark subs that are to be
executed anytime the file is loaded. In the case of loading from
the command line, the :init subs should be executed prior to the
:main sub.
(Currently the .pir/.pbc files I write work around this by explicitly
calling the :load subs from the :main one. While this is workable
when there's just one such sub, it requires a bit more work when the
.pir or .pbc is being produced from several (often generated) sources.)
Note that :init as I've proposed is not the same as writing
":main :load", since only one :main sub is executed (whereas there could
be multiple :init subs).
Pm
Agreed and approved. I was going to say "approved and added to the
relevant PDD", but there doesn't seem to be a PDD documenting these
subroutine attributes.
Allison
Cool. So noted in http://rt.perl.org/rt3/Ticket/Display.html?id=39926.
> I was going to say "approved and added to the relevant PDD", but there
> doesn't seem to be a PDD documenting these subroutine attributes.
Ah, the PIR pdd rears its nonexistent head again.
--
Chip Salzenberg <ch...@pobox.com>
The :init pragma is intended to make it easier for automatically
generated modules to make sure that initializations are performed
prior to execution of :main.
By way of review -- the :main pragma designates the entry point for
a module when it is given to parrot on the command line. If the
module contains multiple subs marked :main, then the last such sub
is used.
However, sometimes the module given to parrot on the command
line actually comes from several sources, such as when using
pbcmerge, or when a compiler includes automatically generated
files coming from pgc or tgc. These external sources may need
to have various initializations performed prior to executing
:main. The easy way to do this is to allow such external sources
to create subs marked :init that are to be executed prior to
:main. Without something like :init, it then becomes the
responsibility of the :main sub to explicitly call any
needed initialization subs, and given that some of these
initialization subs may be coming from other sources, it's
often difficult to know what should be called.
It's easy to confuse :init with the existing :load pragma,
but as :load is currently written it only executes subs
when a module is loaded via the load_bytecode op. Subs
marked :load are not loaded when a .pbc/.pir file comes
from the parrot command line. While we could conceivably
add the "execute before :main" behavior to the :load
pragma, there may be times when we want to differentiate
"execute as program" from "load as library module", so
having a separate :init pragma would allow us to do that.
Also, previous messages in RT #39926 had indicated
that :init would also designate subs to be executed
when loaded as a module, but today we felt that complete
orthogonality might be better. A sub that needs to be
executed in both situations can simply specify both
pragmas (":init :load").
In ticket #39926 both Allison and Chip have already
given their approval for an :init pragma, so this message
is just a summary of where things stand.
More importantly, it's an invitation for people to contribute
tests and code to bring the :init pragma to life. I know that
several of the compiler authors will greatly benefit from
having it available (which is why it came up in today's
#parrotsketch).
Thanks!
Pm
That's an unfortunate decision. There are load-time flags and run-time flags.
You can just take one of the runtime-flags. I'd propose you use:
SUB_FLAG_TAILCALL = PObj_private2_FLAG, /* runtime usage */
SUB_FLAG_PF_INIT = PObj_private2_FLAG, /* loadtime usage */
A part from that, the patch is looking good to me.
Re:
compilers/imcc/main.c:476: error: ‘INIT’ undeclared (first use in this
function)
this could be a missing dependency or bogus make rule. Does it work after make
realclean?
HTH,
leo
I finally did get flex and bison to run.
Do you thing you could annotate the rest of the flags as to when they
are used?
Kevin
typedef enum {
SUB_FLAG_CORO_FF = PObj_private0_FLAG, /* r */
SUB_FLAG_C_HANDLER = PObj_private0_FLAG, r / C exceptions only
SUB_FLAG_IS_OUTER = PObj_private1_FLAG, c
SUB_FLAG_TAILCALL = PObj_private2_FLAG, r
SUB_FLAG_GENERATOR = PObj_private3_FLAG, r / unused
/* from packfile */
SUB_FLAG_PF_ANON = PObj_private3_FLAG, all c
SUB_FLAG_PF_MAIN = PObj_private4_FLAG,
SUB_FLAG_PF_LOAD = PObj_private5_FLAG,
SUB_FLAG_PF_IMMEDIATE = PObj_private6_FLAG,
SUB_FLAG_PF_POSTCOMP = PObj_private7_FLAG,
leo
Do it.
Allison
forgot to cc the list. See my previous comment.
kjs