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