cvsuser     04/04/09 05:04:49

  Modified:    include/parrot objects.h
               src      objects.c
               t/pmc    object-meths.t
  Log:
  alternate object initializer calling scheme
  
  Revision  Changes    Path
  1.24      +2 -1      parrot/include/parrot/objects.h
  
  Index: objects.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/objects.h,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -w -r1.23 -r1.24
  --- objects.h 3 Apr 2004 15:59:24 -0000       1.23
  +++ objects.h 9 Apr 2004 12:04:43 -0000       1.24
  @@ -1,7 +1,7 @@
   /* objects.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: objects.h,v 1.23 2004/04/03 15:59:24 leo Exp $
  + *     $Id: objects.h,v 1.24 2004/04/09 12:04:43 leo Exp $
    *  Overview:
    *     Parrot class and object header stuff
    *  Data Structure and Algorithms:
  @@ -44,6 +44,7 @@
   PMC *Parrot_remove_parent(Parrot_Interp, PMC *, PMC *);
   PMC *Parrot_multi_subclass(Parrot_Interp, PMC *, STRING *);
   void Parrot_instantiate_object(Parrot_Interp, PMC *);
  +void Parrot_instantiate_object_init(Parrot_Interp, PMC *, PMC *);
   INTVAL Parrot_object_isa(Parrot_Interp interpreter, PMC *, PMC *);
   PMC *Parrot_new_method_cache(Parrot_Interp);
   PMC *Parrot_find_method_with_cache(Parrot_Interp, PMC *, STRING *);
  
  
  
  1.79      +103 -12   parrot/src/objects.c
  
  Index: objects.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/objects.c,v
  retrieving revision 1.78
  retrieving revision 1.79
  diff -u -w -r1.78 -r1.79
  --- objects.c 5 Apr 2004 09:24:04 -0000       1.78
  +++ objects.c 9 Apr 2004 12:04:46 -0000       1.79
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: objects.c,v 1.78 2004/04/05 09:24:04 leo Exp $
  +$Id: objects.c,v 1.79 2004/04/09 12:04:46 leo Exp $
   
   =head1 NAME
   
  @@ -440,6 +440,7 @@
   
       /* Reset the init method to our instantiation method */
       new_vtable->init = Parrot_instantiate_object;
  +    new_vtable->init_pmc = Parrot_instantiate_object_init;
       new_class->vtable = new_vtable;
   
       /* Put our new vtable in the global table */
  @@ -458,16 +459,47 @@
       return new_type;
   }
   
  +static PMC*
  +get_init_meth(Parrot_Interp interpreter, PMC *class,
  +        const char * init_name, STRING **meth_str)
  +{
  +    PMC *prop;
  +    STRING *prop_str, *meth;
  +#if 0
  +    prop_str = const_string(interpreter, init_name);
  +    prop = VTABLE_getprop(interpreter, class, prop_str);
  +    if (!VTABLE_defined(interpreter, prop))
  +        return NULL;
  +    meth = VTABLE_get_string(interpreter, prop);
  +#else
  +    HashBucket *b;
  +    PMC *props;
  +    if ( !(props = PMC_metadata(class)))
  +        return NULL;
  +    prop_str = const_string(interpreter, init_name);
  +    b = hash_get_bucket(interpreter,
  +                (Hash*) PMC_struct_val(props), prop_str);
  +    if (!b)
  +        return NULL;
  +    meth = PMC_str_val((PMC*) b->value);
  +#endif
  +    *meth_str = meth;
  +    return Parrot_find_method_with_cache(interpreter, class, meth);
  +}
   
   static void
  -do_initcall(Parrot_Interp interpreter, PMC* class, PMC *object)
  +do_initcall(Parrot_Interp interpreter, PMC* class, PMC *object, PMC *init)
   {
  -
       SLOTTYPE *class_data = PMC_data(class);
       PMC *classsearch_array = get_attrib_num(class_data, PCD_ALL_PARENTS);
       PMC *parent_class;
       INTVAL i, nparents;
  +    int free_it;
  +    /*
  +     * XXX compat mode
  +     */
   
  +    if (!Parrot_getenv("CALL__BUILD", &free_it)) {
       nparents = VTABLE_elements(interpreter, classsearch_array);
       for (i = nparents - 1; i >= 0; --i) {
           parent_class = VTABLE_get_pmc_keyed_int(interpreter,
  @@ -477,11 +509,55 @@
       }
       Parrot_base_vtables[enum_class_delegate]->init(interpreter, object);
   }
  +    else {
  +        /*
  +         * 1) if class has a CONSTRUCT property run it on the object
  +         *    no redispatch
  +         */
  +        STRING *meth_str;
  +        PMC *meth = get_init_meth(interpreter, class, "CONSTRUCT", &meth_str);
  +        if (meth) {
  +            if (init)
  +                Parrot_run_meth_fromc_args_save(interpreter, meth,
  +                        object, meth_str, "vP", init);
  +            else
  +                Parrot_run_meth_fromc_save(interpreter, meth,
  +                        object, meth_str);
  +        }
  +        /*
  +         * 2. if class has a BUILD property call it for all classes
  +         *    in reverse search order - this class last.
  +         */
  +        nparents = VTABLE_elements(interpreter, classsearch_array);
  +        for (i = nparents - 1; i >= 0; --i) {
  +            parent_class = VTABLE_get_pmc_keyed_int(interpreter,
  +                    classsearch_array, i);
  +            meth = get_init_meth(interpreter, parent_class, "BUILD", &meth_str);
  +            if (meth) {
  +                if (init)
  +                    Parrot_run_meth_fromc_args_save(interpreter, meth,
  +                            object, meth_str, "vP", init);
  +                else
  +                    Parrot_run_meth_fromc_save(interpreter, meth,
  +                            object, meth_str);
  +            }
  +        }
  +        meth = get_init_meth(interpreter, class, "BUILD", &meth_str);
  +        if (meth) {
  +            if (init)
  +                Parrot_run_meth_fromc_args_save(interpreter, meth,
  +                        object, meth_str, "vP", init);
  +            else
  +                Parrot_run_meth_fromc_save(interpreter, meth,
  +                        object, meth_str);
  +        }
  +    }
  +}
   
   /*
   
   =item C<void
  -Parrot_instantiate_object(Parrot_Interp interpreter, PMC *object)>
  +Parrot_instantiate_object(Parrot_Interp interpreter, PMC *object, PMC *init)>
   
   Creates a Parrot object. Takes a passed-in class PMC that has sufficient
   information to describe the layout of the object and, well, makes the
  @@ -491,9 +567,24 @@
   
   */
   
  +static void instantiate_object(Parrot_Interp, PMC *object, PMC *init);
  +
  +void
  +Parrot_instantiate_object_init(Parrot_Interp interpreter,
  +        PMC *object, PMC *init)
  +{
  +    instantiate_object(interpreter, object, init);
  +}
  +
   void
   Parrot_instantiate_object(Parrot_Interp interpreter, PMC *object)
   {
  +    instantiate_object(interpreter, object, NULL);
  +}
  +
  +static void
  +instantiate_object(Parrot_Interp interpreter, PMC *object, PMC *init)
  +{
       SLOTTYPE *new_object_array;
       INTVAL attrib_count;
       SLOTTYPE *class_array;
  @@ -536,7 +627,7 @@
       /* We really ought to call the class init routines here...
        * this assumes that an object isa delegate
        */
  -    do_initcall(interpreter, class, object);
  +    do_initcall(interpreter, class, object, init);
   }
   
   /*
  
  
  
  1.16      +84 -2     parrot/t/pmc/object-meths.t
  
  Index: object-meths.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/object-meths.t,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -w -r1.15 -r1.16
  --- object-meths.t    4 Apr 2004 08:30:44 -0000       1.15
  +++ object-meths.t    9 Apr 2004 12:04:49 -0000       1.16
  @@ -1,6 +1,6 @@
   #! perl -w
   # Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -# $Id: object-meths.t,v 1.15 2004/04/04 08:30:44 leo Exp $
  +# $Id: object-meths.t,v 1.16 2004/04/09 12:04:49 leo Exp $
   
   =head1 NAME
   
  @@ -16,7 +16,7 @@
   
   =cut
   
  -use Parrot::Test tests => 17;
  +use Parrot::Test tests => 19;
   use Test::More;
   
   output_like(<<'CODE', <<'OUTPUT', "callmethod - unknown method");
  @@ -604,3 +604,85 @@
   OUTPUT
   };
   
  +$ENV{"CALL__BUILD"} = "1";
  +
  +output_is(<<'CODE', <<'OUTPUT', "constructor - parents BUILD");
  +    new P10, .PerlString
  +    set P10, "_new"
  +    newclass P1, "Foo"
  +    setprop P1, "BUILD", P10
  +    subclass P2, P1, "Bar"
  +    setprop P2, "BUILD", P10
  +    subclass P3, P2, "Baz"
  +    setprop P3, "BUILD", P10
  +    find_type I1, "Baz"
  +    new P3, I1
  +    find_type I1, "Bar"
  +    new P3, I1
  +    find_global P0, "_sub"
  +    invokecc
  +    print "done\n"
  +    end
  +
  +    .namespace ["Foo"]
  +.pcc_sub _new:
  +    print "foo_init\n"
  +    classname S0, P2
  +    print S0
  +    print "\n"
  +    invoke P1
  +
  +    .namespace ["Bar"]
  +.pcc_sub _new:
  +    print "bar_init\n"
  +    invoke P1
  +
  +    .namespace ["Baz"]
  +.pcc_sub _new:
  +    print "baz_init\n"
  +    invoke P1
  +
  +    .namespace [""]  # main again
  +.pcc_sub _sub:
  +    print "in sub\n"
  +    invoke P1
  +
  +CODE
  +foo_init
  +Baz
  +bar_init
  +baz_init
  +foo_init
  +Bar
  +bar_init
  +in sub
  +done
  +OUTPUT
  +
  +delete $ENV{"CALL__BUILD"};
  +
  +output_is(<<'CODE', <<'OUTPUT', "same method name in two namespaces");
  +##PIR##
  +.namespace ["A"]
  +.sub foo method
  +    .param int i
  +
  +    .pcc_begin_return
  +    .pcc_end_return
  +.end
  +
  +.namespace ["B"]
  +.sub foo method
  +    .param int i
  +
  +    .pcc_begin_return
  +    .pcc_end_return
  +.end
  +
  +.namespace [""]
  +.sub _main @MAIN
  +    print "ok\n"
  +.end
  +CODE
  +ok
  +OUTPUT
  
  
  

Reply via email to