You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2014/07/29 00:26:28 UTC
[3/3] git commit: Cache novel method in CFCMethod
Cache novel method in CFCMethod
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/7744424b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/7744424b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/7744424b
Branch: refs/heads/overridden_aliases
Commit: 7744424b8fbc383fda910fc34c8def46e0b26c44
Parents: 811d2ef
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 26 20:20:00 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Jul 29 00:21:20 2014 +0200
----------------------------------------------------------------------
compiler/src/CFCClass.c | 15 ---------------
compiler/src/CFCClass.h | 6 ------
compiler/src/CFCMethod.c | 26 +++++++++++++++++++++++---
compiler/src/CFCMethod.h | 6 ++++++
compiler/src/CFCPerlClass.c | 16 ++--------------
5 files changed, 31 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7744424b/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index e896818..7322e22 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -664,21 +664,6 @@ CFCClass_fresh_member_vars(CFCClass *self) {
return (CFCVariable**)S_fresh_syms(self, (CFCSymbol**)self->member_vars);
}
-CFCMethod*
-CFCClass_find_novel_method(CFCClass *self, const char *sym) {
- if (!self->tree_grown) {
- CFCUtil_die("Can't call original_method before grow_tree");
- }
- CFCClass *ancestor = self;
- do {
- CFCMethod *method = CFCClass_method(ancestor, sym);
- if (method && CFCMethod_novel(method)) {
- return method;
- }
- } while (NULL != (ancestor = CFCClass_get_parent(ancestor)));
- return NULL;
-}
-
CFCClass**
CFCClass_children(CFCClass *self) {
return self->children;
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7744424b/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.h b/compiler/src/CFCClass.h
index 9dde5b4..78eefd0 100644
--- a/compiler/src/CFCClass.h
+++ b/compiler/src/CFCClass.h
@@ -133,12 +133,6 @@ CFCClass_method(CFCClass *self, const char *sym);
struct CFCMethod*
CFCClass_fresh_method(CFCClass *self, const char *sym);
-/** Traverse all ancestors to find the first class which declared the method
- * and return it. Cannot be called before grow_tree().
- */
-struct CFCMethod*
-CFCClass_find_novel_method(CFCClass *self, const char *sym);
-
/** Find the actual class of all object variables without prefix.
*/
void
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7744424b/compiler/src/CFCMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCMethod.c b/compiler/src/CFCMethod.c
index 9335577..0c89f68 100644
--- a/compiler/src/CFCMethod.c
+++ b/compiler/src/CFCMethod.c
@@ -36,6 +36,7 @@
struct CFCMethod {
CFCFunction function;
+ CFCMethod *novel_method;
char *macro_sym;
char *full_override_sym;
char *host_alias;
@@ -127,6 +128,7 @@ CFCMethod_init(CFCMethod *self, CFCParcel *parcel, const char *exposure,
}
}
+ self->novel_method = NULL;
self->macro_sym = CFCUtil_strdup(macro_sym);
self->full_override_sym = NULL;
self->host_alias = NULL;
@@ -155,6 +157,7 @@ CFCMethod_resolve_types(CFCMethod *self) {
void
CFCMethod_destroy(CFCMethod *self) {
+ CFCBase_decref((CFCBase*)self->novel_method);
FREEMEM(self->macro_sym);
FREEMEM(self->full_override_sym);
FREEMEM(self->host_alias);
@@ -234,6 +237,10 @@ CFCMethod_override(CFCMethod *self, CFCMethod *orig) {
// Mark the Method as no longer novel.
self->is_novel = false;
+
+ // Cache novel method.
+ CFCMethod *novel_method = orig->is_novel ? orig : orig->novel_method;
+ self->novel_method = (CFCMethod*)CFCBase_incref((CFCBase*)novel_method);
}
CFCMethod*
@@ -248,7 +255,8 @@ CFCMethod_finalize(CFCMethod *self) {
self->function.param_list,
self->function.docucomment, true,
self->is_abstract);
- finalized->is_novel = self->is_novel;
+ finalized->novel_method = self->novel_method;
+ finalized->is_novel = self->is_novel;
return finalized;
}
@@ -272,7 +280,8 @@ CFCMethod_set_host_alias(CFCMethod *self, const char *alias) {
const char*
CFCMethod_get_host_alias(CFCMethod *self) {
- return self->host_alias;
+ CFCMethod *novel_method = CFCMethod_find_novel_method(self);
+ return novel_method->host_alias;
}
void
@@ -286,7 +295,18 @@ CFCMethod_exclude_from_host(CFCMethod *self) {
int
CFCMethod_excluded_from_host(CFCMethod *self) {
- return self->is_excluded;
+ CFCMethod *novel_method = CFCMethod_find_novel_method(self);
+ return novel_method->is_excluded;
+}
+
+CFCMethod*
+CFCMethod_find_novel_method(CFCMethod *self) {
+ if (self->is_novel) {
+ return self;
+ }
+ else {
+ return self->novel_method;
+ }
}
static char*
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7744424b/compiler/src/CFCMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCMethod.h b/compiler/src/CFCMethod.h
index 54d7e38..dd39203 100644
--- a/compiler/src/CFCMethod.h
+++ b/compiler/src/CFCMethod.h
@@ -108,6 +108,12 @@ CFCMethod*
CFCMethod_finalize(CFCMethod *self);
/**
+ * Find the first declaration of the method in the class hierarchy.
+ */
+CFCMethod*
+CFCMethod_find_novel_method(CFCMethod *self);
+
+/**
* Create the symbol used to invoke the method without the parcel Prefix, e.g.
* "LobClaw_Pinch".
* @param invoker Class for which the symbol is created. If invoker is NULL,
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7744424b/compiler/src/CFCPerlClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlClass.c b/compiler/src/CFCPerlClass.c
index 9d52b16..db6edfc 100644
--- a/compiler/src/CFCPerlClass.c
+++ b/compiler/src/CFCPerlClass.c
@@ -258,20 +258,8 @@ CFCPerlClass_method_bindings(CFCClass *klass) {
// Skip private methods.
if (CFCSymbol_private((CFCSymbol*)method)) { continue; }
- CFCMethod *novel_method;
- if (CFCMethod_novel(method)) {
- novel_method = method;
- }
- else {
- const char *meth_name = CFCMethod_get_macro_sym(method);
- novel_method = CFCClass_find_novel_method(parent, meth_name);
- if (!novel_method) {
- CFCUtil_die("Novel method not found");
- }
- }
-
// Skip methods which have been explicitly excluded.
- if (CFCMethod_excluded_from_host(novel_method)) {
+ if (CFCMethod_excluded_from_host(method)) {
continue;
}
@@ -283,7 +271,7 @@ CFCPerlClass_method_bindings(CFCClass *klass) {
}
// See if the user wants the method to have a specific alias.
- const char *alias = CFCMethod_get_host_alias(novel_method);
+ const char *alias = CFCMethod_get_host_alias(method);
if (!alias) {
alias = CFCMethod_micro_sym(method);
}