cvsuser     04/09/29 02:56:16

  Modified:    ops      core.ops
               src      nci_test.c
               t/pmc    nci.t
  Log:
  [perl #31752] [PATCH] 'dlvar' should not panic, test 'dlvar'
  
  this patch adds two tests of the opcode 'dlvar' to t/pmc/nci.t.
  When a non-existing symbol is requested from a shared library, then 'dlvar'
  should not panic.
  
  See also ticket 31600.
  
  Courtesy of Bernhard Schmalhofer <[EMAIL PROTECTED]>
  
  Revision  Changes    Path
  1.370     +14 -18    parrot/ops/core.ops
  
  Index: core.ops
  ===================================================================
  RCS file: /cvs/public/parrot/ops/core.ops,v
  retrieving revision 1.369
  retrieving revision 1.370
  diff -u -w -r1.369 -r1.370
  --- core.ops  24 Sep 2004 09:45:34 -0000      1.369
  +++ core.ops  29 Sep 2004 09:56:13 -0000      1.370
  @@ -1085,10 +1085,10 @@
   
   op dlfunc (out PMC, in PMC, in STR, in STR) {
     char * name = string_to_cstring(interpreter, ($3));
  -  PMC *nci;
   
     Parrot_csub_t p = (Parrot_csub_t)D2FPTR(
          Parrot_dlsym(PMC_IS_NULL($2) ? NULL : PMC_data($2), name));
  +  string_cstring_free(name);
     if (p == NULL) {
         const char * err = Parrot_dlerror();
         Parrot_warn(interpreter, PARROT_WARNINGS_UNDEF_FLAG,
  @@ -1096,33 +1096,29 @@
         $1 = pmc_new(interpreter, enum_class_PerlUndef);
     }
     else {
  -      $1 = nci = pmc_new(interpreter, enum_class_NCI);
  -      nci->vtable->set_pointer_keyed_str(interpreter, nci, $4, F2DPTR(p));
  +      $1 = pmc_new(interpreter, enum_class_NCI);
  +      $1->vtable->set_pointer_keyed_str(interpreter, $1, $4, F2DPTR(p));
     }
  -  string_cstring_free(name);
     goto NEXT();
   }
   
   op dlvar (out PMC, in PMC, in STR) {
     char * name = string_to_cstring(interpreter, ($3));
   
  -  PMC *final_destination = pmc_new(interpreter, enum_class_UnManagedStruct);
  -
     void *p = Parrot_dlsym(PMC_IS_NULL($2) ? NULL : PMC_data($2), name);
     string_cstring_free(name);
     if(p == NULL) {
       const char * err = Parrot_dlerror();
  -    if(err != NULL) {
  -      fprintf(stderr, "%s\n", err);
  -    }
  -    PANIC("Failed to link native method");
  +      Parrot_warn(interpreter, PARROT_WARNINGS_UNDEF_FLAG,
  +      "Symbol '%s' not found: %s\n", name, err ? err : "unkown reason");
  +      $1 = pmc_new(interpreter, enum_class_PerlUndef);
     }
  -
  +  else {
     /* At this point we have the symbol's address. We just need to build
        a PMC with it so we can get and set the value */
  -
  -  PMC_data(final_destination) = p;
  -  $1 = final_destination;
  +      $1 = pmc_new(interpreter, enum_class_UnManagedStruct);
  +      PMC_data($1) = p;
  +  }
     goto NEXT();
   }
   
  
  
  
  1.32      +19 -1     parrot/src/nci_test.c
  
  Index: nci_test.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/nci_test.c,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -w -r1.31 -r1.32
  --- nci_test.c        16 Sep 2004 20:59:06 -0000      1.31
  +++ nci_test.c        29 Sep 2004 09:56:15 -0000      1.32
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2004 The Perl Foundation.  All Rights Reserved.
  -$Id: nci_test.c,v 1.31 2004/09/16 20:59:06 jrieks Exp $
  +$Id: nci_test.c,v 1.32 2004/09/29 09:56:15 leo Exp $
   
   =head1 NAME
   
  @@ -20,6 +20,7 @@
   
   At that location the shared library is loadable with the opcode 'loadlib'. 
   The functions in the library are available with the opcode 'dlfunc'.
  +The variables in the library are available with the opcode 'dlvar'.
   
   =head1 Functions
   
  @@ -363,6 +364,8 @@
   
   =head1 Functions used for pdd16 tests
   
  +=cut
  +
   */
   
   void
  @@ -463,6 +466,21 @@
      return my_product;
   }
   
  +/*
  +
  +=head1 Variables used for testing the opcode 'dlvar' 
  +
  +=cut
  +
  +*/
  +
  +int nci_dlvar_int = -4444;
  +
  +void 
  +nci_dlvar_vv( void ) {
  +    nci_dlvar_int *= 3;
  +}
  +
   #ifdef TEST
   
   char l2 = 4;
  
  
  
  1.52      +124 -2    parrot/t/pmc/nci.t
  
  Index: nci.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/nci.t,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -w -r1.51 -r1.52
  --- nci.t     24 Sep 2004 09:45:54 -0000      1.51
  +++ nci.t     29 Sep 2004 09:56:15 -0000      1.52
  @@ -1,7 +1,7 @@
   #! perl -w
   
   # Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -# $Id: nci.t,v 1.51 2004/09/24 09:45:54 leo Exp $
  +# $Id: nci.t,v 1.52 2004/09/29 09:56:15 leo Exp $
   
   =head1 NAME
   
  @@ -24,7 +24,7 @@
   
   =cut
   
  -use Parrot::Test tests => 43;
  +use Parrot::Test tests => 46;
   use Parrot::Config;
   
   SKIP: {
  @@ -1881,6 +1881,128 @@
   OUTPUT
   
   
  +output_is( << 'CODE', << 'OUTPUT', "nci_dlvar_int - thrice" );
  +##PIR##
  +.include "datatypes.pasm"
  +
  +.sub _test @MAIN
  +
  +    # load libnci.so
  +    .local string library_name
  +    library_name = 'libnci'
  +    .local pmc libnci
  +    libnci = loadlib library_name
  +    unless libnci goto NOT_LOADED
  +    print library_name
  +    print " was successfully loaded\n"
  +
  +    # address of nci_dlvar_int
  +    .local pmc nci_dlvar_int
  +    nci_dlvar_int = dlvar libnci, "nci_dlvar_int"
  +
  +    # the contained structure pointer
  +    .local pmc nci_dlvar_int_decl
  +    nci_dlvar_int_decl = new PerlArray
  +    push nci_dlvar_int_decl, .DATATYPE_INT
  +    push nci_dlvar_int_decl, 0
  +    push nci_dlvar_int_decl, 0
  +    assign nci_dlvar_int, nci_dlvar_int_decl
  +
  +    I2 = nci_dlvar_int[0]
  +    print I2
  +    print "\n"
  +
  +    .local pmc thrice
  +    thrice = dlfunc libnci, "nci_dlvar_vv", "vv"
  +    thrice()
  +    I1 = nci_dlvar_int[0]
  +    print I1
  +    print "\n"
  +    thrice()
  +    I1 = nci_dlvar_int[0]
  +    print I1
  +    print "\n"
  +    thrice()
  +    I1 = nci_dlvar_int[0]
  +    print I1
  +    print "\n"
  +    thrice()
  +    I1 = nci_dlvar_int[0]
  +    print I1
  +    print "\n"
  +NOT_LOADED:
  +.end
  +CODE
  +libnci was successfully loaded
  +-4444
  +-13332
  +-39996
  +-119988
  +-359964
  +OUTPUT
  +
  +
  +output_is( << 'CODE', << 'OUTPUT', "dlvar - unknown symbol" );
  +##PIR##
  +.include "datatypes.pasm"
  +
  +.sub _test @MAIN
  +
  +    # load libnci.so
  +    .local string library_name
  +    library_name = 'libnci'
  +    .local pmc libnci
  +    libnci = loadlib library_name
  +    unless libnci goto NOT_LOADED
  +    print library_name
  +    print " was successfully loaded\n"
  +
  +    # address of nci_dlvar_int
  +    .local pmc non_existing
  +    non_existing = dlvar libnci, "non_existing"
  +    .local int is_defined
  +    is_defined = defined non_existing
  +    if is_defined goto IS_DEFINED
  +    print "'non_existing' is not defined\n"
  +IS_DEFINED:
  +NOT_LOADED:
  +.end
  +CODE
  +libnci was successfully loaded
  +'non_existing' is not defined
  +OUTPUT
  +
  +
  +output_is( << 'CODE', << 'OUTPUT', "dlfunc - unknown symbol" );
  +##PIR##
  +.include "datatypes.pasm"
  +
  +.sub _test @MAIN
  +
  +    # load libnci.so
  +    .local string library_name
  +    library_name = 'libnci'
  +    .local pmc libnci
  +    libnci = loadlib library_name
  +    unless libnci goto NOT_LOADED
  +    print library_name
  +    print " was successfully loaded\n"
  +
  +    # address of nci_dlvar_int
  +    .local pmc non_existing
  +    non_existing = dlfunc libnci, "non_existing", "iiii"
  +    .local int is_defined
  +    is_defined = defined non_existing
  +    if is_defined goto IS_DEFINED
  +    print "'non_existing' is not defined\n"
  +IS_DEFINED:
  +NOT_LOADED:
  +.end
  +CODE
  +libnci was successfully loaded
  +'non_existing' is not defined
  +OUTPUT
  +
   } # SKIP
   
   output_is(<< 'CODE', << 'OUTPUT', "opcode 'does'");
  
  
  

Reply via email to