Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Supporting safe managed references

0 views
Skip to first unread message

Jonathan Worthington

unread,
Jan 23, 2006, 7:11:14 PM1/23/06
to perl6-i...@perl.org
Hi,

A while back I announced that I was working on a .NET to PIR translator for
my final year project at uni. In case you've ever pondered how well it's
doing, and you don't read Planet Parrot or my blog, the answer is "pretty
well". So far I'm successfully translating:

* Parameters
* Local variables
* Arithemtic and logical ops
* Int/float type conversion
* Checked arithmetic and conversion ops
* Conditional ops and branches
* Non-static method calling, virtual method calling and field access for
classes in the same assembly
* Instructions relating to arrays
* Object instantiation, kinda, but missing the all important constructor
call

Which brings me to about 140 of the 215 instructions there are to translate.
Anyway, onto the real point of the email.

.NET has these managed reference thingies. They're basically like pointers,
but safe. What makes them safe is that only certain instructions can create
them and the pointer value can't be set directly (we can do that fine - just
have a PMC with an underlying struct that hold the pointer, but provide no
PMC methods that set that pointer).

Making them work on Parrot is no problem. Making them work without
comprimising the safety of the VM is harder. Amongst the things you can get
a pointer to are parameters and local variables. Under .NET that means
stack locations; with Parrot that means registers. So, imagine this.

1) Get reference to local in the current method
2) Stash that reference somewhere so it lasts longer than the current
method's context does, or just return it
3) Assigns to that reference later => BANG! Segfault, or perhaps controlled
scribbling to evade security policies etc

Under .NET we have info to track statically where managed references go so
we can do escape analysis before ever running the code to check it is safe
to run. A .NET VM can implement this just fine. However, on Parrot we
can't do this - statically we only know that a P register could hold any old
PMC.

Some discussion on IRC later, leo had come up with two suggestions for
handling this.

1) A two part solution.

a) Make set an MMD operation. This way, a .NET managed reference PMC knows
when it may be about to escape and can say "hey, this ain't allowed" in an
exceptionesque kinda way.

b) Add a v-table flag saying "returning me is forbidden" and checking that
on any PMCs that get returned. (However, there are subtle issues. For
example, we want to be able to pass the PMC to methods that are called from
this one - after all, it's how byref passing is implemented. But with tail
calls we should probably not do it. Also haven't yet pondered if closures
or co-routines may lead to some kinda leakage.)

2) Add a new Reference register type. We have INSP, so we'd also have R too
(perhaps). R registers would only have a very limited set of possible
operations that could be performed on them; not being able to return them
would be one of these. They shouldn't cause an opcode explosion as you
won't be able to do that much with them, so few ops that exist now would be
useful to act upon them. Obviously, you wouldn't be able to assign just any
address to them either. They should be useful beyond running .NET code too.
Of course, adding these would require some effort.

Maybe someone has an idea for a better way. Anyhow, that's the problem and
the ideas so far. Comments and suggestions very welcome.

Thanks,

Jonathan

Chip Salzenberg

unread,
Jan 24, 2006, 1:16:54 AM1/24/06
to Jonathan Worthington, perl6-i...@perl.org
On Tue, Jan 24, 2006 at 12:11:14AM -0000, Jonathan Worthington wrote:
> .NET has these managed reference thingies. They're basically like
> pointers, but safe. [...]

>
> Making them work on Parrot is no problem. Making them work without
> comprimising the safety of the VM is harder. Amongst the things you can
> get a pointer to are parameters and local variables. Under .NET that means
> stack locations; with Parrot that means registers.

Indeed, and yet pointing to registers is not as fatal as you might
imagine, nor does it require restructuring the VM by e.g. adding a
register type.

The trick is to keep references to registers in a way that notices
when the register set is gone, or alternatively, that keeps the
register set from going away. The latter is already achieved by the
default LexPad implementation.

Therefore, the representation of a safe pointer to a register would
not, in fact, be a pointer to the register's storage in memory, but
rather a weak reference (or, conceivably, a strong one? I doubt it)
plus an integer register number.

Is a pointer to a register the only tough case?

And in what way is this different from the Reference type we're going
to have to make work just for e.g. the Perl backslash operator?

(Actually, I'm still a little fuzzy on actual usage patterns for this
kind of thing. Otherwise I'd probably know those answers.)
--
Chip Salzenberg <ch...@pobox.com>

Nicholas Clark

unread,
Jan 24, 2006, 4:38:45 AM1/24/06
to Jonathan Worthington, perl6-i...@perl.org
On Tue, Jan 24, 2006 at 12:11:14AM -0000, Jonathan Worthington wrote:

> .NET has these managed reference thingies. They're basically like

> b) Add a v-table flag saying "returning me is forbidden" and checking that
> on any PMCs that get returned. (However, there are subtle issues. For
> example, we want to be able to pass the PMC to methods that are called from
> this one - after all, it's how byref passing is implemented. But with tail
> calls we should probably not do it. Also haven't yet pondered if closures
> or co-routines may lead to some kinda leakage.)

I don't think that this is going to work. You can bypass the check on
returning one of these merely by assigning it into an aggregate that was
passed in by reference. Neither the managed reference PMC nor the aggregate
is returned, yet the managed reference outlives the function and is
accessible.

Nicholas Clark

Jonathan Worthington

unread,
Jan 24, 2006, 8:04:10 AM1/24/06
to Nicholas Clark, perl6-i...@perl.org
"Nicholas Clark" <ni...@ccl4.org> wrote:
> On Tue, Jan 24, 2006 at 12:11:14AM -0000, Jonathan Worthington wrote:
>
>> .NET has these managed reference thingies. They're basically like
>
>
>> b) Add a v-table flag saying "returning me is forbidden" and checking
>> that
>> on any PMCs that get returned. (However, there are subtle issues. For
>> example, we want to be able to pass the PMC to methods that are called
>> from
>> this one - after all, it's how byref passing is implemented. But with
>> tail
>> calls we should probably not do it. Also haven't yet pondered if
>> closures
>> or co-routines may lead to some kinda leakage.)
>
> I don't think that this is going to work. You can bypass the check on
> returning one of these merely by assigning it into an aggregate
Ah. This was the purpose of part (a) - to make sure we can't assign the
reference to an aggregate (the .NET spec forbids storing a managed reference
in "elements of arrays or fields of objects or value types"). Though I
explicitly said make set MMD and forgot to mention (as leo had commented on
IRC) that you'd need to do it for keyed sets too, so my fault for the
confusion - sorry.

Looking at what Chip said though, it would appear that the much cleaner
solution I was hoping to find exists and can be found in lex pad stuff,
which I need to go stare at for a bit before replying. :-)

Thanks,

Jonathan

Paolo Molaro

unread,
Jan 24, 2006, 10:00:18 AM1/24/06
to perl6-i...@perl.org
On 01/24/06 Jonathan Worthington wrote:
> .NET has these managed reference thingies. They're basically like

They are called managed pointers.

> pointers, but safe. What makes them safe is that only certain instructions
> can create them and the pointer value can't be set directly (we can do that
> fine - just have a PMC with an underlying struct that hold the pointer, but
> provide no PMC methods that set that pointer).

The value of the managed pointers can of course change (you can store
managed pointers to local variables...). This happens also when you
restrict your implementation to verifiable code.

> Making them work on Parrot is no problem. Making them work without
> comprimising the safety of the VM is harder. Amongst the things you can

I think you're approaching this from the wrong side. The IL bytecode is
checked for correctness and verifiability during translation and this is
completely independent on the VM that executes the translated code.
Assuming you don't introduce bugs in the translation and the VM works
correctly, after translation the code won't compromise the VM.

> get a pointer to are parameters and local variables. Under .NET that means
> stack locations; with Parrot that means registers. So, imagine this.

Well, you'll need a stack in parrot, too, or performance will be
orrible. It's still not clear to me if your effort is supposed to build
a practical system or just a proof of concept, though. If you restrict
yourself to a subset of verifiable ops and don't care about speed, any
approach will work;-)

> 1) A two part solution.
>
> a) Make set an MMD operation. This way, a .NET managed reference PMC knows

[...]


> b) Add a v-table flag saying "returning me is forbidden" and checking that

[...]


> 2) Add a new Reference register type. We have INSP, so we'd also have R

[...]


> Maybe someone has an idea for a better way. Anyhow, that's the problem and
> the ideas so far. Comments and suggestions very welcome.

I think the only sane solution is to make sure that the integer
registers are at least pointer-sized and use them to store managed
pointers (not sure if this is possible with parrot: some time back there
was the policy of allowing to configure the size of int regs, so
making a build provide different semantics than another one...).

The only caveat is that you'll need to check those registers during GC.

BTW, from a quick look at your interesting blog:
"the arrays as supported by the VM are fixed length and can only contain
elements of a single type. One reading of the specification hints that
they are always object types, so a FixedPMCArray would do fine for any
array."

Arrays have an element type and all the elements will be of that type.
The element type can be almost any type, though, so not only objects,
but also bytes, integers etc.
Also, if you care about the details: both arrays and strings must be
allocated in a single amount chunk of memory (but see above: with a
subset, non-pratical system you can ignore this).

lupus

--
-----------------------------------------------------------------
lu...@debian.org debian/rules
lu...@ximian.com Monkeys do it better

Jonathan Worthington

unread,
Jan 24, 2006, 10:52:39 AM1/24/06
to Chip Salzenberg, perl6-i...@perl.org
"Chip Salzenberg" <ch...@pobox.com> wrote:
> On Tue, Jan 24, 2006 at 12:11:14AM -0000, Jonathan Worthington wrote:
>> .NET has these managed reference thingies. They're basically like
>> pointers, but safe. [...]
>>
>> Making them work on Parrot is no problem. Making them work without
>> comprimising the safety of the VM is harder. Amongst the things you can
>> get a pointer to are parameters and local variables. Under .NET that
>> means
>> stack locations; with Parrot that means registers.
>
> Indeed, and yet pointing to registers is not as fatal as you might
> imagine, nor does it require restructuring the VM by e.g. adding a
> register type.
>
This is good news, and the kinda solution I was hoping for. :-)

> The trick is to keep references to registers in a way that notices
> when the register set is gone, or alternatively, that keeps the
> register set from going away. The latter is already achieved by the
> default LexPad implementation.
>

Looking at it, I kinda see where you're coming from, but just stashing away
and ensuring a LexPad PMC gets marked for a long as the reference gets
marked is not enough, as a LexPad PMC doesn't control lifetime of a context
structure, which is responsible for the registers. OTOH, taking a closure
does keep the context and thus register frame in place, which is perhaps
what you meant and seems workable.

> Therefore, the representation of a safe pointer to a register would
> not, in fact, be a pointer to the register's storage in memory, but
> rather a weak reference (or, conceivably, a strong one? I doubt it)
> plus an integer register number.

A weak reference to the closure PMC, I assume? I think we don't have weak
references yet though, but that can be fixed up in the future. Ah, and the
reference might not be to an integer register, but that's just detail...

> Is a pointer to a register the only tough case?
>

Other cases are pointer to an array element and pointer to a field.
However, I really don't want to be messing around with referencing into
memory managed by the PMC that could move, so the plan is that the managed
reference PMC will hold a reference to the array PMC plus the element number
(or object PMC and field name). Yes, performance will not be amazing, but
that ain't really the goal.

> And in what way is this different from the Reference type we're going
> to have to make work just for e.g. the Perl backslash operator?
>

Probably not much, apart from that I'd like it to work now. ;-)

Many thanks,

Jonathan

Jonathan Worthington

unread,
Jan 24, 2006, 11:46:28 AM1/24/06
to Paolo Molaro, perl6-i...@perl.org
"Paolo Molaro" <lu...@debian.org> wrote:
> On 01/24/06 Jonathan Worthington wrote:
>> .NET has these managed reference thingies. They're basically like
>
> They are called managed pointers.
>
Yes. And now I've misled Parrot folks into mis-naming them managed
references. D'oh.

>> pointers, but safe. What makes them safe is that only certain
>> instructions
>> can create them and the pointer value can't be set directly (we can do
>> that
>> fine - just have a PMC with an underlying struct that hold the pointer,
>> but
>> provide no PMC methods that set that pointer).
>
> The value of the managed pointers can of course change (you can store
> managed pointers to local variables...). This happens also when you
> restrict your implementation to verifiable code.
>

Yes, I am restricting my implementation to verifiable code. When I said the
value of a managed pointer I meant the address where it points, not the
value it points at - of course the many stind operations change the value it
points at. But I can't see where in the spec where the address can be
changed in verifiable code - have I missed something?

>> Making them work on Parrot is no problem. Making them work without
>> comprimising the safety of the VM is harder. Amongst the things you can
>
> I think you're approaching this from the wrong side. The IL bytecode is
> checked for correctness and verifiability during translation and this is
> completely independent on the VM that executes the translated code.
> Assuming you don't introduce bugs in the translation and the VM works
> correctly, after translation the code won't compromise the VM.
>

Translating .NET bytecode to Parrot bytecode isn't so cheap that you'd want
to do it "on the fly", so translation can be done ahead of time. This takes
in a .NET exe or dll and spits out a Parrot bytecode file. But my concern
isn't really code that has been through the translator, it's the potential
for malicious code to be able to use what exists to support managed pointers
to corrupt the state of Parrot. We don't really have any concept of
verification in Parrot, plus lack the knowledge to be able to do some kind
of static analysis (there's no distinct pointer type).

>> get a pointer to are parameters and local variables. Under .NET that
>> means
>> stack locations; with Parrot that means registers. So, imagine this.
>
> Well, you'll need a stack in parrot, too, or performance will be
> orrible.

How so? My translator maps the stack onto a set of registers, just like a
JIT compiler would. Only difference is they're software registers, not
hardware ones. As for parameters passing, Parrot uses CPS, though it does
build up a kinda "stack" of contexts. I'm translating calls so they use the
standard Parrot calling conventions though.

> It's still not clear to me if your effort is supposed to build
> a practical system or just a proof of concept, though. If you restrict
> yourself to a subset of verifiable ops and don't care about speed, any
> approach will work;-)
>

Well, at the moment the effort is to give me something to write a
dissertation about to submit for my degree. ;-) Long term I'd like to make
this usable and be able to run verifiable code. The point wouldn't really
be for anyone to use Parrot to run an entire .NET app on - they'd do much
better with Mono or the MS implementation. It's more along the lines of "I
have this library that's written in a .NET language, I'd like to use it from
my Perl 6 program" - where the point isn't so much performance any more, but
interoperability. Bytecode translation is only one way to achieve this, but
happens to be the one I chose to play with.

> I think the only sane solution is to make sure that the integer
> registers are at least pointer-sized and use them to store managed
> pointers (not sure if this is possible with parrot: some time back there
> was the policy of allowing to configure the size of int regs, so
> making a build provide different semantics than another one...).
>
> The only caveat is that you'll need to check those registers during GC.
>

Issue here is that there is no way to know which integer registers are
pointers and which are not, and therefore no way to restrict what can be
done to them. Much easier is making a managed pointer PMC which in turn
holds the pointer. This will get marked by GC already and we can control
what operations are allowed on them. No, the performance won't be amazing,
but see above.

> BTW, from a quick look at your interesting blog:
> "the arrays as supported by the VM are fixed length and can only contain
> elements of a single type. One reading of the specification hints that
> they are always object types, so a FixedPMCArray would do fine for any
> array."
>
> Arrays have an element type and all the elements will be of that type.
> The element type can be almost any type, though, so not only objects,
> but also bytes, integers etc.

Yes, I realized this later on - thanks for noting though. I am currently
using a ParrotIntegerArray and ParrotFloatArray for integer and floating
point types respectively, but can make that more efficient later. I suspect
Parrot will have PMCs for byte and short integer arrays respectively.

> Also, if you care about the details: both arrays and strings must be
> allocated in a single amount chunk of memory (but see above: with a
> subset, non-pratical system you can ignore this).
>

I think this holds with the default Parrot implementations of strings and
arrays; if not I can always implement PMCs where the behaviour is like this.

Thanks very much for your input,

Jonathan

Larry Wall

unread,
Jan 24, 2006, 12:19:48 PM1/24/06
to perl6-i...@perl.org
On Tue, Jan 24, 2006 at 01:04:10PM -0000, Jonathan Worthington wrote:
: Looking at what Chip said though, it would appear that the much cleaner
: solution I was hoping to find exists and can be found in lex pad stuff,
: which I need to go stare at for a bit before replying. :-)

This is tangentially related, but we might need to think about
something like typed references in any event to enable various forms
of round-trip language interoperability. That is, we could have
references that are polymorphic depending on language context,
so that different behaviors can be emulated depending on which
facilities are native to the language and which are "borrowed" from
some other language. Think of something which is simultaneously a
P5 and a P6 object. Or pick any other pair/set of languages.

Then again, if we can get away without such a facility, that's okay too.

Larry

Chip Salzenberg

unread,
Jan 24, 2006, 1:31:50 PM1/24/06
to Jonathan Worthington, perl6-i...@perl.org
On Tue, Jan 24, 2006 at 03:52:39PM -0000, Jonathan Worthington wrote:
> "Chip Salzenberg" <ch...@pobox.com> wrote:
> >The trick is to keep references to registers in a way that notices
> >when the register set is gone, or alternatively, that keeps the
> >register set from going away. The latter is already achieved by the
> >default LexPad implementation.
>
> Looking at it, I kinda see where you're coming from, but just stashing away
> and ensuring a LexPad PMC gets marked for a long as the reference gets
> marked is not enough, as a LexPad PMC doesn't control lifetime of a context
> structure, which is responsible for the registers. OTOH, taking a closure
> does keep the context and thus register frame in place, which is perhaps
> what you meant and seems workable.

That's a clever idea, creating a closure, but closures can't achieve any
kind of weak reference. They never want to let go of their context. So
that's a non-starter.

What I had in mind, was imitating whatever a closure does to hold onto a
context chain. I would detail that here except it's not on the top of my
brain except (1) the point is the imitation-rather-than-usage strategy,
and (2) it won't work anyway, also due to the need for a weak reference.

> >Therefore, the representation of a safe pointer to a register would
> >not, in fact, be a pointer to the register's storage in memory, but
> >rather a weak reference (or, conceivably, a strong one? I doubt it)
> >plus an integer register number.
>
> A weak reference to the closure PMC, I assume?

Well, what I meant at the time was a weak reference to the context, so
when the context evaporates on its own, you can be notified. But since
contexts aren't actually GC-able yet that's pretty much impossible now.

To get what you want, you may have to introduce cheap-ass pseudo-GC
pseudo-weak-reference mechanism for contexts. For example, a list of
callbacks attached to contexts that are to be called when the context's
refcount hits zero.

I'd prefer to reuse something in the engine already for those callbacks.
If a lightweight callback mechanism, with parameter, doesn't already
exist, then you could either use a closure for -that- (eh, too expensive)
or else invent such a mechanism for general use, with yourself as first
customer.

> Ah, and the reference might not be to an integer register, but that's
> just detail...

I imagined that the references would only ever be to -PMC- registers...?

> ... the managed reference PMC will hold a reference to the array PMC


> plus the element number (or object PMC and field name). Yes,
> performance will not be amazing, but that ain't really the goal.

That's a good approach, as far as it goes. Given the amazing variety of
"array" PMCs you can't possibly guarantee that there will be a memory
address there to use, even without movement issues.

But a .Net-specific solution seems unworthy. .Net translation isn't
nearly the only code that will want mutable pseudo-references to aggregate
elements. Seems to me that aggregates should have vtable methods to
create such, with the possibility of specializing. For example, a mutable
proxy object for %ENV{$foo} would not bother with hash manipulation; it
would just call getenv() and setenv().
--
Chip Salzenberg <ch...@pobox.com>

Chip Salzenberg

unread,
Jan 24, 2006, 1:39:28 PM1/24/06
to Jonathan Worthington, perl6-i...@perl.org
jeepers I mangled this paragraph

On Tue, Jan 24, 2006 at 10:31:50AM -0800, Chip Salzenberg wrote:
> What I had in mind, was imitating whatever a closure does to hold onto a
> context chain. I would detail that here except it's not on the top of my
> brain except (1) the point is the imitation-rather-than-usage strategy,
> and (2) it won't work anyway, also due to the need for a weak reference.

Let's try again:

What I had in mind, was imitating whatever a closure does to hold onto a

context chain. I would detail that here except (1) it's not on the top of
my brain, (2) the point is the imitation-rather-than-usage -strategy-,
and (3) it won't work anyway, also due to the need for a weak reference.
--
Chip Salzenberg <ch...@pobox.com>

Jonathan Worthington

unread,
Jan 24, 2006, 3:49:55 PM1/24/06
to Chip Salzenberg, perl6-i...@perl.org
"Chip Salzenberg" <ch...@pobox.com> wrote:
> On Tue, Jan 24, 2006 at 03:52:39PM -0000, Jonathan Worthington wrote:
>> "Chip Salzenberg" <ch...@pobox.com> wrote:
>> >The trick is to keep references to registers in a way that notices
>> >when the register set is gone, or alternatively, that keeps the
>> >register set from going away. The latter is already achieved by the
>> >default LexPad implementation.
>>
>> Looking at it, I kinda see where you're coming from, but just stashing
>> away
>> and ensuring a LexPad PMC gets marked for a long as the reference gets
>> marked is not enough, as a LexPad PMC doesn't control lifetime of a
>> context
>> structure, which is responsible for the registers. OTOH, taking a
>> closure
>> does keep the context and thus register frame in place, which is perhaps
>> what you meant and seems workable.
>
> That's a clever idea, creating a closure, but closures can't achieve any
> kind of weak reference. They never want to let go of their context. So
> that's a non-starter.
>
<speaking in terms of making my project basically work for now>
Yes, though it gets freed when the closure PMC is no longer reachable. And
the point is that a managed pointer PMC pointing to a register *should*
always become unreachable by the end of the execution of the sub it was
created in. Though it did occur to me that my managed pointer PMC can
increment the context's ref count on creation, decrement it on destruction
and thus no need for the closure.

<speaking in terms of what's good for Parrot/my project in the long term>
No, it's not a good solution and nor is the "optimization" I suggested.

> What I had in mind, was imitating whatever a closure does to hold onto a
> context chain. I would detail that here except it's not on the top of my
> brain except (1) the point is the imitation-rather-than-usage strategy,
> and (2) it won't work anyway, also due to the need for a weak reference.
>
>> >Therefore, the representation of a safe pointer to a register would
>> >not, in fact, be a pointer to the register's storage in memory, but
>> >rather a weak reference (or, conceivably, a strong one? I doubt it)
>> >plus an integer register number.
>>
>> A weak reference to the closure PMC, I assume?
>
> Well, what I meant at the time was a weak reference to the context, so
> when the context evaporates on its own, you can be notified. But since
> contexts aren't actually GC-able yet that's pretty much impossible now.
>
> To get what you want, you may have to introduce cheap-ass pseudo-GC
> pseudo-weak-reference mechanism for contexts. For example, a list of
> callbacks attached to contexts that are to be called when the context's
> refcount hits zero.
>
> I'd prefer to reuse something in the engine already for those callbacks.
> If a lightweight callback mechanism, with parameter, doesn't already
> exist, then you could either use a closure for -that- (eh, too expensive)
> or else invent such a mechanism for general use, with yourself as first
> customer.
>

There is a mechanism used to do this kinda thing for exit handlers
(src/exit.c), but it doesn't look particularly general. I guess leo will
know if there is something I've missed - leo, thoughts? I guess such a
mechanism probably shouldn't be much work to implement, though, and would
certainly be a nice, clean answer.

>> Ah, and the reference might not be to an integer register, but that's
>> just detail...
>
> I imagined that the references would only ever be to -PMC- registers...?
>

I wouldn't have thought so. I thought in Perl 6 the lowercased types like
"int" were to go in the I registers. I think we'd still want to be able to
create a reference to them though. In the .NET case, there's no reason not
to use I registers for its integers. I guess they could all be PMCs, but
that'd be kinda expensive.

>> ... the managed reference PMC will hold a reference to the array PMC
>> plus the element number (or object PMC and field name). Yes,
>> performance will not be amazing, but that ain't really the goal.
>
> That's a good approach, as far as it goes. Given the amazing variety of
> "array" PMCs you can't possibly guarantee that there will be a memory
> address there to use, even without movement issues.
>

Yes, there's no external interface to get one.

> But a .Net-specific solution seems unworthy. .Net translation isn't
> nearly the only code that will want mutable pseudo-references to aggregate
> elements. Seems to me that aggregates should have vtable methods to
> create such, with the possibility of specializing. For example, a mutable
> proxy object for %ENV{$foo} would not bother with hash manipulation; it
> would just call getenv() and setenv().

In the long term, yes this would be very nice. In the short term, I've got
a project that comes complete with a deadline, so the I'm afraid the .Net
specific one will have to be the way it is for now. Not that it affects
Parrot really, or at least until my code goes public and people start
thinking it shows good ways to do stuff. :-)

Thanks,

Jonathan

Chip Salzenberg

unread,
Jan 24, 2006, 4:02:21 PM1/24/06
to Jonathan Worthington, perl6-i...@perl.org
On Tue, Jan 24, 2006 at 08:49:55PM -0000, Jonathan Worthington wrote:
> "Chip Salzenberg" <ch...@pobox.com> wrote:
> >I'd prefer to reuse something in the engine already for those callbacks.
> >If a lightweight callback mechanism, with parameter, doesn't already
> >exist, then you could either use a closure for -that- (eh, too expensive)
> >or else invent such a mechanism for general use, with yourself as first
> >customer.
>
> There is a mechanism used to do this kinda thing for exit handlers
> (src/exit.c), but it doesn't look particularly general. I guess leo will
> know if there is something I've missed - leo, thoughts? I guess such a
> mechanism probably shouldn't be much work to implement, though, and would
> certainly be a nice, clean answer.

Words I love to hear. Er, read.

> >I imagined that the references would only ever be to -PMC- registers...?
>
> I wouldn't have thought so. I thought in Perl 6 the lowercased types like
> "int" were to go in the I registers.

Yes...

> I think we'd still want to be able to create a reference to them though.

No, sorry. "my int $a" means that $a is fast (good) but can't participate
in any of the reindeer games like CALLER, MY, and references (bad).

> In the .NET case, there's no reason not to use I registers for its
> integers.

Urque. So the real Reference PMC type actually doesn't do everything you
want, and there's no point in waiting for it. As for your .Net-specific
pointer PMC, if you're already keeping a contecxt pointer and an index, all
you need in addition is a type enum for [INSP] and you're set. (Or separate
subclasses of the pmc, whichever works better for you.)
--
Chip Salzenberg <ch...@pobox.com>

Jonathan Worthington

unread,
Jan 24, 2006, 6:08:54 PM1/24/06
to Chip Salzenberg, perl6-i...@perl.org
"Chip Salzenberg" <ch...@pobox.com> wrote:
> On Tue, Jan 24, 2006 at 08:49:55PM -0000, Jonathan Worthington wrote:
>> "Chip Salzenberg" <ch...@pobox.com> wrote:
>> >I'd prefer to reuse something in the engine already for those callbacks.
>> >If a lightweight callback mechanism, with parameter, doesn't already
>> >exist, then you could either use a closure for -that- (eh, too
>> >expensive)
>> >or else invent such a mechanism for general use, with yourself as first
>> >customer.
>>
>> There is a mechanism used to do this kinda thing for exit handlers
>> (src/exit.c), but it doesn't look particularly general. I guess leo will
>> know if there is something I've missed - leo, thoughts? I guess such a
>> mechanism probably shouldn't be much work to implement, though, and would
>> certainly be a nice, clean answer.
>
> Words I love to hear. Er, read.
>
;-) It's in my task list, I'll try and get onto it soon.

>> >I imagined that the references would only ever be to -PMC- registers...?
>>
>> I wouldn't have thought so. I thought in Perl 6 the lowercased types
>> like
>> "int" were to go in the I registers.
>
> Yes...
>
>> I think we'd still want to be able to create a reference to them though.
>
> No, sorry. "my int $a" means that $a is fast (good) but can't participate
> in any of the reindeer games like CALLER, MY, and references (bad).
>

Thanks for the clarification.

>> In the .NET case, there's no reason not to use I registers for its
>> integers.
>
> Urque. So the real Reference PMC type actually doesn't do everything you
> want, and there's no point in waiting for it. As for your .Net-specific
> pointer PMC, if you're already keeping a contecxt pointer and an index,
> all
> you need in addition is a type enum for [INSP] and you're set. (Or
> separate
> subclasses of the pmc, whichever works better for you.)

Yup, got that spec'd out now and can start hacking on it tomorrow, maybe
even get something working. Thanks for all of your help - very much
appreciated.

Jonathan

Chip Salzenberg

unread,
Jan 25, 2006, 2:58:17 PM1/25/06
to perl6-i...@perl.org
On Tue, Jan 24, 2006 at 09:19:48AM -0800, Larry Wall wrote:
> On Tue, Jan 24, 2006 at 01:04:10PM -0000, Jonathan Worthington wrote:
> : Looking at what Chip said though, it would appear that the much cleaner
> : solution I was hoping to find exists and can be found in lex pad stuff,
> : which I need to go stare at for a bit before replying. :-)
>
> This is tangentially related, but we might need to think about
> something like typed references in any event to enable various forms
> of round-trip language interoperability. That is, we could have
> references that are polymorphic depending on language context,
> so that different behaviors can be emulated depending on which
> facilities are native to the language and which are "borrowed" from
> some other language. Think of something which is simultaneously a
> P5 and a P6 object.

An interesting idea. Should be easy enough to do with existing facilities,
switching behavior at runtime based on <pseudop6> CALLER.sub.hll </pseudop6>.
--
Chip Salzenberg <ch...@pobox.com>

0 new messages