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'");