cvsuser     05/03/30 08:05:34

  Modified:    imcc     imcc.y pbc.c
               src      global.c mmd.c
               t/pmc    mmd.t
  Log:
  MMD 11 - dispatch on PMC types
  
  Revision  Changes    Path
  1.160     +10 -2     parrot/imcc/imcc.y
  
  Index: imcc.y
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/imcc.y,v
  retrieving revision 1.159
  retrieving revision 1.160
  diff -u -r1.159 -r1.160
  --- imcc.y    30 Mar 2005 09:07:27 -0000      1.159
  +++ imcc.y    30 Mar 2005 16:05:31 -0000      1.160
  @@ -620,8 +620,16 @@
      | FLOATV           { $$ = mk_const(interp, str_dup("FLOATVAL"), 'S'); }
      | PMCV             { $$ = mk_const(interp, str_dup("PMC"), 'S'); }
      | STRINGV          { $$ = mk_const(interp, str_dup("STRING"), 'S'); }
  -   | '_'              { $$ = mk_const(interp, str_dup("PMC"), 'S'); }
  -   | IDENTIFIER       { $$ = mk_const(interp, $1, 'S'); }
  +   | IDENTIFIER       {
  +                          SymReg *r;
  +                          if (strcmp($1, "_"))
  +                              r = mk_const(interp, $1, 'S');
  +                          else {
  +                              free($1),
  +                              r = mk_const(interp, str_dup("PMC"), 'S');
  +                           }
  +                           $$ = r;
  +                       }
      ;
   
   sub_body:
  
  
  
  1.116     +15 -0     parrot/imcc/pbc.c
  
  Index: pbc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/pbc.c,v
  retrieving revision 1.115
  retrieving revision 1.116
  diff -u -r1.115 -r1.116
  --- pbc.c     30 Mar 2005 09:07:27 -0000      1.115
  +++ pbc.c     30 Mar 2005 16:05:31 -0000      1.116
  @@ -467,6 +467,9 @@
                   }
                   addr = jumppc + bsr->color;
                   if (bsr->set == 'p') {
  +                    Instruction *ins;
  +                    SymReg *r1;
  +                    struct pcc_sub_t *pcc_sub;
                       /*
                        * check in matching namespace
                        */
  @@ -474,7 +477,19 @@
                       /*
                        * if failed change opcode:
                        * set_p_pc  => find_name p_sc
  +                     * the the sub is a multi too
                        */
  +                    assert(s1->unit);
  +                    if (lab && (s1->unit->type & IMC_PCCSUB)) {
  +                        ins = s1->unit->instructions;
  +                        assert(ins);
  +                        r1 = ins->r[1];
  +                        assert(r1);
  +                        pcc_sub = r1->pcc_sub;
  +                        assert(pcc_sub);
  +                        if (pcc_sub->nmulti)
  +                            lab = NULL;
  +                    }
                       if (!lab) {
                           int op, col;
                           SymReg *nam;
  
  
  
  1.17      +9 -2      parrot/src/global.c
  
  Index: global.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/global.c,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- global.c  30 Mar 2005 11:12:35 -0000      1.16
  +++ global.c  30 Mar 2005 16:05:33 -0000      1.17
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2004 The Perl Foundation.  All Rights Reserved.
  -$Id: global.c,v 1.16 2005/03/30 11:12:35 leo Exp $
  +$Id: global.c,v 1.17 2005/03/30 16:05:33 leo Exp $
   
   =head1 NAME
   
  @@ -200,10 +200,17 @@
   PMC *
   Parrot_get_name(Interp* interpreter, STRING *name)
   {
  -    PMC *g, *pad;
  +    PMC *g, *pad, *current_sub, *name_space;
   
       pad = scratchpad_get_current(interpreter);
       g = scratchpad_find(interpreter, pad, name);
  +    if (!g) {
  +        current_sub = interpreter->ctx.current_sub;
  +        if (current_sub &&
  +                (name_space = PMC_sub(current_sub)->name_space))
  +
  +            g = Parrot_find_global_p(interpreter, name_space, name);
  +    }
       if (!g)
           g = Parrot_find_global(interpreter, NULL, name);
       if (!g)
  
  
  
  1.57      +45 -8     parrot/src/mmd.c
  
  Index: mmd.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/mmd.c,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- mmd.c     30 Mar 2005 12:54:34 -0000      1.56
  +++ mmd.c     30 Mar 2005 16:05:33 -0000      1.57
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2003 The Perl Foundation.  All Rights Reserved.
  -$Id: mmd.c,v 1.56 2005/03/30 12:54:34 leo Exp $
  +$Id: mmd.c,v 1.57 2005/03/30 16:05:33 leo Exp $
   
   =head1 NAME
   
  @@ -884,6 +884,9 @@
        */
       if (n > 1)
           mmd_sort_candidates(interpreter, arg_tuple, candidate_list);
  +    n = VTABLE_elements(interpreter, candidate_list);
  +    if (!n)
  +        return NULL;
       /*
        * 6) Uff, return first one
        */
  @@ -982,8 +985,8 @@
   static UINTVAL
   mmd_distance(Interp *interpreter, PMC *pmc, PMC *arg_tuple)
   {
  -    PMC *multi_sig;
  -    INTVAL i, n, args, dist;
  +    PMC *multi_sig, *mro;
  +    INTVAL i, n, args, dist, j, m;
       INTVAL type_sig, type_call;
   
       multi_sig = PMC_sub(pmc)->multi_signature;
  @@ -1014,12 +1017,33 @@
           type_call = VTABLE_get_integer_keyed_int(interpreter, arg_tuple, i);
           if (type_sig == type_call)
               continue;
  -        /* different native types are very different */
  -        if (type_sig <= 0 || type_call <= 0) {
  +        /*
  +         * different native types are very different, except a PMC
  +         * which matches any PMC
  +         */
  +        if ((type_sig <= 0 && type_sig != enum_type_PMC) || type_call <= 0) {
               dist = MMD_BIG_DISTANCE;
               break;
           }
  -        /* TODO now consider MRO of types */
  +        /*
  +         * now consider MRO of types the signature type has to be somewhere
  +         * int the MRO of the type_call
  +         */
  +        mro = Parrot_base_vtables[type_call]->mro;
  +        m = VTABLE_elements(interpreter, mro);
  +        for (j = 0; j < m; ++j) {
  +            PMC *cl = VTABLE_get_pmc_keyed_int(interpreter, mro, j);
  +            if (cl->vtable->base_type == type_sig)
  +                break;
  +            ++dist;
  +        }
  +        /*
  +         * if the type wasn't in MRO check, if any PMC matches
  +         * in that case use the distance + 1 (of an any PMC parent)
  +         */
  +        if (j == m && type_sig != enum_type_PMC)
  +            return MMD_BIG_DISTANCE;
  +        ++dist;
       }
       return dist;
   }
  @@ -1075,6 +1099,13 @@
       data = PMC_data(cl);
       for (i = 0; i < n; ++i) {
           INTVAL idx = helper[i] >> 16;
  +        /*
  +         * if the distance is big stop
  +         */
  +        if ((helper[i] & 0xffff) == MMD_BIG_DISTANCE) {
  +            PMC_int_val(cl) = i;
  +            break;
  +        }
           LVALUE_CAST(PMC*, helper[i]) = data[idx];
       }
       /*
  @@ -1231,12 +1262,18 @@
   static int
   mmd_search_package(Interp *interpreter, STRING *meth, PMC *arg_tuple, PMC 
*cl)
   {
  -    STRING *name_space = interpreter->ctx.current_package;
  +    /* STRING *name_space = interpreter->ctx.current_package; */
       PMC *pmc;
  +    PMC *current_sub;
  +    PMC *name_space;
   
  +    current_sub = interpreter->ctx.current_sub;
  +    if (!current_sub)
  +        return 0;
  +    name_space = PMC_sub(current_sub)->name_space;
       if (!name_space)
           return 0;
  -    pmc = Parrot_find_global(interpreter, name_space, meth);
  +    pmc = Parrot_find_global_p(interpreter, name_space, meth);
       if (pmc) {
           if (mmd_maybe_candidate(interpreter, pmc, arg_tuple, cl))
               return 1;
  
  
  
  1.19      +262 -2    parrot/t/pmc/mmd.t
  
  Index: mmd.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/mmd.t,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- mmd.t     30 Mar 2005 14:04:40 -0000      1.18
  +++ mmd.t     30 Mar 2005 16:05:34 -0000      1.19
  @@ -1,6 +1,6 @@
   #! perl -w
   # Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -# $Id: mmd.t,v 1.18 2005/03/30 14:04:40 leo Exp $
  +# $Id: mmd.t,v 1.19 2005/03/30 16:05:34 leo Exp $
   
   =head1 NAME
   
  @@ -16,7 +16,7 @@
   
   =cut
   
  -use Parrot::Test tests => 12;
  +use Parrot::Test tests => 18;
   
   pir_output_is(<<'CODE', <<'OUTPUT', "PASM divide");
   
  @@ -405,3 +405,263 @@
   ok 1
   42
   OUT
  +
  +pir_output_is(<<'CODE', <<'OUT', "MMD on PMC types");
  +.namespace ["main"]
  +.sub main @MAIN
  +    $P0 = new String
  +    $P0 = "ok 1\n"
  +    $P1 = new PerlString
  +    $P1 = "ok 2\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = subclass "PerlString", "Xstring"
  +    $P0 = new "Xstring"
  +    $P0 = "ok 3\n"
  +    $P1 = subclass "String", "Ystring"
  +    $P1 = new "Ystring"
  +    $P1 = "ok 4\n"
  +    p($P0)
  +    p($P1)
  +.end
  +
  +.namespace [""]
  +
  +.sub p @MULTI(String)
  +    .param pmc p
  +    print "String "
  +    print p
  +.end
  +
  +.sub p @MULTI(PerlString)
  +    .param pmc p
  +    print "PerlSt "
  +    print p
  +.end
  +CODE
  +String ok 1
  +PerlSt ok 2
  +PerlSt ok 3
  +String ok 4
  +OUT
  +
  +pir_output_like(<<'CODE', <<'OUT', "MMD on PMC types, invalid");
  +.namespace ["main"]
  +.sub main @MAIN
  +    $P0 = new String
  +    $P0 = "ok 1\n"
  +    $P1 = new PerlString
  +    $P1 = "ok 2\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = subclass "PerlString", "Xstring"
  +    $P0 = new "Xstring"
  +    $P0 = "ok 3\n"
  +    $P1 = subclass "String", "Ystring"
  +    $P1 = new "Ystring"
  +    $P1 = "ok 4\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = new Integer
  +    p($P0)
  +.end
  +
  +.namespace [""]
  +
  +.sub p @MULTI(String)
  +    .param pmc p
  +    print "String "
  +    print p
  +.end
  +
  +.sub p @MULTI(PerlString)
  +    .param pmc p
  +    print "PerlSt "
  +    print p
  +.end
  +CODE
  +/String ok 1
  +PerlSt ok 2
  +PerlSt ok 3
  +String ok 4
  +Name 'p' not found/
  +OUT
  +
  +pir_output_is(<<'CODE', <<'OUT', "MMD on PMC types 3");
  +.namespace ["main"]
  +.sub main @MAIN
  +    $P0 = new String
  +    $P0 = "ok 1\n"
  +    $P1 = new PerlString
  +    $P1 = "ok 2\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = subclass "PerlString", "Xstring"
  +    $P0 = new "Xstring"
  +    $P0 = "ok 3\n"
  +    $P1 = subclass "String", "Ystring"
  +    $P1 = new "Ystring"
  +    $P1 = "ok 4\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = new PerlInt
  +    $P0 = 42
  +    p($P0)
  +.end
  +
  +.namespace [""]
  +
  +.sub p @MULTI(String)
  +    .param pmc p
  +    print "String "
  +    print p
  +.end
  +
  +.sub p @MULTI(PerlString)
  +    .param pmc p
  +    print "PerlSt "
  +    print p
  +.end
  +
  +.sub p @MULTI(Integer)
  +    .param pmc p
  +    print "Intege "
  +    print p
  +    print "\n"
  +.end
  +
  +CODE
  +String ok 1
  +PerlSt ok 2
  +PerlSt ok 3
  +String ok 4
  +Intege 42
  +OUT
  +
  +pir_output_is(<<'CODE', <<'OUT', "MMD on PMC types, global namespace");
  +.sub main @MAIN
  +    $P0 = new String
  +    $P0 = "ok 1\n"
  +    $P1 = new PerlString
  +    $P1 = "ok 2\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = subclass "PerlString", "Xstring"
  +    $P0 = new "Xstring"
  +    $P0 = "ok 3\n"
  +    $P1 = subclass "String", "Ystring"
  +    $P1 = new "Ystring"
  +    $P1 = "ok 4\n"
  +    p($P0)
  +    p($P1)
  +.end
  +
  +.sub p @MULTI(String)
  +    .param pmc p
  +    print "String "
  +    print p
  +.end
  +
  +.sub p @MULTI(PerlString)
  +    .param pmc p
  +    print "PerlSt "
  +    print p
  +.end
  +CODE
  +String ok 1
  +PerlSt ok 2
  +PerlSt ok 3
  +String ok 4
  +OUT
  +
  +pir_output_is(<<'CODE', <<'OUT', "MMD on PMC types, package namespace");
  +
  +.namespace ["Some"]
  +
  +.sub main @MAIN
  +    $P0 = new String
  +    $P0 = "ok 1\n"
  +    $P1 = new PerlString
  +    $P1 = "ok 2\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = subclass "PerlString", "Xstring"
  +    $P0 = new "Xstring"
  +    $P0 = "ok 3\n"
  +    $P1 = subclass "String", "Ystring"
  +    $P1 = new "Ystring"
  +    $P1 = "ok 4\n"
  +    p($P0)
  +    p($P1)
  +.end
  +
  +.sub p @MULTI(String)
  +    .param pmc p
  +    print "String "
  +    print p
  +.end
  +
  +.sub p @MULTI(PerlString)
  +    .param pmc p
  +    print "PerlSt "
  +    print p
  +.end
  +CODE
  +String ok 1
  +PerlSt ok 2
  +PerlSt ok 3
  +String ok 4
  +OUT
  +
  +pir_output_is(<<'CODE', <<'OUT', "MMD on PMC types - Any");
  +
  +.sub main @MAIN
  +    $P0 = new String
  +    $P0 = "ok 1\n"
  +    $P1 = new PerlString
  +    $P1 = "ok 2\n"
  +    p($P0)
  +    p($P1)
  +    $P0 = new PerlInt
  +    $P0 = 42
  +    p($P0)
  +    $P0 = new PerlInt
  +    $P0 = 43
  +    q($P0)
  +.end
  +
  +.namespace [""]
  +
  +.sub p @MULTI(String)
  +    .param pmc p
  +    print "String "
  +    print p
  +.end
  +
  +.sub p @MULTI(PerlString)
  +    .param pmc p
  +    print "PerlSt "
  +    print p
  +.end
  +
  +.sub p @MULTI(_)
  +    .param pmc p
  +    print "Any    "
  +    print p
  +    print "\n"
  +.end
  +
  +.sub q @MULTI(pmc)
  +    .param pmc p
  +    print "Any    "
  +    print p
  +    print "\n"
  +.end
  +
  +CODE
  +String ok 1
  +PerlSt ok 2
  +Any    42
  +Any    43
  +OUT
  +
  
  
  

Reply via email to