Author: leo
Date: Mon Apr 18 08:33:23 2005
New Revision: 7863
Modified:
trunk/include/parrot/mmd.h
trunk/include/parrot/objects.h
trunk/src/global.c
trunk/src/global_setup.c
trunk/src/mmd.c
trunk/src/objects.c
trunk/t/pmc/mmd.t
Log:
MMD 29 - overload a builtin multi sub
* invalidate (clear) MMD_table if a builtin is overloaded
* fix a typo
Modified: trunk/include/parrot/mmd.h
==============================================================================
--- trunk/include/parrot/mmd.h (original)
+++ trunk/include/parrot/mmd.h Mon Apr 18 08:33:23 2005
@@ -67,7 +67,8 @@
/*
* in src/objects.c :
*/
-const char* Parrot_MMD_methode_name(Interp* i, INTVAL idx);
+const char* Parrot_MMD_method_name(Interp* i, INTVAL idx);
+INTVAL Parrot_MMD_method_idx(Interp* interpreter, char *name);
#endif /* PARROT_MMD_H_GUARD */
Modified: trunk/include/parrot/objects.h
==============================================================================
--- trunk/include/parrot/objects.h (original)
+++ trunk/include/parrot/objects.h Mon Apr 18 08:33:23 2005
@@ -60,7 +60,7 @@
void Parrot_set_class_constructor(Parrot_Interp, STRING *, INTVAL, STRING *);
void Parrot_set_class_destructor(Parrot_Interp, STRING *, INTVAL, STRING *);
void Parrot_set_class_fallback(Parrot_Interp, STRING *, INTVAL, STRING *);
-void Parrot_invalidate_method_cache(Interp*, STRING *class);
+void Parrot_invalidate_method_cache(Interp*, STRING *class, STRING *meth);
/* Objects, classes and PMCarrays all use the same data scheme:
* PMC_data() holds a malloced array, PMC_int_val() is the size of it
Modified: trunk/src/global.c
==============================================================================
--- trunk/src/global.c (original)
+++ trunk/src/global.c Mon Apr 18 08:33:23 2005
@@ -292,7 +292,7 @@
else
stash = globals;
VTABLE_set_pmc_keyed_str(interpreter, stash, globalname, pmc);
- Parrot_invalidate_method_cache(interpreter, class);
+ Parrot_invalidate_method_cache(interpreter, class, globalname);
}
static void
@@ -398,6 +398,8 @@
STRING* sub_name;
PMC *multi_sig;
PMC *name_space;
+ INTVAL func_nr;
+ char *c_meth;
sub_name = PMC_sub(sub_pmc)->name;
name_space = PMC_sub(sub_pmc)->name_space;
@@ -418,6 +420,12 @@
VTABLE_push_pmc(interpreter, multi_sub, sub_pmc);
long_name = Parrot_multi_long_name(interpreter, sub_pmc);
store_sub_in_namespace(interpreter, sub_pmc, name_space, long_name);
+
+ c_meth = string_to_cstring(interpreter, sub_name);
+ if ( (func_nr = Parrot_MMD_method_idx(interpreter, c_meth)) >= 0) {
+ Parrot_mmd_rebuild_table(interpreter, -1, func_nr);
+ }
+ string_cstring_free(c_meth);
}
}
Modified: trunk/src/global_setup.c
==============================================================================
--- trunk/src/global_setup.c (original)
+++ trunk/src/global_setup.c Mon Apr 18 08:33:23 2005
@@ -66,8 +66,6 @@
/* Call base vtable class constructor methods */
Parrot_initialize_core_pmcs(interpreter);
- /* Create MMD_table for all MMD functions */
- Parrot_mmd_rebuild_table(interpreter, -1, -1);
iglobals = interpreter->iglobals;
VTABLE_set_pmc_keyed_int(interpreter, iglobals,
Modified: trunk/src/mmd.c
==============================================================================
--- trunk/src/mmd.c (original)
+++ trunk/src/mmd.c Mon Apr 18 08:33:23 2005
@@ -137,7 +137,7 @@
func = table->mmd_funcs[offset];
}
if (!func) {
- const char *meth_c = Parrot_MMD_methode_name(interpreter, func_nr);
+ const char *meth_c = Parrot_MMD_method_name(interpreter, func_nr);
STRING *meth_s = const_string(interpreter, meth_c);
PMC *method = Parrot_MMD_search_default_infix(interpreter,
meth_s, left_type, r);
@@ -1649,7 +1649,7 @@
STRING *s, *ns;
PMC *multi;
- name = Parrot_MMD_methode_name(interpreter, func_nr);
+ name = Parrot_MMD_method_name(interpreter, func_nr);
ns = CONST_STRING(interpreter, "__parrot_core");
s = const_string(interpreter, name);
/* create in constant pool */
@@ -1670,7 +1670,7 @@
type != enum_class_Ref && type != enum_class_SharedRef &&
type != enum_class_deleg_pmc && type != enum_class_ParrotClass &&
type != enum_class_ParrotObject);
- short_name = Parrot_MMD_methode_name(interpreter, func_nr);
+ short_name = Parrot_MMD_method_name(interpreter, func_nr);
/*
* _int, _float, _str are just native variants of the base
* multi
@@ -1813,8 +1813,21 @@
void
Parrot_mmd_rebuild_table(Interp* interpreter, INTVAL type, INTVAL func_nr)
{
- /* TODO invalidate table */
- return;
+ MMD_table *table;
+ UINTVAL i;
+
+ if (!interpreter->binop_mmd_funcs)
+ return;
+ table = interpreter->binop_mmd_funcs + func_nr;
+ if (!table)
+ return;
+
+ /* TODO specific parts of table
+ * the type and it's mro and
+ * all classes that inherit from type
+ */
+ for (i = 0; i < table->x * table->y; ++i)
+ table->mmd_funcs[i] = NULL;
}
/*
Modified: trunk/src/objects.c
==============================================================================
--- trunk/src/objects.c (original)
+++ trunk/src/objects.c Mon Apr 18 08:33:23 2005
@@ -243,15 +243,21 @@
/*
-=item C<const char* Parrot_MMD_methode_name(Interp*, INTVAL)>
+=item C<const char* Parrot_MMD_method_name(Interp*, INTVAL)>
Return the method name for the given MMD enum.
+=item C<INTVAL Parrot_MMD_method_idx(Interp*, STRING *)>
+
+Return the MMD function number for method name or -1 on failure.
+
+TODO allow dynamic expansion at runtime.
+
=cut
*/
const char*
-Parrot_MMD_methode_name(Interp* interpreter, INTVAL idx)
+Parrot_MMD_method_name(Interp* interpreter, INTVAL idx)
{
assert(idx >= 0);
@@ -260,6 +266,19 @@
return Parrot_mmd_func_names[idx];
}
+INTVAL
+Parrot_MMD_method_idx(Interp* interpreter, char *name)
+{
+ INTVAL i;
+
+ for (i = 0; i < MMD_USER_FIRST; ++i) {
+ if (!strcmp(Parrot_mmd_func_names[i], name))
+ return i;
+ }
+ return -1;
+}
+
+
/*
=item C<PMC *
@@ -1006,7 +1025,7 @@
}
void
-Parrot_invalidate_method_cache(Interp *interpreter, STRING *class)
+Parrot_invalidate_method_cache(Interp *interpreter, STRING *class, STRING
*meth)
{
INTVAL type;
Modified: trunk/t/pmc/mmd.t
==============================================================================
--- trunk/t/pmc/mmd.t (original)
+++ trunk/t/pmc/mmd.t Mon Apr 18 08:33:23 2005
@@ -16,7 +16,7 @@
=cut
-use Parrot::Test tests => 24;
+use Parrot::Test tests => 25;
pir_output_is(<<'CODE', <<'OUTPUT', "PASM divide");
@@ -807,5 +807,40 @@
.end
CODE
62
+2
+OUTPUT
+
+## my $temp = "temp.imc";
+## END { unlink $temp; };
+
+open P, ">$temp" or die "can't write $temp";
+print P <<'EOF';
+.namespace ["__parrot_core"]
+.sub __add @MULTI(Integer, Integer)
+ .param pmc l
+ .param pmc r
+ print l
+ print r
+ print "\n"
+ $P0 = new Integer
+ $P0 = 2
+ .return($P0)
+.end
+EOF
+
+pir_output_is(<<'CODE', <<'OUTPUT', "override builtin n_add");
+.sub main
+ load_bytecode "temp.imc"
+ $P0 = new Integer
+ $P1 = new Integer
+ set $P0, 6
+ set $P1, 2
+
+ $P2 = n_add $P0, $P1
+ print $P2
+ print "\n"
+.end
+CODE
+62
2
OUTPUT