You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2011/06/23 01:33:19 UTC
[lucy-commits] svn commit: r1138683 - in /incubator/lucy/trunk/clownfish: lib/Clownfish.xs
lib/Clownfish/Binding/Core/Method.pm src/CFCBindMethod.c src/CFCBindMethod.h
Author: marvin
Date: Wed Jun 22 23:33:18 2011
New Revision: 1138683
URL: http://svn.apache.org/viewvc?rev=1138683&view=rev
Log:
Port method_def() and its helper routines from
Clownfish::Binding::Core::Method to C.
Modified:
incubator/lucy/trunk/clownfish/lib/Clownfish.xs
incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Method.pm
incubator/lucy/trunk/clownfish/src/CFCBindMethod.c
incubator/lucy/trunk/clownfish/src/CFCBindMethod.h
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish.xs
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish.xs?rev=1138683&r1=1138682&r2=1138683&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish.xs (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish.xs Wed Jun 22 23:33:18 2011
@@ -1723,6 +1723,14 @@ CODE:
OUTPUT: RETVAL
SV*
+_method_def(meth, klass)
+ CFCMethod *meth;
+ CFCClass *klass;
+CODE:
+ RETVAL = S_sv_eat_c_string(CFCBindMeth_method_def(meth, klass));
+OUTPUT: RETVAL
+
+SV*
_callback_obj_def(meth, offset)
CFCMethod *meth;
const char *offset;
Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Method.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Method.pm?rev=1138683&r1=1138682&r2=1138683&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Method.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Binding/Core/Method.pm Wed Jun 22 23:33:18 2011
@@ -21,67 +21,8 @@ use Clownfish::Util qw( a_isa_b );
use Carp;
sub method_def {
- my ( undef, %args ) = @_;
- my ( $method, $class ) = @args{qw( method class )};
- confess("Not a Method")
- unless a_isa_b( $method, "Clownfish::Method" );
- confess("Not a Class")
- unless a_isa_b( $class, "Clownfish::Class" );
- if ( $method->final ) {
- return _final_method_def( $method, $class );
- }
- else {
- return _virtual_method_def( $method, $class );
- }
-}
-
-sub _virtual_method_def {
- my ( $method, $class ) = @_;
- my $cnick = $class->get_cnick;
- my $param_list = $method->get_param_list;
- my $invoker_struct = $class->full_struct_sym;
- my $common_struct = $method->self_type->get_specifier;
- my $full_method_sym = $method->full_method_sym($cnick);
- my $full_offset_sym = $method->full_offset_sym($cnick);
- my $typedef = $method->full_typedef;
- my $arg_names = $param_list->name_list;
- $arg_names =~ s/\s*\w+/self/;
-
- # Prepare the parameter list for the inline function.
- my $params = $param_list->to_c;
- $params =~ s/^.*?\*\s*\w+/const $invoker_struct *self/
- or confess("no match: $params");
-
- # Prepare a return statement... or not.
- my $return_type = $method->get_return_type->to_c;
- my $maybe_return = $method->get_return_type->is_void ? '' : 'return ';
-
- return <<END_STUFF;
-extern size_t $full_offset_sym;
-static CHY_INLINE $return_type
-$full_method_sym($params) {
- char *const method_address = *(char**)self + $full_offset_sym;
- const $typedef method = *(($typedef*)method_address);
- ${maybe_return}method(($common_struct*)$arg_names);
-}
-END_STUFF
-}
-
-# Create a macro definition that aliases to a function name directly, since
-# this method may not be overridden.
-sub _final_method_def {
- my ( $method, $class ) = @_;
- my $cnick = $class->get_cnick;
- my $macro_sym = $method->get_macro_sym;
- my $self_type = $method->self_type->to_c;
- my $full_method_sym = $method->full_method_sym($cnick);
- my $full_func_sym = $method->full_func_sym;
- my $arg_names = $method->get_param_list->name_list;
-
- return <<END_STUFF;
-#define $full_method_sym($arg_names) \\
- $full_func_sym(($self_type)$arg_names)
-END_STUFF
+ my ( undef, %args ) = @_;
+ return _method_def( @args{qw( method class )} );
}
sub callback_obj_def {
Modified: incubator/lucy/trunk/clownfish/src/CFCBindMethod.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindMethod.c?rev=1138683&r1=1138682&r2=1138683&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindMethod.c (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindMethod.c Wed Jun 22 23:33:18 2011
@@ -24,6 +24,15 @@
#include "CFCType.h"
#include "CFCVariable.h"
#include "CFCSymbol.h"
+#include "CFCClass.h"
+
+/* Create a macro definition that aliases to a function name directly, since
+ * this method may not be overridden. */
+static char*
+S_final_method_def(CFCMethod *method, CFCClass *klass);
+
+static char*
+S_virtual_method_def(CFCMethod *method, CFCClass *klass);
/* Take a NULL-terminated list of CFCVariables and build up a string of
* directives like:
@@ -70,6 +79,111 @@ static char*
S_obj_callback_def(CFCMethod *method, const char *callback_params);
char*
+CFCBindMeth_method_def(CFCMethod *method, CFCClass *klass) {
+ if (CFCMethod_final(method)) {
+ return S_final_method_def(method, klass);
+ }
+ else {
+ return S_virtual_method_def(method, klass);
+ }
+}
+
+/* Create a macro definition that aliases to a function name directly, since
+ * this method may not be overridden. */
+static char*
+S_final_method_def(CFCMethod *method, CFCClass *klass) {
+ const char *cnick = CFCClass_get_cnick(klass);
+ const char *self_type = CFCType_to_c(CFCMethod_self_type(method));
+ size_t meth_sym_size = CFCMethod_full_method_sym(method, cnick, NULL, 0);
+ char *full_meth_sym = (char*)MALLOCATE(meth_sym_size);
+ CFCMethod_full_method_sym(method, cnick, full_meth_sym, meth_sym_size);
+ const char *full_func_sym = CFCMethod_implementing_func_sym(method);
+ const char *arg_names
+ = CFCParamList_name_list(CFCMethod_get_param_list(method));
+
+ char pattern[] = "#define %s(%s) \\\n %s((%s)%s)\n";
+ size_t size = sizeof(pattern)
+ + strlen(full_meth_sym)
+ + strlen(arg_names)
+ + strlen(full_func_sym)
+ + strlen(self_type)
+ + strlen(arg_names)
+ + 20;
+ char *method_def = (char*)MALLOCATE(size);
+ sprintf(method_def, pattern, full_meth_sym, arg_names, full_func_sym,
+ self_type, arg_names);
+
+ FREEMEM(full_meth_sym);
+ return method_def;
+}
+
+static char*
+S_virtual_method_def(CFCMethod *method, CFCClass *klass) {
+ const char *cnick = CFCClass_get_cnick(klass);
+ CFCParamList *param_list = CFCMethod_get_param_list(method);
+ const char *invoker_struct = CFCClass_full_struct_sym(klass);
+ const char *common_struct
+ = CFCType_get_specifier(CFCMethod_self_type(method));
+ const char *typedef_str = CFCMethod_full_typedef(method);
+
+ size_t meth_sym_size = CFCMethod_full_method_sym(method, cnick, NULL, 0);
+ char *full_meth_sym = (char*)MALLOCATE(meth_sym_size);
+ CFCMethod_full_method_sym(method, cnick, full_meth_sym, meth_sym_size);
+
+ size_t offset_sym_size = CFCMethod_full_offset_sym(method, cnick, NULL, 0);
+ char *full_offset_sym = (char*)MALLOCATE(offset_sym_size);
+ CFCMethod_full_offset_sym(method, cnick, full_offset_sym, offset_sym_size);
+
+ // Prepare parameter lists, minus invoker. The invoker gets forced to
+ // "self" later.
+ const char *arg_names_minus_invoker = CFCParamList_name_list(param_list);
+ const char *params_minus_invoker = CFCParamList_to_c(param_list);
+ while (*arg_names_minus_invoker && *arg_names_minus_invoker != ',') {
+ arg_names_minus_invoker++;
+ }
+ while (*params_minus_invoker && *params_minus_invoker != ',') {
+ params_minus_invoker++;
+ }
+
+ // Prepare a return statement... or not.
+ CFCType *return_type = CFCMethod_get_return_type(method);
+ const char *ret_type_str = CFCType_to_c(return_type);
+ const char *maybe_return = CFCType_is_void(return_type) ? "" : "return ";
+
+ const char pattern[] =
+ "extern size_t %s;\n"
+ "static CHY_INLINE %s\n"
+ "%s(const %s *self%s) {\n"
+ " char *const method_address = *(char**)self + %s;\n"
+ " const %s method = *((%s*)method_address);\n"
+ " %smethod((%s*)self%s);\n"
+ "}\n";
+
+ size_t size = sizeof(pattern)
+ + strlen(full_offset_sym)
+ + strlen(ret_type_str)
+ + strlen(full_meth_sym)
+ + strlen(invoker_struct)
+ + strlen(params_minus_invoker)
+ + strlen(full_offset_sym)
+ + strlen(typedef_str)
+ + strlen(typedef_str)
+ + strlen(maybe_return)
+ + strlen(common_struct)
+ + strlen(arg_names_minus_invoker)
+ + 40;
+ char *method_def = (char*)MALLOCATE(size);
+ sprintf(method_def, pattern, full_offset_sym, ret_type_str,
+ full_meth_sym, invoker_struct, params_minus_invoker,
+ full_offset_sym, typedef_str, typedef_str, maybe_return,
+ common_struct, arg_names_minus_invoker);
+
+ FREEMEM(full_offset_sym);
+ FREEMEM(full_meth_sym);
+ return method_def;
+}
+
+char*
CFCBindMeth_typdef_dec(struct CFCMethod *method) {
const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method));
const char *ret_type = CFCType_to_c(CFCMethod_get_return_type(method));
Modified: incubator/lucy/trunk/clownfish/src/CFCBindMethod.h
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/src/CFCBindMethod.h?rev=1138683&r1=1138682&r2=1138683&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/src/CFCBindMethod.h (original)
+++ incubator/lucy/trunk/clownfish/src/CFCBindMethod.h Wed Jun 22 23:33:18 2011
@@ -22,6 +22,10 @@ extern "C" {
#endif
struct CFCMethod;
+struct CFCClass;
+
+char*
+CFCBindMeth_method_def(struct CFCMethod *method, struct CFCClass *klass);
char*
CFCBindMeth_typdef_dec(struct CFCMethod *method);