Skip to content

Instantly share code, notes, and snippets.

@rectang
Created May 27, 2015 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rectang/003f7095b0fb3c743c78 to your computer and use it in GitHub Desktop.
Save rectang/003f7095b0fb3c743c78 to your computer and use it in GitHub Desktop.
Interdiff from CLOWNFISH-47-fix-final-methods to CLOWNFISH-47-fix-final-methods-v2
diff --git a/compiler/src/CFCBindMethod.c b/compiler/src/CFCBindMethod.c
index f6ff216..925f481 100644
--- a/compiler/src/CFCBindMethod.c
+++ b/compiler/src/CFCBindMethod.c
@@ -25,6 +25,7 @@
#include "CFCVariable.h"
#include "CFCSymbol.h"
#include "CFCClass.h"
+#include "CFCParcel.h"
#ifndef true
#define true 1
@@ -51,9 +52,9 @@ S_virtual_method_def(CFCMethod *method, CFCClass *klass) {
char*
CFCBindMeth_method_def(CFCMethod *method, CFCClass *klass) {
- // If the method is final and the implementing function is in the same
- // parcel as the invocant, we can optimize the call by resolving to the
- // implementing function directly.
+ // If the method is final and the class where it is declared final is in
+ // the same parcel as the invocant, we can optimize the call by resolving
+ // to the implementing function directly.
if (CFCMethod_final(method)) {
CFCClass *ancestor = klass;
while (ancestor && !CFCMethod_is_fresh(method, ancestor)) {
@@ -94,27 +95,35 @@ S_method_def(CFCMethod *method, CFCClass *klass, int optimized_final_meth) {
const char *ret_type_str = CFCType_to_c(return_type);
const char *maybe_return = CFCType_is_void(return_type) ? "" : "return ";
- char *innards;
+ const char innards_pattern[] =
+ " const %s method = (%s)cfish_obj_method(%s, %s);\n"
+ " %smethod(%s);\n"
+ ;
+ char *innards = CFCUtil_sprintf(innards_pattern, full_typedef,
+ full_typedef, self_name, full_offset_sym,
+ maybe_return, arg_names);
if (optimized_final_meth) {
+ CFCParcel *parcel = CFCClass_get_parcel(klass);
+ const char *privacy_sym = CFCParcel_get_privacy_sym(parcel);
char *invoker_cast = CFCUtil_strdup("");
if (!CFCMethod_is_fresh(method, klass)) {
CFCType *self_type = CFCMethod_self_type(method);
invoker_cast = CFCUtil_cat(invoker_cast, "(",
CFCType_to_c(self_type), ")", NULL);
}
- const char pattern[] = " %s%s(%s%s);\n";
- innards = CFCUtil_sprintf(pattern, maybe_return, full_imp_sym,
- invoker_cast, arg_names);
- FREEMEM(invoker_cast);
- }
- else {
const char pattern[] =
- " const %s method = (%s)cfish_obj_method(%s, %s);\n"
- " %smethod(%s);\n"
+ "#ifdef %s\n"
+ " %s%s(%s%s);\n"
+ "#else\n"
+ "%s"
+ "#endif\n"
;
- innards = CFCUtil_sprintf(pattern, full_typedef, full_typedef,
- self_name, full_offset_sym, maybe_return,
- arg_names);
+ char *temp = CFCUtil_sprintf(pattern, privacy_sym,
+ maybe_return, full_imp_sym,
+ invoker_cast, arg_names, innards);
+ FREEMEM(innards);
+ innards = temp;
+ FREEMEM(invoker_cast);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment