Merge Perl callback and boot code
Merge callback and boot code into a single .c and .h file per parcel
named ${parcel_nick}_perl.[ch].
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/37aa3d30
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/37aa3d30
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/37aa3d30
Branch: refs/heads/master
Commit: 37aa3d302c2ce0ad3f8b9d9e4a2f9d8dcb99eadd
Parents: 3c18e2f
Author: Nick Wellnhofer <[email protected]>
Authored: Mon May 30 14:18:30 2016 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Mon May 30 14:18:30 2016 +0200
----------------------------------------------------------------------
compiler/perl/lib/Clownfish/CFC.xs | 10 +-
compiler/perl/lib/Clownfish/CFC/Perl/Build.pm | 3 +-
compiler/src/CFCPerl.c | 270 +++++++++------------
compiler/src/CFCPerl.h | 17 +-
runtime/common/charmonizer.c | 5 +-
runtime/common/charmonizer.main | 5 +-
6 files changed, 130 insertions(+), 180 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37aa3d30/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs
b/compiler/perl/lib/Clownfish/CFC.xs
index 3a60db1..52cb5f5 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -1972,10 +1972,10 @@ CODE:
OUTPUT: RETVAL
void
-write_boot(self)
+write_host_code(self)
CFCPerl *self;
PPCODE:
- CFCPerl_write_boot(self);
+ CFCPerl_write_host_code(self);
void
write_hostdefs(self)
@@ -1990,12 +1990,6 @@ PPCODE:
CFCPerl_write_bindings(self);
void
-write_callbacks(self)
- CFCPerl *self;
-PPCODE:
- CFCPerl_write_callbacks(self);
-
-void
write_xs_typemap(self)
CFCPerl *self;
PPCODE:
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37aa3d30/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
index 6f2557a..045c0aa 100644
--- a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
+++ b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
@@ -310,8 +310,7 @@ sub ACTION_clownfish {
if ( $cfh_modified || $buildlib_modified ) {
$self->add_to_cleanup($xs_filepath);
- $perl_binding->write_callbacks;
- $perl_binding->write_boot;
+ $perl_binding->write_host_code;
$perl_binding->write_hostdefs;
$perl_binding->write_bindings;
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37aa3d30/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c
index 284fdc5..d14cf84 100644
--- a/compiler/src/CFCPerl.c
+++ b/compiler/src/CFCPerl.c
@@ -65,9 +65,6 @@ S_write_class_pod(CFCPerl *self);
static CFCPerlPodFile*
S_write_standalone_pod(CFCPerl *self);
-static void
-S_write_callbacks_c(CFCPerl *self);
-
static const CFCMeta CFCPERL_META = {
"Clownfish::CFC::Binding::Perl",
sizeof(CFCPerl),
@@ -265,7 +262,7 @@ S_write_standalone_pod(CFCPerl *self) {
}
static void
-S_write_boot_h(CFCPerl *self, CFCParcel *parcel) {
+S_write_host_h(CFCPerl *self, CFCParcel *parcel) {
const char *prefix = CFCParcel_get_prefix(parcel);
const char *PREFIX = CFCParcel_get_PREFIX(parcel);
@@ -296,21 +293,23 @@ S_write_boot_h(CFCPerl *self, CFCParcel *parcel) {
self->c_footer);
const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);
- char *boot_h_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%sboot.h", inc_dest,
+ char *host_h_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%sperl.h", inc_dest,
prefix);
- CFCUtil_write_file(boot_h_path, content, strlen(content));
- FREEMEM(boot_h_path);
+ CFCUtil_write_file(host_h_path, content, strlen(content));
+ FREEMEM(host_h_path);
FREEMEM(content);
FREEMEM(guard);
}
static void
-S_write_boot_c(CFCPerl *self, CFCParcel *parcel) {
+S_write_host_c(CFCPerl *self, CFCParcel *parcel) {
CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
- const char *prefix = CFCParcel_get_prefix(parcel);
- char *alias_adds = CFCUtil_strdup("");
- char *isa_pushes = CFCUtil_strdup("");
+ const char *prefix = CFCParcel_get_prefix(parcel);
+ char *includes = CFCUtil_strdup("");
+ char *cb_defs = CFCUtil_strdup("");
+ char *alias_adds = CFCUtil_strdup("");
+ char *isa_pushes = CFCUtil_strdup("");
for (size_t i = 0; ordered[i] != NULL; i++) {
CFCClass *klass = ordered[i];
@@ -320,6 +319,23 @@ S_write_boot_c(CFCPerl *self, CFCParcel *parcel) {
const char *class_name = CFCClass_get_name(klass);
+ const char *include_h = CFCClass_include_h(klass);
+ includes = CFCUtil_cat(includes, "#include \"", include_h,
+ "\"\n", NULL);
+
+ // Callbacks.
+ CFCMethod **fresh_methods = CFCClass_fresh_methods(klass);
+ for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
+ CFCMethod *method = fresh_methods[meth_num];
+
+ // Define callback.
+ if (CFCMethod_novel(method) && !CFCMethod_final(method)) {
+ char *cb_def = CFCPerlMethod_callback_def(method, klass);
+ cb_defs = CFCUtil_cat(cb_defs, cb_def, "\n", NULL);
+ FREEMEM(cb_def);
+ }
+ }
+
// Add class aliases.
CFCPerlClass *class_binding = CFCPerlClass_singleton(class_name);
if (class_binding) {
@@ -359,9 +375,12 @@ S_write_boot_c(CFCPerl *self, CFCParcel *parcel) {
const char pattern[] =
"%s"
"\n"
- "#include \"%sboot.h\"\n"
- "#include \"%sparcel.h\"\n"
+ "#include \"%sperl.h\"\n"
+ "#include \"XSBind.h\"\n"
"#include \"Clownfish/Class.h\"\n"
+ "#include \"Clownfish/Err.h\"\n"
+ "#include \"Clownfish/Obj.h\"\n"
+ "%s"
"\n"
"/* Avoid conflicts with Clownfish bool type. */\n"
"#define HAS_BOOL\n"
@@ -370,6 +389,80 @@ S_write_boot_c(CFCPerl *self, CFCParcel *parcel) {
"#include \"perl.h\"\n"
"#include \"XSUB.h\"\n"
"\n"
+ "static void\n"
+ "S_finish_callback_void(pTHX_ const char *meth_name) {\n"
+ " int count = call_method(meth_name, G_VOID | G_DISCARD);\n"
+ " if (count != 0) {\n"
+ " CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
+ " meth_name, (int32_t)count);\n"
+ " }\n"
+ " FREETMPS;\n"
+ " LEAVE;\n"
+ "}\n"
+ "\n"
+ "static CFISH_INLINE SV*\n"
+ "SI_do_callback_sv(pTHX_ const char *meth_name) {\n"
+ " int count = call_method(meth_name, G_SCALAR);\n"
+ " if (count != 1) {\n"
+ " CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
+ " meth_name, (int32_t)count);\n"
+ " }\n"
+ " dSP;\n"
+ " SV *return_sv = POPs;\n"
+ " PUTBACK;\n"
+ " return return_sv;\n"
+ "}\n"
+ "\n"
+ "static int64_t\n"
+ "S_finish_callback_i64(pTHX_ const char *meth_name) {\n"
+ " SV *return_sv = SI_do_callback_sv(aTHX_ meth_name);\n"
+ " int64_t retval;\n"
+ " if (sizeof(IV) == 8) {\n"
+ " retval = (int64_t)SvIV(return_sv);\n"
+ " }\n"
+ " else {\n"
+ " if (SvIOK(return_sv)) {\n"
+ " // It's already no more than 32 bits, so don't convert.\n"
+ " retval = SvIV(return_sv);\n"
+ " }\n"
+ " else {\n"
+ " // Maybe lossy.\n"
+ " double temp = SvNV(return_sv);\n"
+ " retval = (int64_t)temp;\n"
+ " }\n"
+ " }\n"
+ " FREETMPS;\n"
+ " LEAVE;\n"
+ " return retval;\n"
+ "}\n"
+ "\n"
+ "static double\n"
+ "S_finish_callback_f64(pTHX_ const char *meth_name) {\n"
+ " SV *return_sv = SI_do_callback_sv(aTHX_ meth_name);\n"
+ " double retval = SvNV(return_sv);\n"
+ " FREETMPS;\n"
+ " LEAVE;\n"
+ " return retval;\n"
+ "}\n"
+ "\n"
+ "static cfish_Obj*\n"
+ "S_finish_callback_obj(pTHX_ void *vself, const char *meth_name,\n"
+ " int nullable) {\n"
+ " SV *return_sv = SI_do_callback_sv(aTHX_ meth_name);\n"
+ " cfish_Obj *retval\n"
+ " = XSBind_perl_to_cfish_nullable(aTHX_ return_sv,
CFISH_OBJ);\n"
+ " FREETMPS;\n"
+ " LEAVE;\n"
+ " if (!nullable && !retval) {\n"
+ " CFISH_THROW(CFISH_ERR, \"%%o#%%s cannot return NULL\",\n"
+ " cfish_Obj_get_class_name((cfish_Obj*)vself),\n"
+ " meth_name);\n"
+ " }\n"
+ " return retval;\n"
+ "}\n"
+ "\n"
+ "%s"
+ "\n"
"void\n"
"%sbootstrap_perl() {\n"
" dTHX;\n"
@@ -383,19 +476,21 @@ S_write_boot_c(CFCPerl *self, CFCParcel *parcel) {
"\n"
"%s";
char *content
- = CFCUtil_sprintf(pattern, self->c_header, prefix, prefix,
+ = CFCUtil_sprintf(pattern, self->c_header, prefix, includes, cb_defs,
prefix, prefix, alias_adds, isa_pushes,
self->c_footer);
const char *src_dest = CFCHierarchy_get_source_dest(self->hierarchy);
- char *boot_c_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%sboot.c", src_dest,
+ char *host_c_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%sperl.c", src_dest,
prefix);
- CFCUtil_write_file(boot_c_path, content, strlen(content));
- FREEMEM(boot_c_path);
+ CFCUtil_write_file(host_c_path, content, strlen(content));
+ FREEMEM(host_c_path);
FREEMEM(content);
FREEMEM(isa_pushes);
FREEMEM(alias_adds);
+ FREEMEM(cb_defs);
+ FREEMEM(includes);
FREEMEM(ordered);
}
@@ -434,15 +529,15 @@ CFCPerl_write_hostdefs(CFCPerl *self) {
}
void
-CFCPerl_write_boot(CFCPerl *self) {
+CFCPerl_write_host_code(CFCPerl *self) {
CFCParcel **parcels = CFCParcel_all_parcels();
for (size_t i = 0; parcels[i]; ++i) {
CFCParcel *parcel = parcels[i];
if (!CFCParcel_included(parcel)) {
- S_write_boot_h(self, parcel);
- S_write_boot_c(self, parcel);
+ S_write_host_h(self, parcel);
+ S_write_host_c(self, parcel);
}
}
}
@@ -516,13 +611,13 @@ CFCPerl_write_bindings(CFCPerl *self) {
}
generated_xs = CFCUtil_cat(generated_xs, "\n", NULL);
- // Include XSBind.h and boot.h.
+ // Include XSBind.h and *_perl.h.
generated_xs = CFCUtil_cat(generated_xs, "#include \"XSBind.h\"\n", NULL);
for (size_t i = 0; parcels[i]; ++i) {
if (!CFCParcel_included(parcels[i])) {
const char *prefix = CFCParcel_get_prefix(parcels[i]);
generated_xs = CFCUtil_cat(generated_xs, "#include \"", prefix,
- "boot.h\"\n", NULL);
+ "perl.h\"\n", NULL);
}
}
@@ -599,137 +694,6 @@ CFCPerl_write_bindings(CFCPerl *self) {
}
void
-CFCPerl_write_callbacks(CFCPerl *self) {
- S_write_callbacks_c(self);
-}
-
-static void
-S_write_callbacks_c(CFCPerl *self) {
- CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
- char *includes = CFCUtil_strdup("");
- char *cb_defs = CFCUtil_strdup("");
-
- for (size_t i = 0; ordered[i] != NULL; i++) {
- CFCClass *klass = ordered[i];
- if (CFCClass_included(klass) || CFCClass_inert(klass)) { continue; }
-
- const char *include_h = CFCClass_include_h(klass);
- includes = CFCUtil_cat(includes, "#include \"", include_h,
- "\"\n", NULL);
-
- CFCMethod **fresh_methods = CFCClass_fresh_methods(klass);
- for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
- CFCMethod *method = fresh_methods[meth_num];
-
- // Define callback.
- if (CFCMethod_novel(method) && !CFCMethod_final(method)) {
- char *cb_def = CFCPerlMethod_callback_def(method, klass);
- cb_defs = CFCUtil_cat(cb_defs, cb_def, "\n", NULL);
- FREEMEM(cb_def);
- }
- }
- }
-
- static const char pattern[] =
- "%s"
- "\n"
- "#include \"XSBind.h\"\n"
- "#include \"Clownfish/Err.h\"\n"
- "#include \"Clownfish/Obj.h\"\n"
- "%s"
- "\n"
- "static void\n"
- "S_finish_callback_void(pTHX_ const char *meth_name) {\n"
- " int count = call_method(meth_name, G_VOID | G_DISCARD);\n"
- " if (count != 0) {\n"
- " CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
- " meth_name, (int32_t)count);\n"
- " }\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- "}\n"
- "\n"
- "static CFISH_INLINE SV*\n"
- "SI_do_callback_sv(pTHX_ const char *meth_name) {\n"
- " int count = call_method(meth_name, G_SCALAR);\n"
- " if (count != 1) {\n"
- " CFISH_THROW(CFISH_ERR, \"Bad callback to '%%s': %%i32\",\n"
- " meth_name, (int32_t)count);\n"
- " }\n"
- " dSP;\n"
- " SV *return_sv = POPs;\n"
- " PUTBACK;\n"
- " return return_sv;\n"
- "}\n"
- "\n"
- "static int64_t\n"
- "S_finish_callback_i64(pTHX_ const char *meth_name) {\n"
- " SV *return_sv = SI_do_callback_sv(aTHX_ meth_name);\n"
- " int64_t retval;\n"
- " if (sizeof(IV) == 8) {\n"
- " retval = (int64_t)SvIV(return_sv);\n"
- " }\n"
- " else {\n"
- " if (SvIOK(return_sv)) {\n"
- " // It's already no more than 32 bits, so don't convert.\n"
- " retval = SvIV(return_sv);\n"
- " }\n"
- " else {\n"
- " // Maybe lossy.\n"
- " double temp = SvNV(return_sv);\n"
- " retval = (int64_t)temp;\n"
- " }\n"
- " }\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- " return retval;\n"
- "}\n"
- "\n"
- "static double\n"
- "S_finish_callback_f64(pTHX_ const char *meth_name) {\n"
- " SV *return_sv = SI_do_callback_sv(aTHX_ meth_name);\n"
- " double retval = SvNV(return_sv);\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- " return retval;\n"
- "}\n"
- "\n"
- "static cfish_Obj*\n"
- "S_finish_callback_obj(pTHX_ void *vself, const char *meth_name,\n"
- " int nullable) {\n"
- " SV *return_sv = SI_do_callback_sv(aTHX_ meth_name);\n"
- " cfish_Obj *retval\n"
- " = XSBind_perl_to_cfish_nullable(aTHX_ return_sv,
CFISH_OBJ);\n"
- " FREETMPS;\n"
- " LEAVE;\n"
- " if (!nullable && !retval) {\n"
- " CFISH_THROW(CFISH_ERR, \"%%o#%%s cannot return NULL\",\n"
- " cfish_Obj_get_class_name((cfish_Obj*)vself),\n"
- " meth_name);\n"
- " }\n"
- " return retval;\n"
- "}\n"
- "\n"
- "%s" // Callback definitions.
- "%s" // Footer.
- "\n";
- char *content = CFCUtil_sprintf(pattern, self->c_header, includes, cb_defs,
- self->c_footer);
-
- // Write if changed.
- const char *src_dest = CFCHierarchy_get_source_dest(self->hierarchy);
- char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "callbacks.c",
- src_dest);
- CFCUtil_write_if_changed(filepath, content, strlen(content));
-
- FREEMEM(filepath);
- FREEMEM(content);
- FREEMEM(cb_defs);
- FREEMEM(includes);
- FREEMEM(ordered);
-}
-
-void
CFCPerl_write_xs_typemap(CFCPerl *self) {
CFCPerlTypeMap_write_xs_typemap(self->hierarchy);
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37aa3d30/compiler/src/CFCPerl.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerl.h b/compiler/src/CFCPerl.h
index eef10ac..ea8bf21 100644
--- a/compiler/src/CFCPerl.h
+++ b/compiler/src/CFCPerl.h
@@ -48,9 +48,9 @@ struct CFCHierarchy;
* # Generated by write_bindings()
* $lib_dir/Crustacean.xs
*
- * # Generated by write_boot()
- * $hierarchy_dest_dir/crust_boot.h
- * $hierarchy_dest_dir/crust_boot.c
+ * # Generated by write_host_code()
+ * $hierarchy_dest_dir/include/crust_perl.h
+ * $hierarchy_dest_dir/source/crust_perl.c
*/
/**
@@ -86,22 +86,17 @@ CFCPerl_destroy(CFCPerl *self);
char**
CFCPerl_write_pod(CFCPerl *self);
-/** Write out "boot" files to the Hierarchy's "dest_dir" which contain code
- * for bootstrapping Clownfish classes.
+/** Write out host-specific files to the Hierarchy's "dest_dir" which contain
+ * code for calling back from C into Perl and bootstrapping Clownfish classes.
*/
void
-CFCPerl_write_boot(CFCPerl *self);
+CFCPerl_write_host_code(CFCPerl *self);
/** Generate the XS bindings for all classes in the hierarchy.
*/
void
CFCPerl_write_bindings(CFCPerl *self);
-/** Generate routines which call back from C into Perl for all methods.
- */
-void
-CFCPerl_write_callbacks(CFCPerl *self);
-
/** Generate hostdefs file.
*/
void
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37aa3d30/runtime/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/runtime/common/charmonizer.c b/runtime/common/charmonizer.c
index 4cce9da..3ab542d 100644
--- a/runtime/common/charmonizer.c
+++ b/runtime/common/charmonizer.c
@@ -8354,11 +8354,10 @@ cfish_MakeFile_new(chaz_CLI *cli) {
}
else if (chaz_CLI_defined(cli, "enable-perl")) {
static const char *perl_autogen_src_files[] = {
- "callbacks",
- "cfish_boot",
"cfish_parcel",
- "testcfish_boot",
+ "cfish_perl",
"testcfish_parcel",
+ "testcfish_perl",
NULL
};
self->host_src_dir = "xs";
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/37aa3d30/runtime/common/charmonizer.main
----------------------------------------------------------------------
diff --git a/runtime/common/charmonizer.main b/runtime/common/charmonizer.main
index f065153..adcc95e 100644
--- a/runtime/common/charmonizer.main
+++ b/runtime/common/charmonizer.main
@@ -300,11 +300,10 @@ cfish_MakeFile_new(chaz_CLI *cli) {
}
else if (chaz_CLI_defined(cli, "enable-perl")) {
static const char *perl_autogen_src_files[] = {
- "callbacks",
- "cfish_boot",
"cfish_parcel",
- "testcfish_boot",
+ "cfish_perl",
"testcfish_parcel",
+ "testcfish_perl",
NULL
};
self->host_src_dir = "xs";