Okay, as promised, here's the object proposal for parrot. (And yes,
it was finished by 5PM EST--if you got it later, it just means I
lingered over coffee in a blissfully wireless-free coffee shop down
the street from my apartment)

Objects, as far as I see it, have the following properties:

1) They have runtime-assignable properties
2) They have reference semantics
3) They belong to a class
4) The class they belong to may be the child of one or more parent
   classes
5) You can call methods on them
6) They have a set of attributes
7) They may inherit attributes from their parent class(es)
8) Attributes are mostly private to the declaring class
9) They don't have a value outside their attributes
10) Parent classes can only be in the inheritance hierarchy once.
11) They are all orange

There are probably other core object properties that I've
missed. This would be the time to mention them.

Now, as far as the above go, here's what we're going to need to add,
and what I'm proposing.

#1 is provided by core services already. We do need to work out
 whether properties get propagated to the object or stay with the
 reference part, but as property assignment's delegated to the PMC
 itself we can do this with no core changes.

#2 can be done with a reference PMC type that delegates most of its
 operations to its referent. This isn't much (if any) different from
 regular references, and just needs a PMC class for it. No biggie.

#3 Since each class has a PMC type, we just need to associate the PMC
 type with the data a class needs. Also pretty much no big deal, and
 something we already have facilities for.

#4 is a matter either for method dispatch, which is handled by the
 PMC's vtable method entry, or for attribute construction, which
 we'll deal with in a little bit.

#5 We can already do this, via the method entry in the PMC's
 vtable. We need to better define how it works, since I've been
 unreasonably fuzzy about it. I'll do that in a little, hopefully
 with a JIT-friendly spin.

#6 Attributes. These are just a set of slots with names associated
 with them. Objects are essentially an attribute chunk wrapper with
 some metadata. I'll describe them after the end of the list

#7 This means that we have to deal with a parent class looking for
 attributes insinde an object of a child class

#8 means we may potentially deal with multiple attributes of the same
 name in an object, in separate parent classes

#9 Yes, this is different from perl 5's object model. That's fine, as
 it won't impact perl 5 object code running on us. (Think about it
 for a second, given what we already have in place... :)

#10 We do MI, but we don't instantiate a class' attributes multiple
 times if its in the hierarchy for a class more than once. If it is,
 the leftmost instance is real, the rest are virtual

#11 This goes without saying, of course

So, with these things in place, what do we need? I see the current
scheme needing extension in three places

1) We need callmeth and jmpmeth opcodes

2) The method call vtable entry needs to be better defined.

3) We need to define what the heck attributes are and how the work
   for an object

4) We need to define how attributes work for classes

The call/jmpmeth opcodes either make a returnable or non-returnable
method call. They fetch the function pointer from the object PMC and
either dispatch to it or save the current state and jsr to it. Note
that you can't jmpmeth into a C-implemented method, so no tail
calling into those without some wrapper opcodes. The registers still
need to be set up appropriately, just like with a regular sub call.

The find_method vtable entry should die, and be replaced with a plain
method entry. This should return either the address of the start of
the method's bytecode, or NULL. The NULL return is for those cases
where the method actually executed via native code, and thus doesn't
have to go anywhere. If an address is returned it's expected that the
engine will immediately dispatch to that spot, obeying parrot's
calling conventions.

For object attributes, we're going to use an Attr PMC. Its data
pointer points to an attribute bufffer, which is just an array. Each
attribute takes up a single slot in the array. By default attributes
must be GC-able entities, but if someone objects and is willing to
pay the speed penalty they can have an Attr subclass that has a
custom GC routine. (I'm not convinced that the speed loss outweighs
the memory win, hence the default restrictions)

Classes are a type of object, and the attributes in classes keep
track of the important meta-information for objects. For example, one
of the class attributes is a hash that has a name->slot mapping table
so we don't have to duplicate it for each object.

We have the option of either building in attribute lookup code to the
interpreter, or adding in a few vtable methods. I'm more inclined to
gp with interpreter support, as we've got more than enough vtable
entries as it is, but I can be convinced otherwise. If we *do* add in
vtable support I think we can safely skip the keyed versions, since
the only things that should be getting attribute info are the methods
for a class, and by the time you're in there you have to have a real
object, not an index into an array or something.

The structures:

*) Attr PMCs have an array off their data pointer.

*) Classes are variants of Attr PMCs. They have the following
 guaranteed attributes in slots:

   0) Hash with class name to attribute offset
   1) Hash with attribute name to attribute offset (relative to the
      offset found from the hash in slot 0, generally known at
      compile time, but introspection is nice)
   2) Integer number of attributes this class has
   3) Notification array

Finally, for perl 5 compatibility, we don't have to add anything
special to the interpreter engine. Having an appropriate method
vtable entry for perl 5 classes is all it takes, and that's no big
deal. (As perl 5 classes are just hashes/arrays/scalars with a special
method call entry)

I'm not 100% sure how to handle delegation, so for right now we're
just punting. No automatic delegation. This *will* be fixed, but we
can hash it out after this proposal has been ravaged appropriately.

So.... have at it. What have I forgotten, what's wrong, and who's got
questions on how this works? (I can put together examples, but this
is pretty long as it is, and I think it's reasonably
self-explanatory. Besides, assembly language isn't generally the best
way to demonstrate anything... :)

--
                                        Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                      teddy bears get drunk

Reply via email to