cvsuser 03/10/14 05:29:09
Modified: . dynext.c interpreter.c ops2c.pl
Log:
dynamic oplibs - plain core
Revision Changes Path
1.10 +52 -17 parrot/dynext.c
Index: dynext.c
===================================================================
RCS file: /cvs/public/parrot/dynext.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -w -r1.9 -r1.10
--- dynext.c 14 Oct 2003 10:15:13 -0000 1.9
+++ dynext.c 14 Oct 2003 12:29:09 -0000 1.10
@@ -1,7 +1,7 @@
/* dynext.c
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: dynext.c,v 1.9 2003/10/14 10:15:13 leo Exp $
+ * $Id: dynext.c,v 1.10 2003/10/14 12:29:09 leo Exp $
* Overview:
* Dynamic extension stuff
* Data Structure and Algorithms:
@@ -14,21 +14,31 @@
#include "parrot/parrot.h"
#include "parrot/dynext.h"
-
/*
- * dynamic library loader
- * the initializer is currently unused
- *
- * calls Parrot_lib_load_%s which performs the registration of the lib once
- * Parrot_lib_init_%s gets called (if exists) to perform thread specific setup
+ * set a property
*/
-
static void
-store_lib_pmc(Parrot_Interp interpreter, PMC* lib_pmc, STRING *path)
+set_cstring_prop(Parrot_Interp interpreter, PMC *lib_pmc, const char *what,
+ STRING *name)
{
- PMC *iglobals, *dyn_libs, *prop;
+ PMC *prop;
STRING *key;
+ prop = pmc_new(interpreter, enum_class_PerlString);
+ VTABLE_set_string_native(interpreter, prop, name);
+ key = string_from_cstring(interpreter, what, 0);
+ VTABLE_setprop(interpreter, lib_pmc, key, prop);
+}
+
+/*
+ * store a library PMC in interpreter iglobals
+ */
+static void
+store_lib_pmc(Parrot_Interp interpreter, PMC* lib_pmc, STRING *path,
+ STRING *type)
+{
+ PMC *iglobals, *dyn_libs;
+
iglobals = interpreter->iglobals;
dyn_libs = VTABLE_get_pmc_keyed_int(interpreter, iglobals,
IGLOBALS_DYN_LIBS);
@@ -40,14 +50,17 @@
/*
* remember path/file in props
*/
- prop = pmc_new(interpreter, enum_class_PerlString);
- VTABLE_set_string_native(interpreter, prop, path);
- key = string_from_cstring(interpreter, "_filename", 0);
- VTABLE_setprop(interpreter, lib_pmc, key, prop);
+ set_cstring_prop(interpreter, lib_pmc, "_filename", path);
+ set_cstring_prop(interpreter, lib_pmc, "_type", type);
VTABLE_push_pmc(interpreter, dyn_libs, lib_pmc);
}
+/*
+ * check if a library PMC with the filename path exists
+ * if yes return it
+ *
+ */
static PMC*
is_loaded(Parrot_Interp interpreter, STRING *path)
{
@@ -76,7 +89,7 @@
/*
* return path and handle of a dynamic lib
*/
-STRING *
+static STRING *
get_path(Interp *interpreter, STRING *lib, void **handle)
{
char *cpath;
@@ -125,10 +138,19 @@
return path;
}
+/*
+ * dynamic library loader
+ * the initializer is currently unused
+ *
+ * calls Parrot_lib_load_%s which performs the registration of the lib once
+ * Parrot_lib_init_%s gets called (if exists) to perform
+ * thread specific setup
+ */
+
PMC *
Parrot_load_lib(Interp *interpreter, STRING *lib, PMC *initializer)
{
- STRING *path, *load_func_name, *init_func_name;
+ STRING *path, *load_func_name, *init_func_name, *type;
void * handle;
PMC *(*load_func)(Interp *);
void (*init_func)(Interp *, PMC *);
@@ -137,9 +159,15 @@
UNUSED(initializer);
path = get_path(interpreter, lib, &handle);
+ /*
+ * TODO move the class_count_mutex here
+ *
+ * LOCK()
+ */
lib_pmc = is_loaded(interpreter, path);
if (lib_pmc) {
Parrot_dlclose(handle);
+ /* UNLOCK */
return lib_pmc;
}
load_func_name = Parrot_sprintf_c(interpreter, "Parrot_lib_%Ss_load", lib);
@@ -150,9 +178,15 @@
if (!load_func) {
/* seems to be a native/NCI lib */
lib_pmc = pmc_new(interpreter, enum_class_ConstParrotLibrary);
+ type = string_from_cstring(interpreter, "NCI", 0);
}
else {
lib_pmc = (*load_func)(interpreter);
+ /* we could set a private flag in the PMC header too
+ * but currently only ops files have struct_val set
+ */
+ type = string_from_cstring(interpreter,
+ lib_pmc->cache.struct_val ? "Ops" : "PMC", 0);
/*
* TODO call init, if it exists
*/
@@ -161,7 +195,8 @@
/*
* remember lib_pmc in iglobals
*/
- store_lib_pmc(interpreter, lib_pmc, path);
+ store_lib_pmc(interpreter, lib_pmc, path, type);
+ /* UNLOCK */
return lib_pmc;
}
1.212 +56 -1 parrot/interpreter.c
Index: interpreter.c
===================================================================
RCS file: /cvs/public/parrot/interpreter.c,v
retrieving revision 1.211
retrieving revision 1.212
diff -u -w -r1.211 -r1.212
--- interpreter.c 14 Oct 2003 07:39:54 -0000 1.211
+++ interpreter.c 14 Oct 2003 12:29:09 -0000 1.212
@@ -1,7 +1,7 @@
/* interpreter.c
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: interpreter.c,v 1.211 2003/10/14 07:39:54 leo Exp $
+ * $Id: interpreter.c,v 1.212 2003/10/14 12:29:09 leo Exp $
* Overview:
* The interpreter api handles running the operations
* Data Structure and Algorithms:
@@ -769,6 +769,7 @@
interpreter->op_count = interpreter->op_lib->op_count;
interpreter->op_func_table = interpreter->op_lib->op_func_table;
interpreter->op_info_table = interpreter->op_lib->op_info_table;
+ SET_NULL_P(interpreter->all_op_libs, op_lib_t **);
/* Set up defaults for line/package/file */
interpreter->current_file =
@@ -1053,6 +1054,60 @@
}
}
+/*
+ * dynamic loading stuff
+ */
+
+/*=for api interpreter dynop_register
+ *
+ * register a dynamic oplib
+ */
+
+void
+dynop_register(Parrot_Interp interpreter, PMC* lib_pmc)
+{
+ op_lib_t *lib, *core;
+ oplib_init_f init_func;
+ op_func_t *new_func_table;
+ op_info_t *new_info_table;
+ size_t i, n_old, n_new;
+
+ interpreter->all_op_libs = mem_sys_realloc(interpreter->all_op_libs,
+ sizeof(op_lib_t *) * (interpreter->n_libs + 1));
+
+ init_func = get_op_lib_init(0, 0, lib_pmc);
+ lib = init_func(1);
+
+ interpreter->all_op_libs[interpreter->n_libs++] = lib;
+ n_old = interpreter->op_count;
+ n_new = lib->op_count;
+
+ /*
+ * allocate new op_func and info tables
+ */
+ new_func_table = mem_sys_allocate(sizeof (void *) * (n_old + n_new));
+ new_info_table = mem_sys_allocate(sizeof (op_info_t) * (n_old + n_new));
+ /* copy old */
+ for (i = 0; i < n_old; ++i) {
+ new_func_table[i] = interpreter->op_func_table[i];
+ new_info_table[i] = interpreter->op_info_table[i];
+ }
+ /* add new */
+ for (i = n_old; i < n_old + n_new; ++i) {
+ new_func_table[i] = ((op_func_t*)lib->op_func_table)[i - n_old];
+ new_info_table[i] = lib->op_info_table[i - n_old];
+ }
+ core = PARROT_CORE_OPLIB_INIT(1);
+ /*
+ * deinit core, so that it gets rehashed
+ */
+ (void) PARROT_CORE_OPLIB_INIT(0);
+ /* set table */
+ core->op_func_table = interpreter->op_func_table = new_func_table;
+ core->op_info_table = interpreter->op_info_table = new_info_table;
+ core->op_count = interpreter->op_count = n_old + n_new;
+ /* done for plain core */
+}
/*
* Local variables:
1.51 +9 -7 parrot/ops2c.pl
Index: ops2c.pl
===================================================================
RCS file: /cvs/public/parrot/ops2c.pl,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -w -r1.50 -r1.51
--- ops2c.pl 14 Oct 2003 07:40:31 -0000 1.50
+++ ops2c.pl 14 Oct 2003 12:29:09 -0000 1.51
@@ -5,7 +5,7 @@
# Generate a C header and source file from the operation definitions in
# an .ops file, using a supplied transform.
#
-# $Id: ops2c.pl,v 1.50 2003/10/14 07:40:31 leo Exp $
+# $Id: ops2c.pl,v 1.51 2003/10/14 12:29:09 leo Exp $
#
use strict;
@@ -398,7 +398,7 @@
}
-if ($suffix eq '' && !$dynamic) {
+if ($suffix eq '') {
$op_info = 'op_info_table';
$getop = 'get_op';
#
@@ -481,6 +481,7 @@
static void hop_init(void);
static size_t hash_str(const char * str);
static void store_op(op_info_t *info, int full);
+static op_lib_t op_lib;
/* XXX on changing interpreters, this should be called,
through a hook */
@@ -524,18 +525,18 @@
}
for(p = hop[hidx]; p; p = p->next) {
if(!strcmp(name, full ? p->info->full_name : p->info->name))
- return p->info - op_info_table;
+ return p->info - op_lib.op_info_table;
}
return -1;
}
static void hop_init() {
size_t i;
- op_info_t * info = op_info_table;
+ op_info_t * info = op_lib.op_info_table;
/* store full names */
- for (i = 0; i < NUM_OPS; i++)
+ for (i = 0; i < op_lib.op_count; i++)
store_op(info + i, 1);
/* plus one short name */
- for (i = 0; i < NUM_OPS; i++)
+ for (i = 0; i < op_lib.op_count; i++)
if (get_op(info[i].name, 0) == -1)
store_op(info + i, 0);
}
@@ -602,7 +603,7 @@
END_C
if ($dynamic) {
- my $load_func = "Parrot_lib_load_${base}${suffix}_ops";
+ my $load_func = "Parrot_lib_${base}${suffix}_ops_load";
print SOURCE <<END_C;
/*
* dynamic lib load function - called once
@@ -613,6 +614,7 @@
{
PMC *lib = pmc_new(interpreter, enum_class_ConstParrotLibrary);
lib->cache.struct_val = (void *) $init_func;
+ dynop_register(interpreter, lib);
return lib;
}
END_C