[11/14] lucy-clownfish git commit: Fix conv warnings in CFC test suite.

2016-03-19 Thread marvin
Fix conv warnings in CFC test suite.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/9b7678b1
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/9b7678b1
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/9b7678b1

Branch: refs/heads/master
Commit: 9b7678b10f06f4ebe320ca8a14012d2291554e0c
Parents: 9d3aef8
Author: Marvin Humphrey 
Authored: Sat Mar 19 22:31:29 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 compiler/src/CFCTestParamList.c | 4 ++--
 compiler/src/CFCTestParser.c| 6 +++---
 compiler/src/CFCTestUtil.c  | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9b7678b1/compiler/src/CFCTestParamList.c
--
diff --git a/compiler/src/CFCTestParamList.c b/compiler/src/CFCTestParamList.c
index 9dab0b8..5a375af 100644
--- a/compiler/src/CFCTestParamList.c
+++ b/compiler/src/CFCTestParamList.c
@@ -60,7 +60,7 @@ S_run_tests(CFCTest *test) {
 OK(test, CFCParamList_variadic(param_list), "variadic");
 STR_EQ(test, CFCParamList_to_c(param_list),
"neato_Obj* self, int num, ...", "to_c");
-INT_EQ(test, CFCParamList_num_vars(param_list), 2, "num_vars");
+UINT_EQ(test, CFCParamList_num_vars(param_list), 2, "num_vars");
 const char **initial_values
 = CFCParamList_get_initial_values(param_list);
 STR_EQ(test, initial_values[0], "NULL", "initial_values[0]"); 
@@ -78,7 +78,7 @@ S_run_tests(CFCTest *test) {
 = CFCTest_parse_param_list(test, parser, "()");
 CFCParamList_resolve_types(param_list);
 STR_EQ(test, CFCParamList_to_c(param_list), "void", "to_c");
-INT_EQ(test, CFCParamList_num_vars(param_list), 0, "num_vars");
+UINT_EQ(test, CFCParamList_num_vars(param_list), 0, "num_vars");
 CFCVariable **variables = CFCParamList_get_variables(param_list);
 OK(test, variables[0] == NULL, "get_variables");
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9b7678b1/compiler/src/CFCTestParser.c
--
diff --git a/compiler/src/CFCTestParser.c b/compiler/src/CFCTestParser.c
index 057d5d9..2219dba 100644
--- a/compiler/src/CFCTestParser.c
+++ b/compiler/src/CFCTestParser.c
@@ -228,12 +228,12 @@ S_run_tests(CFCTest *test) {
 "(int foo)",
 "(Obj *foo, Foo **foo_ptr)"
 };
-for (int i = 0; i < 3; ++i) {
+for (size_t i = 0; i < 3; ++i) {
 const char *param_list_string = param_list_strings[i];
 CFCParamList *param_list
 = CFCTest_parse_param_list(test, parser, param_list_string);
-INT_EQ(test, CFCParamList_num_vars(param_list), i,
-   "param list num_vars: %d", i);
+UINT_EQ(test, CFCParamList_num_vars(param_list), i,
+"param list num_vars: %u", (unsigned)i);
 CFCBase_decref((CFCBase*)param_list);
 }
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9b7678b1/compiler/src/CFCTestUtil.c
--
diff --git a/compiler/src/CFCTestUtil.c b/compiler/src/CFCTestUtil.c
index fd431e3..77e7c7b 100644
--- a/compiler/src/CFCTestUtil.c
+++ b/compiler/src/CFCTestUtil.c
@@ -76,7 +76,7 @@ S_run_file_tests(CFCTest *test) {
 OK(test, file != NULL, "can open file");
 char buf[10];
 size_t chars_read = fread(buf, 1, 10, file);
-INT_EQ(test, chars_read, 3, "read correct number of chars");
+UINT_EQ(test, chars_read, 3, "read correct number of chars");
 OK(test, memcmp(buf, "foo", 3) == 0, "read correct string");
 
 long file_length = CFCUtil_flength(file);
@@ -88,7 +88,7 @@ S_run_file_tests(CFCTest *test) {
 {
 size_t content_len;
 char *content = CFCUtil_slurp_text(foo_txt, &content_len);
-INT_EQ(test, content_len, 3, "slurp_text len");
+UINT_EQ(test, content_len, 3, "slurp_text len");
 OK(test, memcmp(content, "foo", 3) == 0, "slurp_text content");
 FREEMEM(content);
 }



[04/14] lucy-clownfish git commit: Fix some `unused` warnings in the Perl bindings.

2016-03-19 Thread marvin
Fix some `unused` warnings in the Perl bindings.

Have the code generator emit some temp variables only if they are
needed.  Deploy one UNUSED_VAR macro.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/338ab9f6
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/338ab9f6
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/338ab9f6

Branch: refs/heads/master
Commit: 338ab9f6c61a4cf71edde1068de88b4cb77f2fe6
Parents: f35c02d
Author: Marvin Humphrey 
Authored: Wed Mar 16 00:35:55 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:42:44 2016 -0700

--
 compiler/src/CFCPerlConstructor.c   |  4 ++--
 compiler/src/CFCPerlMethod.c| 23 +++-
 .../perl/buildlib/Clownfish/Build/Binding.pm|  1 +
 3 files changed, 20 insertions(+), 8 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/338ab9f6/compiler/src/CFCPerlConstructor.c
--
diff --git a/compiler/src/CFCPerlConstructor.c 
b/compiler/src/CFCPerlConstructor.c
index c0c3a89..380cb08 100644
--- a/compiler/src/CFCPerlConstructor.c
+++ b/compiler/src/CFCPerlConstructor.c
@@ -118,7 +118,8 @@ CFCPerlConstructor_xsub_def(CFCPerlConstructor *self, 
CFCClass *klass) {
 unsigned num_params = num_vars - 1;
 items_check = "items < 1";
 param_specs = CFCPerlSub_build_param_specs((CFCPerlSub*)self, 1);
-locs_decl   = CFCUtil_sprintf("int32_t locations[%u];\n",
+locs_decl   = CFCUtil_sprintf("int32_t locations[%u];\n"
+  "SV *sv;\n",
   num_params);
 
 const char *pattern =
@@ -146,7 +147,6 @@ CFCPerlConstructor_xsub_def(CFCPerlConstructor *self, 
CFCClass *klass) {
 "dXSARGS;\n"
 "%s" // param_specs
 "%s" // locs_decl
-"SV *sv;\n"
 "%s" // arg_decls
 "%s retval;\n"
 "\n"

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/338ab9f6/compiler/src/CFCPerlMethod.c
--
diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c
index 08d32e2..c8281ee 100644
--- a/compiler/src/CFCPerlMethod.c
+++ b/compiler/src/CFCPerlMethod.c
@@ -258,13 +258,18 @@ S_xsub_def_labeled_params(CFCPerlMethod *self, CFCClass 
*klass) {
 retval_decl = CFCUtil_sprintf("%s retval;\n", return_type_c);
 }
 
+const char *locations_sv = "";
+if (num_vars > 1) {
+locations_sv = "SV *sv;\n";
+}
+
 char pattern[] =
 "XS(%s);\n"
 "XS(%s) {\n"
 "dXSARGS;\n"
 "%s"// param_specs
 "int32_t locations[%d];\n"
-"SV *sv;\n"
+"%s" // locations_sv
 "%s"// arg_decls
 "%s method;\n"
 "%s"
@@ -286,8 +291,9 @@ S_xsub_def_labeled_params(CFCPerlMethod *self, CFCClass 
*klass) {
 "}\n";
 char *xsub_def
 = CFCUtil_sprintf(pattern, c_name, c_name, param_specs, num_vars - 1,
-  arg_decls, meth_type_c, retval_decl, self_name,
-  num_vars - 1, self_assign, arg_assigns, body);
+  locations_sv, arg_decls, meth_type_c, retval_decl,
+  self_name, num_vars - 1, self_assign, arg_assigns,
+  body);
 
 FREEMEM(param_specs);
 FREEMEM(arg_decls);
@@ -342,6 +348,10 @@ S_xsub_def_positional_args(CFCPerlMethod *self, CFCClass 
*klass) {
NULL);
 }
 }
+const char *working_sv = "";
+if (num_vars > 1) {
+working_sv = "SV *sv;\n";
+}
 
 char *retval_decl;
 if (CFCType_is_void(return_type)) {
@@ -356,7 +366,7 @@ S_xsub_def_positional_args(CFCPerlMethod *self, CFCClass 
*klass) {
 "XS(%s);\n"
 "XS(%s) {\n"
 "dXSARGS;\n"
-"SV *sv;\n"
+"%s" // working_sv
 "%s" // arg_decls
 "%s method;\n"
 "%s"
@@ -376,8 +386,9 @@ S_xsub_def_positional_args(CFCPerlMethod *self, CFCClass 
*klass) {
 "}\n";
 char *xsub
 = CFCUtil_sprintf(pattern, self->sub.c_name, self->sub.c_name,
-  arg_decls, meth_type_c, retval_decl, num_args_cond,
-  xs_name_list, self_assign, arg_assigns, body);
+  working_sv, arg_decls, meth_type_c, retval_decl,
+  num_args_cond, xs_name_list, self_assign,
+  arg_assigns, body);
 
 FREEMEM(arg_assigns);
 FREEMEM(arg_decls);

http://git-wip-us.apache.org/repos/asf/lucy-clown

[09/14] lucy-clownfish git commit: Address int warnings in Clownfish core.

2016-03-19 Thread marvin
Address int warnings in Clownfish core.

Clean up after adding `-Wconversion`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/840567ed
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/840567ed
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/840567ed

Branch: refs/heads/master
Commit: 840567edd83fc137692fb7f4c1661ffca7f33ad0
Parents: 91f0005
Author: Marvin Humphrey 
Authored: Sat Mar 19 01:17:18 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 runtime/core/Clownfish/ByteBuf.c   |  8 +++
 runtime/core/Clownfish/CharBuf.c   | 25 ++---
 runtime/core/Clownfish/Class.c |  6 ++---
 runtime/core/Clownfish/Obj.c   |  2 +-
 runtime/core/Clownfish/PtrHash.c   |  2 +-
 runtime/core/Clownfish/String.c|  6 ++---
 runtime/core/Clownfish/Test/TestHash.c |  6 ++---
 runtime/core/Clownfish/TestHarness/TestUtils.c | 16 ++---
 runtime/core/Clownfish/Util/SortUtils.c|  8 +++
 runtime/core/Clownfish/Util/StringHelper.c |  3 ++-
 10 files changed, 41 insertions(+), 41 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/840567ed/runtime/core/Clownfish/ByteBuf.c
--
diff --git a/runtime/core/Clownfish/ByteBuf.c b/runtime/core/Clownfish/ByteBuf.c
index 14ede6f..96d31b6 100644
--- a/runtime/core/Clownfish/ByteBuf.c
+++ b/runtime/core/Clownfish/ByteBuf.c
@@ -54,7 +54,7 @@ BB_new(size_t capacity) {
 ByteBuf*
 BB_init(ByteBuf *self, size_t min_cap) {
 // Round up to next multiple of eight.
-size_t capacity = (min_cap + 7) & ~7;
+size_t capacity = (min_cap + 7) & ((size_t)~7);
 // Check for overflow.
 if (capacity < min_cap) { capacity = SIZE_MAX; }
 
@@ -73,7 +73,7 @@ BB_new_bytes(const void *bytes, size_t size) {
 ByteBuf*
 BB_init_bytes(ByteBuf *self, const void *bytes, size_t size) {
 // Round up to next multiple of eight.
-size_t capacity = (size + 7) & ~7;
+size_t capacity = (size + 7) & ((size_t)~7);
 // Check for overflow.
 if (capacity < size) { capacity = SIZE_MAX; }
 
@@ -174,7 +174,7 @@ char*
 BB_Grow_IMP(ByteBuf *self, size_t min_cap) {
 if (min_cap > self->cap) {
 // Round up to next multiple of eight.
-size_t capacity = (min_cap + 7) & ~7;
+size_t capacity = (min_cap + 7) & ((size_t)~7);
 // Check for overflow.
 if (capacity < min_cap) { capacity = SIZE_MAX; }
 
@@ -236,7 +236,7 @@ S_grow_and_oversize(ByteBuf *self, size_t min_size) {
 // Oversize by 25%, but at least eight bytes.
 size_t extra = min_size / 4;
 // Round up to next multiple of eight.
-extra = (extra + 7) & ~7;
+extra = (extra + 7) & ((size_t)~7);
 
 size_t capacity = min_size + extra;
 // Check for overflow.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/840567ed/runtime/core/Clownfish/CharBuf.c
--
diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c
index 53541c2..3867249 100644
--- a/runtime/core/Clownfish/CharBuf.c
+++ b/runtime/core/Clownfish/CharBuf.c
@@ -20,6 +20,7 @@
 
 #include "charmony.h"
 
+#include 
 #include 
 #include 
 #include 
@@ -143,8 +144,8 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list 
args) {
 // Consume all characters leading up to a '%'.
 while (slice_end < pattern_end && *slice_end != '%') { slice_end++; }
 if (pattern != slice_end) {
-size_t size = slice_end - pattern;
-S_cat_utf8(self, pattern, size);
+ptrdiff_t size = slice_end - pattern;
+S_cat_utf8(self, pattern, (size_t)size);
 pattern = slice_end;
 }
 
@@ -173,7 +174,6 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list 
args) {
 break;
 case 'i': {
 int64_t val = 0;
-size_t size;
 if (pattern[1] == '8') {
 val = va_arg(args, int32_t);
 pattern++;
@@ -189,13 +189,12 @@ CB_VCatF_IMP(CharBuf *self, const char *pattern, va_list 
args) {
 else {
 S_die_invalid_pattern(pattern_start);
 }
-size = sprintf(buf, "%" PRId64, val);
-S_cat_utf8(self, buf, size);
+int size = sprintf(buf, "%" PRId64, val);
+S_cat_utf8(self, buf, (size_t)size);
 }
 break;
 case

[01/14] lucy-clownfish git commit: Remove unused static function `S_to_parcel`.

2016-03-19 Thread marvin
Repository: lucy-clownfish
Updated Branches:
  refs/heads/master b8d40d0ef -> c1ed8ee70


Remove unused static function `S_to_parcel`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/bf4723fc
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/bf4723fc
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/bf4723fc

Branch: refs/heads/master
Commit: bf4723fc2d3b4a110eb7b4b0dd7625df92d79ea1
Parents: b8d40d0
Author: Marvin Humphrey 
Authored: Tue Mar 15 23:50:39 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:42:22 2016 -0700

--
 compiler/python/src/cfc/_cfc.c | 6 --
 1 file changed, 6 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bf4723fc/compiler/python/src/cfc/_cfc.c
--
diff --git a/compiler/python/src/cfc/_cfc.c b/compiler/python/src/cfc/_cfc.c
index 24e45a4..0f6c882 100644
--- a/compiler/python/src/cfc/_cfc.c
+++ b/compiler/python/src/cfc/_cfc.c
@@ -91,12 +91,6 @@ S_to_Hierarchy(PyObject *wrapper) {
 "Clownfish::CFC::Model::Hierarchy");
 }
 
-static CFCParcel*
-S_to_Parcel(PyObject *wrapper) {
-return (CFCParcel*)S_to_cfc_something(wrapper,
-"Clownfish::CFC::Model::Parcel");
-}
-
 static CFCBindCore*
 S_to_BindCore(PyObject *wrapper) {
 return (CFCBindCore*)S_to_cfc_something(wrapper,



[14/14] lucy-clownfish git commit: Merge branch 'fixwarn2'

2016-03-19 Thread marvin
Merge branch 'fixwarn2'

Address many compiler warnings, particularly integer precision warnings
triggered by adding `-Wconversion`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/c1ed8ee7
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/c1ed8ee7
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/c1ed8ee7

Branch: refs/heads/master
Commit: c1ed8ee7027a2311fb6487ac8f055a4316117721
Parents: b8d40d0 9b7678b
Author: Marvin Humphrey 
Authored: Sat Mar 19 22:51:44 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:51:44 2016 -0700

--
 compiler/c/cfc.c|  5 +-
 compiler/python/src/cfc/_cfc.c  |  8 +---
 compiler/src/CFCBase.h  |  2 +-
 compiler/src/CFCCHtml.c |  9 ++--
 compiler/src/CFCClass.c |  2 +-
 compiler/src/CFCDocuComment.c   |  6 +--
 compiler/src/CFCFile.c  |  2 +-
 compiler/src/CFCGoFunc.c| 12 ++---
 compiler/src/CFCGoTypeMap.c |  8 ++--
 compiler/src/CFCParcel.c|  8 ++--
 compiler/src/CFCParser.c|  2 +-
 compiler/src/CFCPerl.c  |  2 +-
 compiler/src/CFCPerlConstructor.c   |  6 +--
 compiler/src/CFCPerlMethod.c| 25 +++---
 compiler/src/CFCPerlPod.c   |  6 +--
 compiler/src/CFCPerlSub.c   |  4 +-
 compiler/src/CFCPyClass.c   |  2 +-
 compiler/src/CFCPyMethod.c  | 32 ++---
 compiler/src/CFCPython.c|  4 +-
 compiler/src/CFCRuby.c  |  2 +-
 compiler/src/CFCTest.c  | 19 +++-
 compiler/src/CFCTest.h  | 13 -
 compiler/src/CFCTestParamList.c |  4 +-
 compiler/src/CFCTestParser.c|  6 +--
 compiler/src/CFCTestUtil.c  |  4 +-
 compiler/src/CFCType.c  |  4 +-
 compiler/src/CFCUtil.c  | 25 +-
 compiler/src/CFCVersion.c   |  3 +-
 runtime/core/Clownfish/ByteBuf.c|  8 ++--
 runtime/core/Clownfish/CharBuf.c| 25 +-
 runtime/core/Clownfish/Class.c  |  6 +--
 runtime/core/Clownfish/Obj.c|  2 +-
 runtime/core/Clownfish/PtrHash.c|  2 +-
 runtime/core/Clownfish/String.c |  6 +--
 runtime/core/Clownfish/Test/TestBlob.c  |  4 +-
 runtime/core/Clownfish/Test/TestByteBuf.c   |  8 ++--
 runtime/core/Clownfish/Test/TestHash.c  | 28 +--
 .../core/Clownfish/Test/TestLockFreeRegistry.c  |  2 +-
 runtime/core/Clownfish/Test/TestNum.c   |  2 +-
 runtime/core/Clownfish/Test/TestString.c| 50 ++--
 runtime/core/Clownfish/Test/TestVector.c| 34 ++---
 runtime/core/Clownfish/Test/Util/TestMemory.c   | 20 
 .../core/Clownfish/Test/Util/TestStringHelper.c | 12 ++---
 .../Clownfish/TestHarness/TestBatchRunner.c | 33 +++--
 .../Clownfish/TestHarness/TestBatchRunner.cfh   | 13 -
 runtime/core/Clownfish/TestHarness/TestUtils.c  | 16 +++
 runtime/core/Clownfish/Util/SortUtils.c |  8 ++--
 runtime/core/Clownfish/Util/StringHelper.c  |  3 +-
 .../perl/buildlib/Clownfish/Build/Binding.pm|  1 +
 runtime/python/setup.py |  2 +-
 50 files changed, 291 insertions(+), 219 deletions(-)
--




[05/14] lucy-clownfish git commit: Address int warnings in CFC.

2016-03-19 Thread marvin
Address int warnings in CFC.

Quiet warnings exposed by adding `-Wconversion`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/91f00051
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/91f00051
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/91f00051

Branch: refs/heads/master
Commit: 91f00051d7b434136244a7f44f3f6d1fe187464f
Parents: 338ab9f
Author: Marvin Humphrey 
Authored: Fri Mar 18 23:41:26 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:19:41 2016 -0700

--
 compiler/c/cfc.c  |  5 +++--
 compiler/src/CFCBase.h|  2 +-
 compiler/src/CFCCHtml.c   |  9 +
 compiler/src/CFCClass.c   |  2 +-
 compiler/src/CFCDocuComment.c |  6 +++---
 compiler/src/CFCFile.c|  2 +-
 compiler/src/CFCGoFunc.c  | 12 ++--
 compiler/src/CFCGoTypeMap.c   |  8 
 compiler/src/CFCParcel.c  |  8 
 compiler/src/CFCParser.c  |  2 +-
 compiler/src/CFCPerl.c|  2 +-
 compiler/src/CFCPerlConstructor.c |  2 +-
 compiler/src/CFCPerlMethod.c  |  2 +-
 compiler/src/CFCPerlPod.c |  6 +++---
 compiler/src/CFCPerlSub.c |  4 ++--
 compiler/src/CFCPyClass.c |  2 +-
 compiler/src/CFCPyMethod.c| 30 +++---
 compiler/src/CFCPython.c  |  4 ++--
 compiler/src/CFCRuby.c|  2 +-
 compiler/src/CFCType.c|  4 ++--
 compiler/src/CFCUtil.c| 25 +
 compiler/src/CFCVersion.c |  3 ++-
 22 files changed, 73 insertions(+), 69 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/91f00051/compiler/c/cfc.c
--
diff --git a/compiler/c/cfc.c b/compiler/c/cfc.c
index 6f5f527..369a0b1 100644
--- a/compiler/c/cfc.c
+++ b/compiler/c/cfc.c
@@ -75,6 +75,7 @@ S_parse_string_array_argument(const char *arg, const char 
*name,
 size_t   arg_len  = strlen(arg);
 size_t   name_len = strlen(name);
 int  new_num_results;
+size_t   amount;
 char   **new_results;
 
 if (arg_len < name_len
@@ -85,8 +86,8 @@ S_parse_string_array_argument(const char *arg, const char 
*name,
 }
 
 new_num_results = *num_results + 1;
-new_results = (char **)REALLOCATE(*results,
-  (new_num_results + 1) * sizeof(char *));
+amount = (((size_t)new_num_results + 1) * sizeof(char *));
+new_results = (char **)REALLOCATE(*results, amount);
 new_results[new_num_results-1] = CFCUtil_strdup(arg + name_len + 1);
 new_results[new_num_results]   = NULL;
 *num_results = new_num_results;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/91f00051/compiler/src/CFCBase.h
--
diff --git a/compiler/src/CFCBase.h b/compiler/src/CFCBase.h
index 9117ae2..09ee662 100644
--- a/compiler/src/CFCBase.h
+++ b/compiler/src/CFCBase.h
@@ -33,7 +33,7 @@ typedef void (*CFCBase_destroy_t)(CFCBase *self);
 #ifdef CFC_NEED_BASE_STRUCT_DEF
 struct CFCBase {
 const CFCMeta *meta;
-int refcount;
+unsigned refcount;
 };
 #endif
 struct CFCMeta {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/91f00051/compiler/src/CFCCHtml.c
--
diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c
index 6f42ea6..a054cb8 100644
--- a/compiler/src/CFCCHtml.c
+++ b/compiler/src/CFCCHtml.c
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1091,8 +1092,8 @@ S_type_to_html(CFCType *type, const char *sep, CFCClass 
*doc_class) {
 CFCUtil_die("Unprefixed object specifier '%s'", specifier);
 }
 
-size_t  offset = underscore + 1 - specifier;
-char   *prefix = CFCUtil_strndup(specifier, offset);
+ptrdiff_t   offset = underscore + 1 - specifier;
+char   *prefix = CFCUtil_strndup(specifier, (size_t)offset);
 const char *struct_sym = specifier + offset;
 
 if (!klass) {
@@ -1117,7 +1118,7 @@ S_type_to_html(CFCType *type, const char *sep, CFCClass 
*doc_class) {
 const char *const_str = CFCType_const(type) ? "const " : "";
 
 int indirection = CFCType_get_indirection(type);
-size_t asterisk_offset = indirection < 10 ? 10 - indirection : 0;
+ptrdiff_t asterisk_offset = indirection < 10 ? 10 - indirection : 0;
 const char *asterisks = "**";
 const char *ind_str   = asterisks + asterisk_offset;
 
@@ -1203,7 +1204,7 @@ S_relative_url(const char *url, CFCClass *base, int 
dir_level) {
 }
 
 // Create path back to root
-size_t bytes 

[10/14] lucy-clownfish git commit: Address int warnings in core tests.

2016-03-19 Thread marvin
Address int warnings in core tests.

Fix warnings from `-Wconversion`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/0f6fdb45
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/0f6fdb45
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/0f6fdb45

Branch: refs/heads/master
Commit: 0f6fdb45b9ad0f60391dcb81e0e7d05f83aeada7
Parents: e37b154
Author: Marvin Humphrey 
Authored: Sat Mar 19 01:58:57 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 runtime/core/Clownfish/Test/TestBlob.c  |  4 +-
 runtime/core/Clownfish/Test/TestByteBuf.c   |  8 ++--
 runtime/core/Clownfish/Test/TestHash.c  | 22 -
 .../core/Clownfish/Test/TestLockFreeRegistry.c  |  2 +-
 runtime/core/Clownfish/Test/TestNum.c   |  2 +-
 runtime/core/Clownfish/Test/TestString.c| 50 ++--
 runtime/core/Clownfish/Test/TestVector.c| 34 ++---
 runtime/core/Clownfish/Test/Util/TestMemory.c   | 20 
 .../core/Clownfish/Test/Util/TestStringHelper.c | 12 ++---
 9 files changed, 77 insertions(+), 77 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0f6fdb45/runtime/core/Clownfish/Test/TestBlob.c
--
diff --git a/runtime/core/Clownfish/Test/TestBlob.c 
b/runtime/core/Clownfish/Test/TestBlob.c
index 9307f5f..c8c70c3 100644
--- a/runtime/core/Clownfish/Test/TestBlob.c
+++ b/runtime/core/Clownfish/Test/TestBlob.c
@@ -49,8 +49,8 @@ test_Equals(TestBatchRunner *runner) {
 
 {
 Blob *other = Blob_new("bar", 4);
-TEST_INT_EQ(runner, Blob_Get_Size(blob), Blob_Get_Size(other),
-"same length");
+TEST_UINT_EQ(runner, Blob_Get_Size(blob), Blob_Get_Size(other),
+ "same length");
 TEST_FALSE(runner, Blob_Equals(blob, (Obj*)other),
"Different content spoils Equals");
 DECREF(other);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0f6fdb45/runtime/core/Clownfish/Test/TestByteBuf.c
--
diff --git a/runtime/core/Clownfish/Test/TestByteBuf.c 
b/runtime/core/Clownfish/Test/TestByteBuf.c
index 6e8063c..bc29bb1 100644
--- a/runtime/core/Clownfish/Test/TestByteBuf.c
+++ b/runtime/core/Clownfish/Test/TestByteBuf.c
@@ -59,8 +59,8 @@ test_Equals(TestBatchRunner *runner) {
 
 {
 ByteBuf *other = BB_new_bytes("bar", 4);
-TEST_INT_EQ(runner, BB_Get_Size(bb), BB_Get_Size(other),
-"same length");
+TEST_UINT_EQ(runner, BB_Get_Size(bb), BB_Get_Size(other),
+ "same length");
 TEST_FALSE(runner, BB_Equals(bb, (Obj*)other),
"Different content spoils Equals");
 DECREF(other);
@@ -72,10 +72,10 @@ test_Equals(TestBatchRunner *runner) {
 static void
 test_Grow(TestBatchRunner *runner) {
 ByteBuf *bb = BB_new(1);
-TEST_INT_EQ(runner, BB_Get_Capacity(bb), 8,
+TEST_UINT_EQ(runner, BB_Get_Capacity(bb), 8,
 "Allocate in 8-byte increments");
 BB_Grow(bb, 9);
-TEST_INT_EQ(runner, BB_Get_Capacity(bb), 16,
+TEST_UINT_EQ(runner, BB_Get_Capacity(bb), 16,
 "Grow in 8-byte increments");
 DECREF(bb);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0f6fdb45/runtime/core/Clownfish/Test/TestHash.c
--
diff --git a/runtime/core/Clownfish/Test/TestHash.c 
b/runtime/core/Clownfish/Test/TestHash.c
index c5c9c1f..e77c816 100644
--- a/runtime/core/Clownfish/Test/TestHash.c
+++ b/runtime/core/Clownfish/Test/TestHash.c
@@ -80,8 +80,8 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
 }
 TEST_TRUE(runner, Hash_Equals(hash, (Obj*)dupe), "Equals");
 
-TEST_INT_EQ(runner, Hash_Get_Capacity(hash), starting_cap,
-"Initial capacity sufficient (no rebuilds)");
+TEST_UINT_EQ(runner, Hash_Get_Capacity(hash), starting_cap,
+ "Initial capacity sufficient (no rebuilds)");
 
 for (size_t i = 0; i < 100; i++) {
 String *key  = (String*)Vec_Fetch(expected, i);
@@ -91,8 +91,8 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
 
 TEST_TRUE(runner, Vec_Equals(got, (Obj*)expected),
   "basic Store and Fetch");
-TEST_INT_EQ(runner, Hash_Get_Size(hash), 100,
-"size incremented properly by Hash_Store");
+TEST_UINT_EQ(runner, Hash_Get_Size(hash), 100,
+ "size incremented properly by Hash_Store");
 
 TEST_TRUE(runner, Hash_Fetch(hash, foo) == NULL,
   "Fetch against non-existent key returns NULL");
@@ -103,18 +103,18 @@ test_Store_and_Fet

[03/14] lucy-clownfish git commit: Avoid `uninitialized` warning within TRY block.

2016-03-19 Thread marvin
Avoid `uninitialized` warning within TRY block.

The compiler can't tell that either the TRY block will assign to
`retvalCF` successfully or an error will be detected before we return
it.  Therefore, assign an initial value to quiet the warning.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/f35c02d9
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/f35c02d9
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/f35c02d9

Branch: refs/heads/master
Commit: f35c02d96610e8f1fef0ed396650a1b498a1d138
Parents: b71d2db
Author: Marvin Humphrey 
Authored: Wed Mar 16 00:23:47 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:42:36 2016 -0700

--
 compiler/src/CFCPyMethod.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f35c02d9/compiler/src/CFCPyMethod.c
--
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 3d13665..45b0f86 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -515,7 +515,7 @@ S_gen_meth_invocation(CFCMethod *method, CFCClass *invoker) 
{
 maybe_assign = "";
 }
 else {
-maybe_declare = CFCUtil_sprintf("%s retvalCF;\n",
+maybe_declare = CFCUtil_sprintf("%s retvalCF = 0;\n",
 CFCType_to_c(return_type));
 maybe_assign = "retvalCF = ";
 }



[12/14] lucy-clownfish git commit: Change INT_EQ args from uint64_t to int64_t.

2016-03-19 Thread marvin
Change INT_EQ args from uint64_t to int64_t.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b5a1dd20
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b5a1dd20
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b5a1dd20

Branch: refs/heads/master
Commit: b5a1dd206ed0f1e19ef999ae595bb2f0ae29409b
Parents: 840567e
Author: Marvin Humphrey 
Authored: Sat Mar 19 01:26:52 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 runtime/core/Clownfish/TestHarness/TestBatchRunner.c   | 8 
 runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b5a1dd20/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
--
diff --git a/runtime/core/Clownfish/TestHarness/TestBatchRunner.c 
b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
index f832d0e..df95034 100644
--- a/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
+++ b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
@@ -150,8 +150,8 @@ TestBatchRunner_test_false(TestBatchRunner *self, bool 
condition,
 }
 
 bool
-TestBatchRunner_test_int_equals(TestBatchRunner *self, uint64_t got,
-uint64_t expected, const char *pattern, ...) {
+TestBatchRunner_test_int_equals(TestBatchRunner *self, int64_t got,
+int64_t expected, const char *pattern, ...) {
 va_list args;
 va_start(args, pattern);
 bool result = TestBatchRunner_VTest_Int_Equals(self, got, expected,
@@ -223,8 +223,8 @@ TestBatchRunner_VTest_False_IMP(TestBatchRunner *self, bool 
condition,
 }
 
 bool
-TestBatchRunner_VTest_Int_Equals_IMP(TestBatchRunner *self, uint64_t got,
- uint64_t expected, const char *pattern,
+TestBatchRunner_VTest_Int_Equals_IMP(TestBatchRunner *self, int64_t got,
+ int64_t expected, const char *pattern,
  va_list args) {
 bool pass = (got == expected);
 S_vtest_true(self, pass, pattern, args);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b5a1dd20/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
--
diff --git a/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh 
b/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
index fc39d33..85bec44 100644
--- a/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
+++ b/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
@@ -68,7 +68,7 @@ class Clownfish::TestHarness::TestBatchRunner inherits 
Clownfish::Obj {
...);
 
 inert bool
-test_int_equals(TestBatchRunner *self, uint64_t got, uint64_t expected,
+test_int_equals(TestBatchRunner *self, int64_t got, int64_t expected,
 const char *pattern, ...);
 
 inert bool
@@ -97,7 +97,7 @@ class Clownfish::TestHarness::TestBatchRunner inherits 
Clownfish::Obj {
 va_list args);
 
 bool
-VTest_Int_Equals(TestBatchRunner *self, uint64_t got, uint64_t expected,
+VTest_Int_Equals(TestBatchRunner *self, int64_t got, int64_t expected,
  const char *pattern, va_list args);
 
 bool



[02/14] lucy-clownfish git commit: Better Python include dirs for Python.h.

2016-03-19 Thread marvin
Better Python include dirs for Python.h.

Getting the include dir from `distutils.sysconfig` seems to be more
reliable than `sysconfig`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b71d2dbd
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b71d2dbd
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b71d2dbd

Branch: refs/heads/master
Commit: b71d2dbd60bcef59153fce949b9f519b64c297f7
Parents: bf4723f
Author: Marvin Humphrey 
Authored: Wed Mar 16 00:21:05 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:42:28 2016 -0700

--
 runtime/python/setup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b71d2dbd/runtime/python/setup.py
--
diff --git a/runtime/python/setup.py b/runtime/python/setup.py
index 2e89dd2..fa184ef 100644
--- a/runtime/python/setup.py
+++ b/runtime/python/setup.py
@@ -39,7 +39,7 @@ def ext_build_dir(base):
 # CFLAGS.  Add the Python headers include dir to CFLAGS.
 compiler = distutils.ccompiler.new_compiler()
 cflags = sysconfig.get_config_var('CFLAGS')
-cflags = cflags + " -I" + sysconfig.get_path('include')
+cflags = cflags + " -I" + distutils.sysconfig.get_python_inc()
 compiler_type = distutils.ccompiler.get_default_compiler()
 
 # There's no public way to get a string representing the compiler executable



[08/14] lucy-clownfish git commit: Change CFCTest's INT_EQ to used signed int.

2016-03-19 Thread marvin
Change CFCTest's INT_EQ to used signed int.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/74b7a06a
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/74b7a06a
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/74b7a06a

Branch: refs/heads/master
Commit: 74b7a06ae204119b3a7cbacd7281f2376b2de88a
Parents: d8eb00c
Author: Marvin Humphrey 
Authored: Sat Mar 19 22:24:42 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 compiler/src/CFCTest.c | 6 +++---
 compiler/src/CFCTest.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/74b7a06a/compiler/src/CFCTest.c
--
diff --git a/compiler/src/CFCTest.c b/compiler/src/CFCTest.c
index a542c32..3e8cd41 100644
--- a/compiler/src/CFCTest.c
+++ b/compiler/src/CFCTest.c
@@ -271,7 +271,7 @@ CFCTest_test_string_equals(CFCTest *self, const char 
*result,
 }
 
 void
-CFCTest_test_int_equals(CFCTest *self, uint64_t result, uint64_t expected,
+CFCTest_test_int_equals(CFCTest *self, int64_t result, int64_t expected,
 const char *fmt, ...) {
 int cond = (result == expected);
 
@@ -281,8 +281,8 @@ CFCTest_test_int_equals(CFCTest *self, uint64_t result, 
uint64_t expected,
 va_end(args);
 
 if (!cond) {
-self->formatter->test_comment("Expected '%"PRIu64"',"
-  " got '%"PRIu64"'.\n",
+self->formatter->test_comment("Expected '%"PRId64"',"
+  " got '%"PRId64"'.\n",
   expected, result);
 }
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/74b7a06a/compiler/src/CFCTest.h
--
diff --git a/compiler/src/CFCTest.h b/compiler/src/CFCTest.h
index fd8bd30..a88418a 100644
--- a/compiler/src/CFCTest.h
+++ b/compiler/src/CFCTest.h
@@ -110,7 +110,7 @@ CFCTest_test_string_equals(CFCTest *self, const char 
*result,
  * @param fmt printf-like format string describing the test.
  */
 void
-CFCTest_test_int_equals(CFCTest *self, uint64_t result, uint64_t expected,
+CFCTest_test_int_equals(CFCTest *self, int64_t result, int64_t expected,
 const char *fmt, ...);
 
 /* Skip tests.



[13/14] lucy-clownfish git commit: Fix compiler warning in Py CFC.

2016-03-19 Thread marvin
Fix compiler warning in Py CFC.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d8eb00c4
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d8eb00c4
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d8eb00c4

Branch: refs/heads/master
Commit: d8eb00c49fa63605f5e423e89a8c0f739316a59b
Parents: 0f6fdb4
Author: Marvin Humphrey 
Authored: Sat Mar 19 02:16:04 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 compiler/python/src/cfc/_cfc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8eb00c4/compiler/python/src/cfc/_cfc.c
--
diff --git a/compiler/python/src/cfc/_cfc.c b/compiler/python/src/cfc/_cfc.c
index 0f6c882..e7e8f3f 100644
--- a/compiler/python/src/cfc/_cfc.c
+++ b/compiler/python/src/cfc/_cfc.c
@@ -177,7 +177,7 @@ static PyObject*
 S_CFCHierarchy_get_dest(PyObject *wrapper, PyObject *unused) {
 CHY_UNUSED_VAR(unused);
 const char *dest = CFCHierarchy_get_dest(S_to_Hierarchy(wrapper));
-return PyUnicode_DecodeASCII(dest, strlen(dest), NULL);
+return PyUnicode_DecodeASCII(dest, (Py_ssize_t)strlen(dest), NULL);
 }
 
 static PyObject*



[07/14] lucy-clownfish git commit: Add UINT_EQ to CFC tests.

2016-03-19 Thread marvin
Add UINT_EQ to CFC tests.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/9d3aef80
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/9d3aef80
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/9d3aef80

Branch: refs/heads/master
Commit: 9d3aef8012cba02f43cb5cf17cefbebb8a9814a8
Parents: 74b7a06
Author: Marvin Humphrey 
Authored: Sat Mar 19 22:27:49 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 compiler/src/CFCTest.c | 17 +
 compiler/src/CFCTest.h | 11 +++
 2 files changed, 28 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9d3aef80/compiler/src/CFCTest.c
--
diff --git a/compiler/src/CFCTest.c b/compiler/src/CFCTest.c
index 3e8cd41..f925cb1 100644
--- a/compiler/src/CFCTest.c
+++ b/compiler/src/CFCTest.c
@@ -288,6 +288,23 @@ CFCTest_test_int_equals(CFCTest *self, int64_t result, 
int64_t expected,
 }
 
 void
+CFCTest_test_uint_equals(CFCTest *self, uint64_t result, uint64_t expected,
+const char *fmt, ...) {
+int cond = (result == expected);
+
+va_list args;
+va_start(args, fmt);
+S_vtest_true(self, cond, fmt, args);
+va_end(args);
+
+if (!cond) {
+self->formatter->test_comment("Expected '%"PRIu64"',"
+  " got '%"PRIu64"'.\n",
+  expected, result);
+}
+}
+
+void
 CFCTest_skip(CFCTest *self, int num, const char *fmt, ...) {
 va_list args;
 va_start(args, fmt);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9d3aef80/compiler/src/CFCTest.h
--
diff --git a/compiler/src/CFCTest.h b/compiler/src/CFCTest.h
index a88418a..352e390 100644
--- a/compiler/src/CFCTest.h
+++ b/compiler/src/CFCTest.h
@@ -29,6 +29,7 @@
   #define OK  CFCTest_test_true
   #define STR_EQ  CFCTest_test_string_equals
   #define INT_EQ  CFCTest_test_int_equals
+  #define UINT_EQ CFCTest_test_uint_equals
   #define SKIPCFCTest_skip
 #endif
 
@@ -113,6 +114,16 @@ void
 CFCTest_test_int_equals(CFCTest *self, int64_t result, int64_t expected,
 const char *fmt, ...);
 
+/* Test unsigned integers for equality and collect result.
+ *
+ * @param result Result integer to be tested.
+ * @param expected Expected result integer.
+ * @param fmt printf-like format string describing the test.
+ */
+void
+CFCTest_test_uint_equals(CFCTest *self, uint64_t result, uint64_t expected,
+ const char *fmt, ...);
+
 /* Skip tests.
  *
  * @param num Number of tests to skip.



[06/14] lucy-clownfish git commit: Add UINT_EQ test functions.

2016-03-19 Thread marvin
Add UINT_EQ test functions.

Add unsigned integer unit test functions.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/e37b154b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/e37b154b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/e37b154b

Branch: refs/heads/master
Commit: e37b154b20984708dc533d4060cbaed7eca1a49c
Parents: b5a1dd2
Author: Marvin Humphrey 
Authored: Sat Mar 19 21:59:44 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 22:34:21 2016 -0700

--
 .../Clownfish/TestHarness/TestBatchRunner.c | 25 
 .../Clownfish/TestHarness/TestBatchRunner.cfh   |  9 +++
 2 files changed, 34 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/e37b154b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
--
diff --git a/runtime/core/Clownfish/TestHarness/TestBatchRunner.c 
b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
index df95034..fd3bec9 100644
--- a/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
+++ b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
@@ -161,6 +161,17 @@ TestBatchRunner_test_int_equals(TestBatchRunner *self, 
int64_t got,
 }
 
 bool
+TestBatchRunner_test_uint_equals(TestBatchRunner *self, uint64_t got,
+ uint64_t expected, const char *pattern, ...) {
+va_list args;
+va_start(args, pattern);
+bool result = TestBatchRunner_VTest_UInt_Equals(self, got, expected,
+pattern, args);
+va_end(args);
+return result;
+}
+
+bool
 TestBatchRunner_test_float_equals(TestBatchRunner *self, double got,
   double expected, const char *pattern, ...) {
 va_list args;
@@ -230,6 +241,20 @@ TestBatchRunner_VTest_Int_Equals_IMP(TestBatchRunner 
*self, int64_t got,
 S_vtest_true(self, pass, pattern, args);
 if (!pass) {
 TestFormatter_test_comment(self->formatter,
+   "Expected '%"PRId64"', got '%"PRId64"'.\n",
+   expected, got);
+}
+return pass;
+}
+
+bool
+TestBatchRunner_VTest_UInt_Equals_IMP(TestBatchRunner *self, uint64_t got,
+  uint64_t expected, const char *pattern,
+  va_list args) {
+bool pass = (got == expected);
+S_vtest_true(self, pass, pattern, args);
+if (!pass) {
+TestFormatter_test_comment(self->formatter,
"Expected '%"PRIu64"', got '%"PRIu64"'.\n",
expected, got);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/e37b154b/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
--
diff --git a/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh 
b/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
index 85bec44..0f01b38 100644
--- a/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
+++ b/runtime/core/Clownfish/TestHarness/TestBatchRunner.cfh
@@ -72,6 +72,10 @@ class Clownfish::TestHarness::TestBatchRunner inherits 
Clownfish::Obj {
 const char *pattern, ...);
 
 inert bool
+test_uint_equals(TestBatchRunner *self, uint64_t got, uint64_t expected,
+ const char *pattern, ...);
+
+inert bool
 test_float_equals(TestBatchRunner *self, double got, double expected,
   const char *pattern, ...);
 
@@ -101,6 +105,10 @@ class Clownfish::TestHarness::TestBatchRunner inherits 
Clownfish::Obj {
  const char *pattern, va_list args);
 
 bool
+VTest_UInt_Equals(TestBatchRunner *self, uint64_t got, uint64_t expected,
+ const char *pattern, va_list args);
+
+bool
 VTest_Float_Equals(TestBatchRunner *self, double got, double expected,
const char *pattern, va_list args);
 
@@ -125,6 +133,7 @@ __C__
   #define TEST_TRUEcfish_TestBatchRunner_test_true
   #define TEST_FALSE   cfish_TestBatchRunner_test_false
   #define TEST_INT_EQ  cfish_TestBatchRunner_test_int_equals
+  #define TEST_UINT_EQ cfish_TestBatchRunner_test_uint_equals
   #define TEST_FLOAT_EQcfish_TestBatchRunner_test_float_equals
   #define TEST_STR_EQ  cfish_TestBatchRunner_test_string_equals
   #define PASS cfish_TestBatchRunner_pass



[2/2] lucy-clownfish git commit: Merge branch 'itervar'

2016-03-19 Thread marvin
Merge branch 'itervar'

Fix latent iteration variable bug.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b8d40d0e
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b8d40d0e
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b8d40d0e

Branch: refs/heads/master
Commit: b8d40d0efa466b25b3e2d5a9fe59d69eb3031497
Parents: f3bab0e d352cc9
Author: Marvin Humphrey 
Authored: Sat Mar 19 21:39:14 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:39:32 2016 -0700

--
 compiler/src/CFCGo.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)
--




[1/2] lucy-clownfish git commit: Fix incorrect (`i` vs. `j`) iteration variable.

2016-03-19 Thread marvin
Repository: lucy-clownfish
Updated Branches:
  refs/heads/master f3bab0eec -> b8d40d0ef


Fix incorrect (`i` vs. `j`) iteration variable.

This latent bug would have affected Clownfish packages with multiple
dependencies.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d352cc9a
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d352cc9a
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d352cc9a

Branch: refs/heads/master
Commit: d352cc9acf36af4d28c0522dcbd22438af339112
Parents: f3bab0e
Author: Marvin Humphrey 
Authored: Wed Mar 16 01:03:14 2016 +
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:37:11 2016 -0700

--
 compiler/src/CFCGo.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d352cc9a/compiler/src/CFCGo.c
--
diff --git a/compiler/src/CFCGo.c b/compiler/src/CFCGo.c
index 45e9e3f..c263bfd 100644
--- a/compiler/src/CFCGo.c
+++ b/compiler/src/CFCGo.c
@@ -46,7 +46,7 @@ struct mapping {
 char *package;
 };
 
-static int num_parcel_mappings;
+static size_t num_parcel_mappings;
 static struct mapping *parcel_mappings;
 
 struct CFCGo {
@@ -198,9 +198,9 @@ S_gen_prereq_imports(CFCParcel *parcel) {
 for (int i = 0; prereqs[i] != NULL; i++) {
 const char *dep_parcel = CFCParcel_get_name(prereqs[i]);
 const char *dep_package = NULL;
-for (int j = 0; j < num_parcel_mappings; j++) {
-if (strcmp(dep_parcel, parcel_mappings[i].parcel) == 0) {
-dep_package = parcel_mappings[i].package;
+for (size_t j = 0; j < num_parcel_mappings; j++) {
+if (strcmp(dep_parcel, parcel_mappings[j].parcel) == 0) {
+dep_package = parcel_mappings[j].package;
 }
 }
 if (dep_package == NULL) {



[2/2] lucy git commit: Merge remote-tracking branch 'github/LUCY-294-nul-term'

2016-03-19 Thread marvin
Merge remote-tracking branch 'github/LUCY-294-nul-term'

Fix some nul-termination problems in test code.

This closes #35.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/b9fba0da
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/b9fba0da
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/b9fba0da

Branch: refs/heads/master
Commit: b9fba0dada5199810b25ac7ab49d57bf9547f538
Parents: 7805188 d9c7f35
Author: Marvin Humphrey 
Authored: Sat Mar 19 21:01:28 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 21:01:28 2016 -0700

--
 core/Lucy/Test/Analysis/TestNormalizer.c| 14 ---
 core/Lucy/Test/Analysis/TestSnowballStemmer.c   |  6 -
 core/Lucy/Test/Analysis/TestStandardTokenizer.c | 20 +++
 core/Lucy/Test/Highlight/TestHighlighter.c  |  4 ++-
 core/Lucy/Test/Index/TestSortWriter.c   | 16 +---
 core/Lucy/Test/Plan/TestFieldMisc.c |  6 +++--
 core/Lucy/Test/Search/TestQueryParserLogic.c| 19 +-
 core/Lucy/Test/Search/TestQueryParserSyntax.c   | 15 +++
 core/Lucy/Test/Store/TestCompoundFileWriter.c   |  6 -
 core/Lucy/Test/Store/TestFSFileHandle.c | 26 +---
 10 files changed, 95 insertions(+), 37 deletions(-)
--




[1/2] lucy git commit: Ensure nul-terminated C strings in test code.

2016-03-19 Thread marvin
Repository: lucy
Updated Branches:
  refs/heads/master 7805188df -> b9fba0dad


Ensure nul-terminated C strings in test code.

Use `Str_To_Utf8` which is guaranteed to return a nul-terminated C
string instead of `Str_To_Ptr8`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/d9c7f359
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/d9c7f359
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/d9c7f359

Branch: refs/heads/master
Commit: d9c7f35926aa337320112d6f03736b0cd13261c0
Parents: ee5cebe
Author: Marvin Humphrey 
Authored: Mon Mar 14 14:44:45 2016 -0700
Committer: Marvin Humphrey 
Committed: Mon Mar 14 15:13:04 2016 -0700

--
 core/Lucy/Test/Analysis/TestNormalizer.c| 14 ---
 core/Lucy/Test/Analysis/TestSnowballStemmer.c   |  6 -
 core/Lucy/Test/Analysis/TestStandardTokenizer.c | 20 +++
 core/Lucy/Test/Highlight/TestHighlighter.c  |  4 ++-
 core/Lucy/Test/Index/TestSortWriter.c   | 16 +---
 core/Lucy/Test/Plan/TestFieldMisc.c |  6 +++--
 core/Lucy/Test/Search/TestQueryParserLogic.c| 19 +-
 core/Lucy/Test/Search/TestQueryParserSyntax.c   | 15 +++
 core/Lucy/Test/Store/TestCompoundFileWriter.c   |  6 -
 core/Lucy/Test/Store/TestFSFileHandle.c | 26 +---
 10 files changed, 95 insertions(+), 37 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy/blob/d9c7f359/core/Lucy/Test/Analysis/TestNormalizer.c
--
diff --git a/core/Lucy/Test/Analysis/TestNormalizer.c 
b/core/Lucy/Test/Analysis/TestNormalizer.c
index c882546..011e8e2 100644
--- a/core/Lucy/Test/Analysis/TestNormalizer.c
+++ b/core/Lucy/Test/Analysis/TestNormalizer.c
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include 
+
 #define C_TESTLUCY_TESTNORMALIZER
 #define C_LUCY_NORMALIZER
 #define TESTLUCY_USE_SHORT_NAMES
@@ -98,13 +100,17 @@ test_normalization(TestBatchRunner *runner) {
 String *word = (String*)Vec_Fetch(words, j);
 Vector *got  = Normalizer_Split(normalizer, word);
 String *norm = (String*)Vec_Fetch(got, 0);
+char   *fstr = Str_To_Utf8(form);
+char   *wstr = Str_To_Utf8(word);
 TEST_TRUE(runner,
   norm
   && Str_is_a(norm, STRING)
   && Str_Equals(norm, Vec_Fetch(norms, j)),
-  "Normalize %s %d %d: %s", Str_Get_Ptr8(form),
-  case_fold, strip_accents, Str_Get_Ptr8(word)
+  "Normalize %s %d %d: %s", fstr,
+  case_fold, strip_accents, wstr
  );
+free(fstr);
+free(wstr);
 DECREF(got);
 }
 DECREF(normalizer);
@@ -139,7 +145,9 @@ test_utf8proc_normalization(TestBatchRunner *runner) {
 if (!json) {
 json = Str_newf("[failed to encode]");
 }
-FAIL(runner, "Failed to normalize: %s", Str_Get_Ptr8(json));
+char *str = Str_To_Utf8(json);
+FAIL(runner, "Failed to normalize: %s", str);
+free(str);
 DECREF(json);
 DECREF(source);
 return;

http://git-wip-us.apache.org/repos/asf/lucy/blob/d9c7f359/core/Lucy/Test/Analysis/TestSnowballStemmer.c
--
diff --git a/core/Lucy/Test/Analysis/TestSnowballStemmer.c 
b/core/Lucy/Test/Analysis/TestSnowballStemmer.c
index 329864d..5889247 100644
--- a/core/Lucy/Test/Analysis/TestSnowballStemmer.c
+++ b/core/Lucy/Test/Analysis/TestSnowballStemmer.c
@@ -76,22 +76,26 @@ test_stemming(TestBatchRunner *runner) {
 HashIterator *iter = HashIter_new(tests);
 while (HashIter_Next(iter)) {
 String *iso   = HashIter_Get_Key(iter);
+char   *iso_str   = Str_To_Utf8(iso);
 Hash   *lang_data = (Hash*)HashIter_Get_Value(iter);
 Vector *words = (Vector*)Hash_Fetch_Utf8(lang_data, "words", 5);
 Vector *stems = (Vector*)Hash_Fetch_Utf8(lang_data, "stems", 5);
 SnowballStemmer *stemmer = SnowStemmer_new(iso);
 for (uint32_t i = 0, max = Vec_Get_Size(words); i < max; i++) {
 String *word  = (String*)Vec_Fetch(words, i);
+char   *wstr  = Str_To_Utf8(word);
 Vector *got   = SnowStemmer_Split(stemmer, word);
 String *stem  = (String*)Vec_Fetch(got, 0);
 TEST_TRUE(runner,
   stem
   && Str_is_a(stem, STRING)
   && Str_Equals(stem, Vec_Fetch(stems, i)),
-  "Stem %s: %s", Str_Get_Ptr8(iso), Str_Get_Ptr8(word)
+  "Stem %s: %s", iso_str, wst

[1/2] lucy-clownfish git commit: Ensure nul-terminated arg to strtod.

2016-03-19 Thread marvin
Repository: lucy-clownfish
Updated Branches:
  refs/heads/master fa009460e -> f3bab0eec


Ensure nul-terminated arg to strtod.

Inside Str_To_F64 we use strtod, which requires a nul-terminated C
string argument.  Now that Clownfish Strings consistently lack
nul-termination, we need to copy content into a nul-terminated buffer
and pass that to strtod.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/4dab61a5
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/4dab61a5
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/4dab61a5

Branch: refs/heads/master
Commit: 4dab61a5717135c4f60fc6d063e21870a453bb1f
Parents: f5139ff
Author: Marvin Humphrey 
Authored: Mon Mar 14 16:05:23 2016 -0700
Committer: Marvin Humphrey 
Committed: Mon Mar 14 16:05:23 2016 -0700

--
 runtime/core/Clownfish/String.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/4dab61a5/runtime/core/Clownfish/String.c
--
diff --git a/runtime/core/Clownfish/String.c b/runtime/core/Clownfish/String.c
index 7c2c0fa..ac17bad 100644
--- a/runtime/core/Clownfish/String.c
+++ b/runtime/core/Clownfish/String.c
@@ -263,8 +263,8 @@ Str_BaseX_To_I64_IMP(String *self, uint32_t base) {
 return retval;
 }
 
-static double
-S_safe_to_f64(String *self) {
+double
+Str_To_F64_IMP(String *self) {
 size_t amount = self->size < 511 ? self->size : 511;
 char buf[512];
 memcpy(buf, self->ptr, amount);
@@ -272,17 +272,6 @@ S_safe_to_f64(String *self) {
 return strtod(buf, NULL);
 }
 
-double
-Str_To_F64_IMP(String *self) {
-char   *end;
-double  value= strtod(self->ptr, &end);
-size_t  consumed = end - self->ptr;
-if (consumed > self->size) { // strtod overran
-value = S_safe_to_f64(self);
-}
-return value;
-}
-
 char*
 Str_To_Utf8_IMP(String *self) {
 char *buf = (char*)malloc(self->size + 1);



[2/2] lucy-clownfish git commit: Merge 'CLOWNFISH-84-nul-term-strtod'

2016-03-19 Thread marvin
Merge 'CLOWNFISH-84-nul-term-strtod'

Make safer usage of `strtod`.

This closes #64.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/f3bab0ee
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/f3bab0ee
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/f3bab0ee

Branch: refs/heads/master
Commit: f3bab0eec219330b561c6c3a12a5aa641816afe7
Parents: fa00946 4dab61a
Author: Marvin Humphrey 
Authored: Sat Mar 19 20:56:51 2016 -0700
Committer: Marvin Humphrey 
Committed: Sat Mar 19 20:56:51 2016 -0700

--
 runtime/core/Clownfish/String.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)
--




[14/14] lucy-clownfish git commit: Merge branch 'threadsafe-bootstrap'

2016-03-19 Thread nwellnhof
Merge branch 'threadsafe-bootstrap'

Fixes CLOWNFISH-78.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/fa009460
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/fa009460
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/fa009460

Branch: refs/heads/master
Commit: fa009460e27cb9873fa59e4f53ba5416f8531aae
Parents: 94eed76 7cc75eb
Author: Nick Wellnhofer 
Authored: Sat Mar 19 18:22:46 2016 +0100
Committer: Nick Wellnhofer 
Committed: Sat Mar 19 18:22:46 2016 +0100

--
 compiler/src/CFCBindCore.c|  56 +++---
 compiler/src/CFCBindSpecs.c   |  24 -
 runtime/c/src/tls.c   |   9 +-
 runtime/core/Clownfish/Boolean.c  |  21 ++--
 runtime/core/Clownfish/Class.c| 142 +
 runtime/core/Clownfish/Class.cfh  |  25 ++---
 runtime/core/Clownfish/Hash.c |   6 +-
 runtime/core/Clownfish/Method.c   |   7 +-
 runtime/core/Clownfish/Test.c |   2 +
 runtime/core/Clownfish/Test/TestClass.c   |  93 
 runtime/core/Clownfish/Test/TestClass.cfh |  28 +
 runtime/go/clownfish/class_test.go|   4 +-
 runtime/perl/t/core/010-class.t   |  23 
 runtime/perl/xs/XSBind.c  |   5 +-
 14 files changed, 304 insertions(+), 141 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/fa009460/runtime/core/Clownfish/Test.c
--

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/fa009460/runtime/perl/xs/XSBind.c
--



[01/14] lucy-clownfish git commit: Implement pointer-to-pointer hash table

2016-03-19 Thread nwellnhof
Repository: lucy-clownfish
Updated Branches:
  refs/heads/master f5139fff5 -> fa009460e


Implement pointer-to-pointer hash table


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/6c8dbb36
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/6c8dbb36
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/6c8dbb36

Branch: refs/heads/master
Commit: 6c8dbb36de4171950264c54ea813f1bba275bc61
Parents: 20eef8f
Author: Nick Wellnhofer 
Authored: Tue Mar 8 11:54:30 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 14:28:49 2016 +0100

--
 runtime/core/Clownfish/PtrHash.c| 226 +++
 runtime/core/Clownfish/PtrHash.h|  53 ++
 runtime/core/Clownfish/Test.c   |   2 +
 runtime/core/Clownfish/Test/TestPtrHash.c   | 108 +++
 runtime/core/Clownfish/Test/TestPtrHash.cfh |  29 +++
 runtime/perl/t/core/050-ptrhash.t   |  23 +++
 6 files changed, 441 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/6c8dbb36/runtime/core/Clownfish/PtrHash.c
--
diff --git a/runtime/core/Clownfish/PtrHash.c b/runtime/core/Clownfish/PtrHash.c
new file mode 100644
index 000..9d42622
--- /dev/null
+++ b/runtime/core/Clownfish/PtrHash.c
@@ -0,0 +1,226 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include 
+#include 
+
+#include "charmony.h"
+
+#define CFISH_USE_SHORT_NAMES
+#include "Clownfish/PtrHash.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/Util/Memory.h"
+
+#undef PTRHASH_STATS
+
+#ifdef PTRHASH_STATS
+  #include 
+#endif
+
+#if CHAR_BIT * CHY_SIZEOF_PTR <= 32
+  #define PTR_BITS 32
+#else
+  #define PTR_BITS 64
+#endif
+
+#define MAX_FILL_FACTOR 0.625
+
+typedef struct PtrHashEntry {
+void *key;
+void *value;
+} PtrHashEntry;
+
+struct PtrHash {
+size_t num_items;
+size_t cap;
+intshift;
+PtrHashEntry *entries;
+PtrHashEntry *end;
+};
+
+static CFISH_INLINE size_t
+SI_find_index(void *key, int shift);
+
+static CFISH_INLINE size_t
+SI_get_cap(size_t size);
+
+static void
+S_resize(PtrHash *self);
+
+PtrHash*
+PtrHash_new(size_t min_cap) {
+PtrHash *self   = (PtrHash*)MALLOCATE(sizeof(PtrHash));
+
+// Use minimum size of 8.
+// size == 2 ** (PTR_BITS - shift)
+size_t size  = 8;
+intshift = PTR_BITS - 3;
+size_t cap   = SI_get_cap(size);
+
+while (cap < min_cap) {
+if (size > SIZE_MAX / 2 || shift == 0) {
+THROW(ERR, "PtrHash size overflow");
+}
+size  *= 2;
+shift -= 1;
+cap= SI_get_cap(size);
+}
+
+self->num_items = 0;
+self->cap   = cap;
+self->shift = shift;
+self->entries   = (PtrHashEntry*)CALLOCATE(size, sizeof(PtrHashEntry));
+self->end   = &self->entries[size];
+
+return self;
+}
+
+void
+PtrHash_Destroy(PtrHash *self) {
+FREEMEM(self->entries);
+FREEMEM(self);
+}
+
+// Multiplicative hash function using the prime nearest to the golden ratio.
+// Reasonably good and very fast.
+static CFISH_INLINE size_t
+SI_find_index(void *key, int shift) {
+#if PTR_BITS == 32
+uint32_t value = (uint32_t)key * 0x9E3779B1u;
+#else
+uint64_t value = (uint64_t)key * UINT64_C(0x9E3779B97F4A7C55);
+#endif
+return (size_t)(value >> shift);
+}
+
+static CFISH_INLINE size_t
+SI_get_cap(size_t size) {
+return (size_t)(MAX_FILL_FACTOR * size);
+}
+
+void
+PtrHash_Store(PtrHash *self, void *key, void *value) {
+if (key == NULL) {
+THROW(ERR, "Can't store NULL key");
+}
+
+size_t index = SI_find_index(key, self->shift);
+PtrHashEntry *entry = &self->entries[index];
+
+while (entry->key != NULL) {
+if (entry->key == key) {
+entry->value = value;
+return;
+}
+
+entry += 1;
+if (entry >= self->end) { entry = self->entries; }
+}
+
+if (self->num_items >= self->cap) {
+S_resize(self);
+ind

[08/14] lucy-clownfish git commit: Make cfish_init_parcel thread-safe

2016-03-19 Thread nwellnhof
Make cfish_init_parcel thread-safe

Initialize globals with compare-and-swap.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/7528af45
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/7528af45
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/7528af45

Branch: refs/heads/master
Commit: 7528af4514e1ddea3c99bf9f6dcc4392c1f1b8e2
Parents: d7c863b
Author: Nick Wellnhofer 
Authored: Thu Mar 10 19:33:51 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:45:10 2016 +0100

--
 runtime/c/src/tls.c  |  9 +++--
 runtime/core/Clownfish/Boolean.c | 21 +++--
 runtime/core/Clownfish/Hash.c|  6 +-
 runtime/perl/xs/XSBind.c |  5 -
 4 files changed, 31 insertions(+), 10 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/c/src/tls.c
--
diff --git a/runtime/c/src/tls.c b/runtime/c/src/tls.c
index b550f13..a7fda40 100644
--- a/runtime/c/src/tls.c
+++ b/runtime/c/src/tls.c
@@ -49,11 +49,16 @@ static DWORD err_context_tls_index;
 
 void
 Tls_init() {
-err_context_tls_index = TlsAlloc();
-if (err_context_tls_index == TLS_OUT_OF_INDEXES) {
+DWORD tls_index = TlsAlloc();
+if (tls_index == TLS_OUT_OF_INDEXES) {
 fprintf(stderr, "TlsAlloc failed (TLS_OUT_OF_INDEXES)\n");
 abort();
 }
+LONG old_index = InterlockedCompareExchange((LONG*)&err_context_tls_index,
+tls_index, 0);
+if (old_index != 0) {
+TlsFree(tls_index);
+}
 }
 
 ErrContext*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/core/Clownfish/Boolean.c
--
diff --git a/runtime/core/Clownfish/Boolean.c b/runtime/core/Clownfish/Boolean.c
index fd7c6d9..44a7c48 100644
--- a/runtime/core/Clownfish/Boolean.c
+++ b/runtime/core/Clownfish/Boolean.c
@@ -22,18 +22,26 @@
 
 #include "Clownfish/Class.h"
 #include "Clownfish/String.h"
+#include "Clownfish/Util/Atomic.h"
 
 Boolean *Bool_true_singleton;
 Boolean *Bool_false_singleton;
 
 void
 Bool_init_class() {
-Bool_true_singleton  = (Boolean*)Class_Make_Obj(BOOLEAN);
-Bool_true_singleton->value   = true;
-Bool_true_singleton->string  = Str_newf("true");
-Bool_false_singleton = (Boolean*)Class_Make_Obj(BOOLEAN);
-Bool_false_singleton->value  = false;
-Bool_false_singleton->string = Str_newf("false");
+Boolean *true_obj = (Boolean*)Class_Make_Obj(BOOLEAN);
+true_obj->value   = true;
+true_obj->string  = Str_newf("true");
+if (!Atomic_cas_ptr((void**)&Bool_true_singleton, NULL, true_obj)) {
+Bool_Destroy(true_obj);
+}
+
+Boolean *false_obj = (Boolean*)Class_Make_Obj(BOOLEAN);
+false_obj->value   = false;
+false_obj->string  = Str_newf("false");
+if (!Atomic_cas_ptr((void**)&Bool_false_singleton, NULL, false_obj)) {
+Bool_Destroy(false_obj);
+}
 }
 
 Boolean*
@@ -44,6 +52,7 @@ Bool_singleton(bool value) {
 void
 Bool_Destroy_IMP(Boolean *self) {
 if (self && self != CFISH_TRUE && self != CFISH_FALSE) {
+DECREF(self->string);
 SUPER_DESTROY(self, BOOLEAN);
 }
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/core/Clownfish/Hash.c
--
diff --git a/runtime/core/Clownfish/Hash.c b/runtime/core/Clownfish/Hash.c
index e0e5d80..174cc11 100644
--- a/runtime/core/Clownfish/Hash.c
+++ b/runtime/core/Clownfish/Hash.c
@@ -26,6 +26,7 @@
 #include "Clownfish/String.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Vector.h"
+#include "Clownfish/Util/Atomic.h"
 #include "Clownfish/Util/Memory.h"
 
 // TOMBSTONE is shared across threads, so it must never be incref'd or
@@ -50,7 +51,10 @@ SI_rebuild_hash(Hash *self);
 
 void
 Hash_init_class() {
-TOMBSTONE = Str_newf("[HASHTOMBSTONE]");
+String *tombstone = Str_newf("[HASHTOMBSTONE]");
+if (!Atomic_cas_ptr((void**)&TOMBSTONE, NULL, tombstone)) {
+DECREF(tombstone);
+}
 }
 
 Hash*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/perl/xs/XSBind.c
--
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 85bd85b..b6dd944 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -738,7 +738,10 @@ void
 cfish_Err_init_class(void) {
 dTHX;
 char *file = (char*)__FILE__;
-attempt_xsub = (SV*)newXS(NULL, cfish_Err_attempt_via_xs, file);
+SV *xsub = (SV*)newXS(NULL, cfish_Err_attempt_via_xs, file);
+if (!cfish_At

[06/14] lucy-clownfish git commit: Start to make Class_bootstrap thread-safe

2016-03-19 Thread nwellnhof
Start to make Class_bootstrap thread-safe

Use Atomic_cas_ptr to write

- global class pointer
- class name
- class method array


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/ce1fe99c
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/ce1fe99c
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/ce1fe99c

Branch: refs/heads/master
Commit: ce1fe99cf3f45045af77bf717da3b17cb6549ffd
Parents: dc56c14
Author: Nick Wellnhofer 
Authored: Thu Mar 10 18:34:33 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:22:50 2016 +0100

--
 runtime/core/Clownfish/Class.c | 40 ++---
 1 file changed, 33 insertions(+), 7 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/ce1fe99c/runtime/core/Clownfish/Class.c
--
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 1ab7523..a96bf96 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -78,7 +78,7 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 + spec->num_novel_meths
   * sizeof(cfish_method_t);
 
-Class *klass = (Class*)Memory_wrapped_calloc(class_alloc_size, 1);
+Class *klass = (Class*)CALLOCATE(class_alloc_size, 1);
 
 // Needed to calculate size of subclasses.
 klass->class_alloc_size = class_alloc_size;
@@ -92,7 +92,10 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 }
 
 // Initialize the global pointer to the Class.
-*spec->klass = klass;
+if (!Atomic_cas_ptr((void**)spec->klass, NULL, klass)) {
+// Another thread beat us to it.
+FREEMEM(klass);
+}
 }
 
 /* Pass 2:
@@ -203,9 +206,24 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 const ClassSpec *spec = &specs[i];
 Class *klass = *spec->klass;
 
-S_set_name(klass, spec->name, strlen(spec->name));
-klass->methods = (Method**)MALLOCATE((spec->num_novel_meths + 1)
- * sizeof(Method*));
+String *name_internal
+= Str_new_from_trusted_utf8(spec->name, strlen(spec->name));
+if (!Atomic_cas_ptr((void**)&klass->name_internal, NULL,
+name_internal)
+   ) {
+DECREF(name_internal);
+name_internal = klass->name_internal;
+}
+
+String *name = Str_new_wrap_trusted_utf8(Str_Get_Ptr8(name_internal),
+ Str_Get_Size(name_internal));
+if (!Atomic_cas_ptr((void**)&klass->name, NULL, name)) {
+DECREF(name);
+name = klass->name;
+}
+
+Method **methods = (Method**)MALLOCATE((spec->num_novel_meths + 1)
+   * sizeof(Method*));
 
 // Only store novel methods for now.
 for (size_t i = 0; i < spec->num_novel_meths; ++i) {
@@ -213,10 +231,18 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 String *name = SSTR_WRAP_C(mspec->name);
 Method *method = Method_new(name, mspec->callback_func,
 *mspec->offset);
-klass->methods[i] = method;
+methods[i] = method;
 }
 
-klass->methods[spec->num_novel_meths] = NULL;
+methods[spec->num_novel_meths] = NULL;
+
+if (!Atomic_cas_ptr((void**)&klass->methods, NULL, methods)) {
+// Another thread beat us to it.
+for (size_t i = 0; i < spec->num_novel_meths; ++i) {
+Method_Destroy(methods[i]);
+}
+FREEMEM(methods);
+}
 
 Class_add_to_registry(klass);
 }



[12/14] lucy-clownfish git commit: Replace parcel_id with ParcelSpec pointer

2016-03-19 Thread nwellnhof
Replace parcel_id with ParcelSpec pointer

This makes the check whether a class is in the same parcel thread-safe.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/25f58a6a
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/25f58a6a
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/25f58a6a

Branch: refs/heads/master
Commit: 25f58a6a5267ba8b33bbe00f8a25fa58c490e585
Parents: 8b71db6
Author: Nick Wellnhofer 
Authored: Thu Mar 10 21:19:21 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:49:25 2016 +0100

--
 runtime/core/Clownfish/Class.c   | 33 -
 runtime/core/Clownfish/Class.cfh | 20 ++--
 2 files changed, 14 insertions(+), 39 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/25f58a6a/runtime/core/Clownfish/Class.c
--
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 15cde2c..60434d2 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -50,9 +50,6 @@ S_set_name(Class *self, const char *utf8, size_t size);
 static Method*
 S_find_method(Class *self, const char *meth_name);
 
-static int32_t
-S_claim_parcel_id(void);
-
 static LockFreeRegistry *Class_registry;
 cfish_Class_bootstrap_hook1_t cfish_Class_bootstrap_hook1;
 
@@ -64,8 +61,6 @@ Class_bootstrap(const cfish_ParcelSpec *parcel_spec) {
 const InheritedMethSpec  *inherited_specs  = parcel_spec->inherited_specs;
 uint32_t num_classes = parcel_spec->num_classes;
 
-int32_t parcel_id = S_claim_parcel_id();
-
 /* Pass 1:
  * - Allocate memory.
  * - Initialize global Class pointers.
@@ -107,7 +102,7 @@ Class_bootstrap(const cfish_ParcelSpec *parcel_spec) {
  * - Initialize IVARS_OFFSET.
  * - Initialize 'klass' ivar and refcount by calling Init_Obj.
  * - Initialize parent, flags, obj_alloc_size, class_alloc_size.
- * - Assign parcel_id.
+ * - Assign parcel_spec.
  * - Initialize method pointers and offsets.
  */
 uint32_t num_novel  = 0;
@@ -122,7 +117,7 @@ Class_bootstrap(const cfish_ParcelSpec *parcel_spec) {
 if (spec->ivars_offset_ptr != NULL) {
 if (parent) {
 Class *ancestor = parent;
-while (ancestor && ancestor->parcel_id == parcel_id) {
+while (ancestor && ancestor->parcel_spec == parcel_spec) {
 ancestor = ancestor->parent;
 }
 ivars_offset = ancestor ? ancestor->obj_alloc_size : 0;
@@ -137,8 +132,8 @@ Class_bootstrap(const cfish_ParcelSpec *parcel_spec) {
 // values set in the previous pass or by another thread.
 Class_Init_Obj_IMP(CLASS, klass);
 
-klass->parent= parent;
-klass->parcel_id = parcel_id;
+klass->parent  = parent;
+klass->parcel_spec = parcel_spec;
 
 // CLASS->obj_alloc_size must stay at 0.
 if (klass != CLASS) {
@@ -316,7 +311,6 @@ S_simple_subclass(Class *parent, String *name) {
 
 subclass->parent   = parent;
 subclass->flags= parent->flags;
-subclass->parcel_id= parent->parcel_id;
 subclass->obj_alloc_size   = parent->obj_alloc_size;
 subclass->class_alloc_size = parent->class_alloc_size;
 subclass->methods  = (Method**)CALLOCATE(1, sizeof(Method*));
@@ -483,22 +477,3 @@ S_find_method(Class *self, const char *name) {
 return NULL;
 }
 
-static size_t parcel_count;
-
-static int32_t
-S_claim_parcel_id(void) {
-// TODO: use ordinary cas rather than cas_ptr.
-union { size_t num; void *ptr; } old_value;
-union { size_t num; void *ptr; } new_value;
-
-bool succeeded = false;
-do {
-old_value.num = parcel_count;
-new_value.num = old_value.num + 1;
-succeeded = Atomic_cas_ptr((void*volatile*)&parcel_count,
-   old_value.ptr, new_value.ptr);
-} while (!succeeded);
-
-return (int32_t)new_value.num;
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/25f58a6a/runtime/core/Clownfish/Class.cfh
--
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index ab6e2b8..3ac602c 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -24,16 +24,16 @@ parcel Clownfish;
 
 public final class Clownfish::Class inherits Clownfish::Obj {
 
-Class  *parent;
-String *name;
-String *name_internal;
-uint32_tflags;
-int32_t parcel_id;
-uint32_tobj_alloc_size;
-

[04/14] lucy-clownfish git commit: Add extra parameter to Obj_To_Host

2016-03-19 Thread nwellnhof
Add extra parameter to Obj_To_Host

This parameter will be used to pass the conversion cache around.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/f3eea9b2
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/f3eea9b2
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/f3eea9b2

Branch: refs/heads/master
Commit: f3eea9b22fef28df418cc4f71f861d9c7f2ab3d8
Parents: 3e0546f
Author: Nick Wellnhofer 
Authored: Tue Mar 8 11:54:47 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 14:47:23 2016 +0100

--
 compiler/src/CFCPerlMethod.c|  2 +-
 compiler/src/CFCPerlTypeMap.c   |  2 +-
 runtime/c/src/clownfish.c   | 35 +++
 runtime/core/Clownfish/Blob.cfh |  2 +-
 runtime/core/Clownfish/Boolean.cfh  |  2 +-
 runtime/core/Clownfish/ByteBuf.cfh  |  2 +-
 runtime/core/Clownfish/Hash.cfh |  2 +-
 runtime/core/Clownfish/Num.cfh  |  4 +-
 runtime/core/Clownfish/Obj.cfh  |  2 +-
 runtime/core/Clownfish/String.cfh   |  2 +-
 runtime/core/Clownfish/Vector.cfh   |  2 +-
 runtime/example-lang/src/Clownfish/Obj.c|  2 +-
 runtime/go/ext/clownfish.c  | 38 +
 .../perl/buildlib/Clownfish/Build/Binding.pm| 11 +++--
 runtime/perl/xs/XSBind.c| 45 
 runtime/perl/xs/XSBind.h|  2 +-
 runtime/python/cfext/CFBind.c   | 27 
 runtime/python/cfext/CFBind.h   |  4 +-
 18 files changed, 103 insertions(+), 83 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f3eea9b2/compiler/src/CFCPerlMethod.c
--
diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c
index 911d51d..08d32e2 100644
--- a/compiler/src/CFCPerlMethod.c
+++ b/compiler/src/CFCPerlMethod.c
@@ -456,7 +456,7 @@ S_callback_start(CFCMethod *method) {
 "ENTER;\n"
 "SAVETMPS;\n"
 "PUSHMARK(SP);\n"
-"mPUSHs((SV*)CFISH_Obj_To_Host((cfish_Obj*)self));\n";
+"mPUSHs((SV*)CFISH_Obj_To_Host((cfish_Obj*)self, NULL));\n";
 int num_args = (int)CFCParamList_num_vars(param_list) - 1;
 int num_to_extend = num_args == 0 ? 1
   : num_args == 1 ? 2

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f3eea9b2/compiler/src/CFCPerlTypeMap.c
--
diff --git a/compiler/src/CFCPerlTypeMap.c b/compiler/src/CFCPerlTypeMap.c
index c975c4f..d416284 100644
--- a/compiler/src/CFCPerlTypeMap.c
+++ b/compiler/src/CFCPerlTypeMap.c
@@ -278,7 +278,7 @@ CFCPerlTypeMap_write_xs_typemap(CFCHierarchy *hierarchy) {
 class_var, ", ", allocation, ");\n\n", NULL);
 
 output = CFCUtil_cat(output, class_var, "_\n"
- "$arg = 
(SV*)CFISH_Obj_To_Host((cfish_Obj*)$var);\n"
+ "$arg = 
(SV*)CFISH_Obj_To_Host((cfish_Obj*)$var, NULL);\n"
  "CFISH_DECREF($var);\n"
  "\n", NULL);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f3eea9b2/runtime/c/src/clownfish.c
--
diff --git a/runtime/c/src/clownfish.c b/runtime/c/src/clownfish.c
index 3566cf9..239a796 100644
--- a/runtime/c/src/clownfish.c
+++ b/runtime/c/src/clownfish.c
@@ -120,8 +120,9 @@ cfish_dec_refcount(void *vself) {
 }
 
 void*
-Obj_To_Host_IMP(Obj *self) {
+Obj_To_Host_IMP(Obj *self, void *vcache) {
 UNUSED_VAR(self);
+UNUSED_VAR(vcache);
 THROW(ERR, "Obj_To_Host not supported in C bindings");
 UNREACHABLE_RETURN(void*);
 }
@@ -264,58 +265,58 @@ cfish_TestUtils_destroy_host_runtime(void *runtime) {
 / To_Host methods **/
 
 void*
-Str_To_Host_IMP(String *self) {
+Str_To_Host_IMP(String *self, void *vcache) {
 Str_To_Host_t super_to_host
 = SUPER_METHOD_PTR(STRING, CFISH_Str_To_Host);
-return super_to_host(self);
+return super_to_host(self, vcache);
 }
 
 void*
-Blob_To_Host_IMP(Blob *self) {
+Blob_To_Host_IMP(Blob *self, void *vcache) {
 Blob_To_Host_t super_to_host
 = SUPER_METHOD_PTR(BLOB, CFISH_Blob_To_Host);
-return super_to_host(self);
+return super_to_host(self, vcache);
 }
 
 void*
-BB_To_Host_IMP(ByteBuf *self) {
+BB_To_Host_IMP(ByteBuf *self, void *vcache) {
 BB_To_Host_t super_to_host
 = SUPER_METHOD_PTR(BYTEBUF, CFISH_BB_To_Host);
-return super_t

[03/14] lucy-clownfish git commit: Handle circular refs when converting to Perl

2016-03-19 Thread nwellnhof
Handle circular refs when converting to Perl

Also check for I32 overflow when converting Vector to AV.

Second half of CLOWNFISH-36.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d9829fb0
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d9829fb0
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d9829fb0

Branch: refs/heads/master
Commit: d9829fb0dfdfbedc39463d19e2d1958d9a84593d
Parents: f3eea9b
Author: Nick Wellnhofer 
Authored: Tue Mar 8 11:54:53 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 14:47:23 2016 +0100

--
 runtime/perl/t/binding/016-vector.t |  5 +-
 runtime/perl/t/binding/017-hash.t   | 15 --
 runtime/perl/xs/XSBind.c| 83 ++--
 3 files changed, 95 insertions(+), 8 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9829fb0/runtime/perl/t/binding/016-vector.t
--
diff --git a/runtime/perl/t/binding/016-vector.t 
b/runtime/perl/t/binding/016-vector.t
index 15c3942..7f07a53 100644
--- a/runtime/perl/t/binding/016-vector.t
+++ b/runtime/perl/t/binding/016-vector.t
@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 3;
+use Test::More tests => 4;
 use Clownfish qw( to_clownfish );
 
 my ( $vector, $twin );
@@ -57,3 +57,6 @@ is(
 'to_clownfish($arrayref) handles deep circular references'
 );
 
+my $roundtripped = $vector->to_perl;
+is_deeply( $roundtripped, $arrayref, 'to_perl handles circular references');
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9829fb0/runtime/perl/t/binding/017-hash.t
--
diff --git a/runtime/perl/t/binding/017-hash.t 
b/runtime/perl/t/binding/017-hash.t
index b69d8e7..f2aefa7 100644
--- a/runtime/perl/t/binding/017-hash.t
+++ b/runtime/perl/t/binding/017-hash.t
@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 12;
+use Test::More tests => 14;
 use Clownfish qw( to_clownfish );
 
 my $hash = Clownfish::Hash->new( capacity => 10 );
@@ -53,7 +53,16 @@ $hash = to_clownfish($hashref);
 is( $$hash, ${ $hash->fetch_raw('foo') },
 'to_clownfish($hashref) handles circular references' );
 
-$hash = to_clownfish({ key => $hashref })->fetch_raw('key');
-is( $$hash, ${ $hash->fetch_raw('bar')->fetch_raw(0) },
+my $roundtripped = $hash->to_perl;
+is_deeply( $roundtripped, $hashref, 'to_perl handles circular references' );
+
+$hashref = { key => $hashref };
+$hash = to_clownfish($hashref);
+my $val = $hash->fetch_raw('key');
+is( $$val, ${ $val->fetch_raw('bar')->fetch_raw(0) },
 'to_clownfish($hashref) handles deep circular references' );
 
+$roundtripped = $hash->to_perl;
+is_deeply( $roundtripped, $hashref,
+   'to_perl handles deep circular references' );
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9829fb0/runtime/perl/xs/XSBind.c
--
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 793d5eb..1fdb836 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -987,25 +987,64 @@ CFISH_BB_To_Host_IMP(cfish_ByteBuf *self, void *vcache) {
 void*
 CFISH_Vec_To_Host_IMP(cfish_Vector *self, void *vcache) {
 dTHX;
+cfish_ConversionCache *cache = (cfish_ConversionCache*)vcache;
+cfish_ConversionCache  new_cache;
+
+if (cache) {
+// Lookup Vector in conversion cache.
+if ((cfish_Obj*)self == cache->root_obj) {
+return newRV_inc(cache->root_sv);
+}
+if (cache->seen) {
+void *cached_av = CFISH_PtrHash_Fetch(cache->seen, self);
+if (cached_av) {
+return newRV_inc((SV*)cached_av);
+}
+}
+}
+
 AV *perl_array = newAV();
-uint32_t num_elems = CFISH_Vec_Get_Size(self);
+
+if (!cache) {
+// Set up conversion cache.
+cache = &new_cache;
+cache->root_obj = (cfish_Obj*)self;
+cache->root_sv  = (SV*)perl_array;
+cache->seen = NULL;
+}
+else {
+if (!cache->seen) {
+// Create PtrHash lazily.
+cache->seen = cfish_PtrHash_new(0);
+}
+CFISH_PtrHash_Store(cache->seen, self, perl_array);
+}
+
+size_t num_elems = CFISH_Vec_Get_Size(self);
 
 // Iterate over array elems.
 if (num_elems) {
+if (num_elems > I32_MAX) {
+THROW(CFISH_ERR, "Vector too large for Perl AV");
+}
 av_fill(perl_array, num_elems - 1);
-for (uint32_t i = 0; i < num_elems; i++) {
+for (size_t i = 0; i < num_elems; i++) {
 cfish_Obj *val = CFISH_Vec_Fetch(self, i);
  

[09/14] lucy-clownfish git commit: Keep CLASS->obj_alloc_size at 0

2016-03-19 Thread nwellnhof
Keep CLASS->obj_alloc_size at 0

This makes sure that Init_Obj doesn't reset any values when bootstrapping.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/70f2562d
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/70f2562d
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/70f2562d

Branch: refs/heads/master
Commit: 70f2562db5dbd3614b8a6b36f2a1562cdf7f9e05
Parents: 7528af4
Author: Nick Wellnhofer 
Authored: Thu Mar 10 20:48:58 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:49:25 2016 +0100

--
 runtime/core/Clownfish/Class.c | 35 ++---
 runtime/go/clownfish/class_test.go |  4 ++--
 2 files changed, 12 insertions(+), 27 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/70f2562d/runtime/core/Clownfish/Class.c
--
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index bfa9978..86fe7c1 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -93,14 +93,6 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 // Needed to calculate size of subclasses.
 klass->class_alloc_size = class_alloc_size;
 
-if (spec->klass == &CLASS) {
-// `obj_alloc_size` is used by Init_Obj to zero the object. In the
-// next pass, this method is called to initialize the Class
-// objects. The Class struct is zeroed already, so this isn't
-// crucial, but let's set the correct value here.
-klass->obj_alloc_size = offsetof(Class, vtable);
-}
-
 // Initialize the global pointer to the Class.
 if (!Atomic_cas_ptr((void**)spec->klass, NULL, klass)) {
 // Another thread beat us to it.
@@ -138,26 +130,15 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 }
 }
 
-// Init_Obj clears all klass ivars, so `class_alloc_size` must be
-// recalculated.
+// CLASS->obj_alloc_size is always 0, so Init_Obj doesn't clear any
+// values set in the previous pass or by another thread.
 Class_Init_Obj_IMP(CLASS, klass);
 
-uint32_t novel_offset = parent
-? parent->class_alloc_size
-: offsetof(Class, vtable);
-uint32_t class_alloc_size = novel_offset
-+ spec->num_novel_meths
-  * sizeof(cfish_method_t);
-
-klass->parent   = parent;
-klass->parcel_id= parcel_id;
-klass->class_alloc_size = class_alloc_size;
+klass->parent= parent;
+klass->parcel_id = parcel_id;
 
-if (klass == CLASS) {
-// Don't account for vtable array.
-klass->obj_alloc_size = offsetof(Class, vtable);
-}
-else {
+// CLASS->obj_alloc_size must stay at 0.
+if (klass != CLASS) {
 klass->obj_alloc_size = ivars_offset + spec->ivars_size;
 }
 if (cfish_Class_bootstrap_hook1 != NULL) {
@@ -195,6 +176,10 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 Class_Override_IMP(klass, mspec->func, *mspec->offset);
 }
 
+uint32_t novel_offset = parent
+? parent->class_alloc_size
+: offsetof(Class, vtable);
+
 for (size_t i = 0; i < spec->num_novel_meths; ++i) {
 const NovelMethSpec *mspec = &novel_specs[num_novel++];
 *mspec->offset = novel_offset;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/70f2562d/runtime/go/clownfish/class_test.go
--
diff --git a/runtime/go/clownfish/class_test.go 
b/runtime/go/clownfish/class_test.go
index ebd3a68..b96b1e0 100644
--- a/runtime/go/clownfish/class_test.go
+++ b/runtime/go/clownfish/class_test.go
@@ -36,8 +36,8 @@ func TestClassGetParent(t *testing.T) {
 
 func TestClassGetObjAllocSize(t *testing.T) {
intClass := FetchClass("Clownfish::Integer")
-   classClass := FetchClass("Clownfish::Class")
-   if intClass.GetObjAllocSize() >= classClass.GetObjAllocSize() {
+   objClass := FetchClass("Clownfish::Obj")
+   if intClass.GetObjAllocSize() <= objClass.GetObjAllocSize() {
t.Error("Unexpected result for getObjAllocSize")
}
 }



[07/14] lucy-clownfish git commit: Make bootstrap_parcel thread-safe

2016-03-19 Thread nwellnhof
Make bootstrap_parcel thread-safe

Remove bootstrap_inheritance.

Add bootstrap_internal which invokes Class_bootstrap and parcel_init only
for a single parcel.

Detect inheritance cycles in Class_bootstrap.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d7c863b9
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d7c863b9
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d7c863b9

Branch: refs/heads/master
Commit: d7c863b92dae97fd8a7eea93364941607e4921e1
Parents: ce1fe99
Author: Nick Wellnhofer 
Authored: Thu Mar 10 19:06:53 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:23:57 2016 +0100

--
 compiler/src/CFCBindCore.c | 56 +
 runtime/core/Clownfish/Class.c | 12 +++-
 2 files changed, 24 insertions(+), 44 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d7c863b9/compiler/src/CFCBindCore.c
--
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index e5b23ce..4b2d3c6 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -362,13 +362,13 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
 "\n"
 "%s" // Extra definitions.
 "%sVISIBLE void\n"
-"%sbootstrap_inheritance();\n"
+"%sbootstrap_internal(void);\n"
 "\n"
 "%sVISIBLE void\n"
-"%sbootstrap_parcel();\n"
+"%sbootstrap_parcel(void);\n"
 "\n"
 "void\n"
-"%sinit_parcel();\n"
+"%sinit_parcel(void);\n"
 "\n"
 "#ifdef __cplusplus\n"
 "}\n"
@@ -439,30 +439,12 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
 char *spec_init_func = CFCBindSpecs_init_func_def(specs);
 FREEMEM(ordered);
 
-// Bootstrapping code for prerequisite parcels.
-//
-// bootstrap_inheritance() first calls bootstrap_inheritance() for all
-// parcels from which classes are inherited. Then the Classes of the parcel
-// are initialized. It aborts on recursive invocation.
-//
-// bootstrap_parcel() first calls bootstrap_inheritance() of its own
-// parcel. Then it calls bootstrap_parcel() for all prerequisite parcels.
-// Finally, it calls init_parcel(). Recursive invocation is allowed.
-
-char *inh_bootstrap= CFCUtil_strdup("");
 char *prereq_bootstrap = CFCUtil_strdup("");
-CFCParcel **inh_parcels = CFCParcel_inherited_parcels(parcel);
-for (size_t i = 0; inh_parcels[i]; ++i) {
-const char *inh_prefix = CFCParcel_get_prefix(inh_parcels[i]);
-inh_bootstrap = CFCUtil_cat(inh_bootstrap, "", inh_prefix,
-"bootstrap_inheritance();\n", NULL);
-}
-FREEMEM(inh_parcels);
 CFCParcel **prereq_parcels = CFCParcel_prereq_parcels(parcel);
 for (size_t i = 0; prereq_parcels[i]; ++i) {
 const char *prereq_prefix = CFCParcel_get_prefix(prereq_parcels[i]);
 prereq_bootstrap = CFCUtil_cat(prereq_bootstrap, "", prereq_prefix,
-   "bootstrap_parcel();\n", NULL);
+   "bootstrap_internal();\n", NULL);
 }
 FREEMEM(prereq_parcels);
 
@@ -490,37 +472,26 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
 "\n"
 "%s" // spec_init_func
 "\n"
-"static int bootstrap_state = 0;\n"
-"\n"
 "void\n"
-"%sbootstrap_inheritance() {\n"
-"if (bootstrap_state == 1) {\n"
-"fprintf(stderr, \"Cycle in class inheritance between\"\n"
-"\" parcels detected.\\n\");\n"
-"abort();\n"
-"}\n"
-"if (bootstrap_state >= 2) { return; }\n"
-"bootstrap_state = 1;\n"
-"%s" // Bootstrap inherited parcels.
+"%sbootstrap_internal() {\n"
+"static int bootstrapped = 0;\n"
+"if (bootstrapped) { return; }\n"
 "S_bootstrap_specs();\n"
-"bootstrap_state = 2;\n"
+"%sinit_parcel();\n"
+"bootstrapped = 1;\n"
 "}\n"
 "\n"
 "void\n"
 "%sbootstrap_parcel() {\n"
-"if (bootstrap_state >= 3) { return; }\n"
-"%sbootstrap_inheritance();\n"
-"bootstrap_state = 3;\n"
-"%s" // Finish bootstrapping of all prerequisite parcels.
-"%sinit_parcel();\n"
+"%s" // Bootstrap prerequisite parcels.
+"%sbootstrap_internal();\n"
 "}\n"
 "\n"
 "%s\n";
 char *file_content
 = CFCUtil_sprintf(pattern, self->c_header, privacy_syms, includes,
-  c_da

[11/14] lucy-clownfish git commit: Introduce struct cfish_ParcelSpec

2016-03-19 Thread nwellnhof
Introduce struct cfish_ParcelSpec

Change Class_bootstrap to take a single pointer to struct
cfish_ParcelSpec.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/8b71db60
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/8b71db60
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/8b71db60

Branch: refs/heads/master
Commit: 8b71db60c361fde4135e7b16b4e018a48bae1d2f
Parents: 70f2562
Author: Nick Wellnhofer 
Authored: Thu Mar 10 21:15:12 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:49:25 2016 +0100

--
 compiler/src/CFCBindSpecs.c  | 24 
 runtime/core/Clownfish/Class.c   | 17 ++---
 runtime/core/Clownfish/Class.cfh |  5 +
 3 files changed, 31 insertions(+), 15 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8b71db60/compiler/src/CFCBindSpecs.c
--
diff --git a/compiler/src/CFCBindSpecs.c b/compiler/src/CFCBindSpecs.c
index d9aecca..ee10a50 100644
--- a/compiler/src/CFCBindSpecs.c
+++ b/compiler/src/CFCBindSpecs.c
@@ -131,6 +131,14 @@ CFCBindSpecs_get_typedefs() {
 "uint32_t  num_inherited_meths;\n"
 "uint32_t  flags;\n"
 "} cfish_ClassSpec;\n"
+"\n"
+"typedef struct cfish_ParcelSpec {\n"
+"const cfish_ClassSpec  *class_specs;\n"
+"const cfish_NovelMethSpec  *novel_specs;\n"
+"const cfish_OverriddenMethSpec *overridden_specs;\n"
+"const cfish_InheritedMethSpec  *inherited_specs;\n"
+"uint32_t num_classes;\n"
+"} cfish_ParcelSpec;\n"
 "\n";
 }
 
@@ -267,9 +275,18 @@ CFCBindSpecs_defs(CFCBindSpecs *self) {
 "%s"
 "static cfish_ClassSpec class_specs[] = {\n"
 "%s\n"
+"};\n"
+"\n"
+"static const cfish_ParcelSpec parcel_spec = {\n"
+"class_specs,\n"
+"novel_specs,\n"
+"overridden_specs,\n"
+"inherited_specs,\n"
+"%d\n" // num_classes
 "};\n";
 char *defs = CFCUtil_sprintf(pattern, novel_specs, overridden_specs,
- inherited_specs, self->class_specs);
+ inherited_specs, self->class_specs,
+ self->num_specs);
 
 FREEMEM(inherited_specs);
 FREEMEM(overridden_specs);
@@ -284,10 +301,9 @@ CFCBindSpecs_init_func_def(CFCBindSpecs *self) {
 "S_bootstrap_specs() {\n"
 "%s"
 "\n"
-"cfish_Class_bootstrap(class_specs, %d, novel_specs,\n"
-"  overridden_specs, inherited_specs);\n"
+"cfish_Class_bootstrap(&parcel_spec);\n"
 "}\n";
-return CFCUtil_sprintf(pattern, self->init_code, self->num_specs);
+return CFCUtil_sprintf(pattern, self->init_code);
 }
 
 static char*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8b71db60/runtime/core/Clownfish/Class.c
--
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 86fe7c1..15cde2c 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -57,17 +57,20 @@ static LockFreeRegistry *Class_registry;
 cfish_Class_bootstrap_hook1_t cfish_Class_bootstrap_hook1;
 
 void
-Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
-const cfish_NovelMethSpec *novel_specs,
-const cfish_OverriddenMethSpec *overridden_specs,
-const cfish_InheritedMethSpec *inherited_specs) {
+Class_bootstrap(const cfish_ParcelSpec *parcel_spec) {
+const ClassSpec  *specs= parcel_spec->class_specs;
+const NovelMethSpec  *novel_specs  = parcel_spec->novel_specs;
+const OverriddenMethSpec *overridden_specs = parcel_spec->overridden_specs;
+const InheritedMethSpec  *inherited_specs  = parcel_spec->inherited_specs;
+uint32_t num_classes = parcel_spec->num_classes;
+
 int32_t parcel_id = S_claim_parcel_id();
 
 /* Pass 1:
  * - Allocate memory.
  * - Initialize global Class pointers.
  */
-for (size_t i = 0; i < num_specs; ++i) {
+for (uint32_t i = 0; i < num_classes; ++i) {
 const ClassSpec *spec = &specs[i];
 Class *parent = NULL;
 
@@ -110,7 +113,7 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 uint32_t num_novel  = 0;
 uint32_t num_overridden = 0;
 uint32_t num_inherited  = 0;
-for (size_t i = 0; i < num_specs; ++i) {
+for (uint32_t i = 0; i < num_classes; ++i) {
 const ClassSpec *spec = &specs[i];
 Class *klass  = *spec->kla

[02/14] lucy-clownfish git commit: Handle circular refs when converting from Perl

2016-03-19 Thread nwellnhof
Handle circular refs when converting from Perl

First half of CLOWNFISH-36.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/3e0546fa
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/3e0546fa
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/3e0546fa

Branch: refs/heads/master
Commit: 3e0546fabc8a2c3953561e184fc3bc5d2a10a8f1
Parents: 6c8dbb3
Author: Nick Wellnhofer 
Authored: Tue Mar 8 11:54:42 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 14:29:29 2016 +0100

--
 runtime/perl/t/binding/016-vector.t |  29 ++-
 runtime/perl/t/binding/017-hash.t   |  14 +++-
 runtime/perl/xs/XSBind.c| 128 +++
 3 files changed, 151 insertions(+), 20 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/3e0546fa/runtime/perl/t/binding/016-vector.t
--
diff --git a/runtime/perl/t/binding/016-vector.t 
b/runtime/perl/t/binding/016-vector.t
index ff2e547..15c3942 100644
--- a/runtime/perl/t/binding/016-vector.t
+++ b/runtime/perl/t/binding/016-vector.t
@@ -16,8 +16,8 @@
 use strict;
 use warnings;
 
-use Test::More tests => 1;
-use Clownfish;
+use Test::More tests => 3;
+use Clownfish qw( to_clownfish );
 
 my ( $vector, $twin );
 
@@ -32,3 +32,28 @@ $vector->insert(
 $twin = $vector->clone_raw;
 is_deeply( $twin->to_perl, $vector->to_perl, "clone" );
 
+use Data::Dumper;
+
+my $hashref  = { foo => 'Foo', bar => 'Bar' };
+$hashref->{baz} = [ { circular => [ undef, $hashref ], one => 'One' } ];
+
+my $arrayref = [];
+push( @$arrayref, [] ) for 1..5000;
+push( @$arrayref, $arrayref, { key => $arrayref }, 42, $hashref, 'string' );
+
+$vector = to_clownfish($arrayref);
+is( $$vector, ${ $vector->fetch_raw(5000) },
+'to_clownfish($arrayref) handles circular references' );
+
+my $hash = $vector->fetch_raw(5003);
+is(
+$$hash,
+${
+$hash->fetch_raw('baz')
+ ->fetch_raw(0)
+ ->fetch_raw('circular')
+ ->fetch_raw(1)
+},
+'to_clownfish($arrayref) handles deep circular references'
+);
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/3e0546fa/runtime/perl/t/binding/017-hash.t
--
diff --git a/runtime/perl/t/binding/017-hash.t 
b/runtime/perl/t/binding/017-hash.t
index 9b26829..b69d8e7 100644
--- a/runtime/perl/t/binding/017-hash.t
+++ b/runtime/perl/t/binding/017-hash.t
@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 10;
+use Test::More tests => 12;
 use Clownfish qw( to_clownfish );
 
 my $hash = Clownfish::Hash->new( capacity => 10 );
@@ -45,3 +45,15 @@ my $round_tripped = to_clownfish( \%hash_with_utf8_keys 
)->to_perl;
 is_deeply( $round_tripped, \%hash_with_utf8_keys,
 "Round trip conversion of hash with UTF-8 keys" );
 
+my $hashref = {};
+$hashref->{foo} = $hashref;
+$hashref->{bar} = [ $hashref ];
+
+$hash = to_clownfish($hashref);
+is( $$hash, ${ $hash->fetch_raw('foo') },
+'to_clownfish($hashref) handles circular references' );
+
+$hash = to_clownfish({ key => $hashref })->fetch_raw('key');
+is( $$hash, ${ $hash->fetch_raw('bar')->fetch_raw(0) },
+'to_clownfish($hashref) handles deep circular references' );
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/3e0546fa/runtime/perl/xs/XSBind.c
--
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 85bd85b..a4f9046 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -30,6 +30,7 @@
 #include "Clownfish/HashIterator.h"
 #include "Clownfish/Method.h"
 #include "Clownfish/Num.h"
+#include "Clownfish/PtrHash.h"
 #include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/Util/Atomic.h"
 #include "Clownfish/Util/StringHelper.h"
@@ -38,19 +39,29 @@
 #define XSBIND_REFCOUNT_FLAG   1
 #define XSBIND_REFCOUNT_SHIFT  1
 
+// Used to remember converted objects in array and hash conversion to
+// handle circular references. The root object and SV are stored separately
+// to allow lazy creation of the seen PtrHash.
+typedef struct {
+cfish_Obj *root_obj;
+SV*root_sv;
+cfish_PtrHash *seen;
+} cfish_ConversionCache;
+
 static bool
 S_maybe_perl_to_cfish(pTHX_ SV *sv, cfish_Class *klass, bool increment,
-  void *allocation, cfish_Obj **obj_ptr);
+  void *allocation, cfish_ConversionCache *cache,
+  cfish_Obj **obj_ptr);
 
 // Convert a Perl hash into a Clownfish Hash.  Caller takes responsibility for
 // a refcount.
 static cfish_Hash*
-S_perl_hash_to_cfish_hash(pTHX_ HV *phash);
+S_perl_hash_to_cfish_hash(pTHX_ HV *p

[05/14] lucy-clownfish git commit: Implement dtors for Class and Method

2016-03-19 Thread nwellnhof
Implement dtors for Class and Method

Only for internal use. Destructors of immortal types won't be invoked
via DECREF, so they must be called directly.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/dc56c144
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/dc56c144
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/dc56c144

Branch: refs/heads/master
Commit: dc56c144cace1d9faa70e857ae98596cfee2329d
Parents: 20eef8f
Author: Nick Wellnhofer 
Authored: Thu Mar 10 15:11:36 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:22:42 2016 +0100

--
 runtime/core/Clownfish/Class.c  | 11 ++-
 runtime/core/Clownfish/Method.c |  7 ++-
 2 files changed, 16 insertions(+), 2 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dc56c144/runtime/core/Clownfish/Class.c
--
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 68258c6..1ab7523 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -224,7 +224,16 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t 
num_specs,
 
 void
 Class_Destroy_IMP(Class *self) {
-THROW(ERR, "Insane attempt to destroy Class for class '%o'", self->name);
+for (size_t i = 0; self->methods[i]; i++) {
+// Call Destroy directly instead of going through DECREF.
+Method_Destroy(self->methods[i]);
+}
+FREEMEM(self->methods);
+
+DECREF(self->name);
+DECREF(self->name_internal);
+
+SUPER_DESTROY(self, CLASS);
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dc56c144/runtime/core/Clownfish/Method.c
--
diff --git a/runtime/core/Clownfish/Method.c b/runtime/core/Clownfish/Method.c
index a044f35..44bcdb4 100644
--- a/runtime/core/Clownfish/Method.c
+++ b/runtime/core/Clownfish/Method.c
@@ -54,7 +54,12 @@ Method_init(Method *self, String *name, cfish_method_t 
callback_func,
 
 void
 Method_Destroy_IMP(Method *self) {
-THROW(ERR, "Insane attempt to destroy Method '%o'", self->name);
+DECREF(self->name);
+DECREF(self->name_internal);
+DECREF(self->host_alias);
+DECREF(self->host_alias_internal);
+
+SUPER_DESTROY(self, METHOD);
 }
 
 String*



[10/14] lucy-clownfish git commit: Test idempotence of bootstrap process

2016-03-19 Thread nwellnhof
Test idempotence of bootstrap process


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/7cc75eb8
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/7cc75eb8
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/7cc75eb8

Branch: refs/heads/master
Commit: 7cc75eb8dd53bb63966170629ec66cdbc62e7d34
Parents: 25f58a6
Author: Nick Wellnhofer 
Authored: Thu Mar 10 20:05:20 2016 +0100
Committer: Nick Wellnhofer 
Committed: Thu Mar 10 21:49:25 2016 +0100

--
 compiler/src/CFCBindCore.c| 10 +--
 runtime/core/Clownfish/Test.c |  2 +
 runtime/core/Clownfish/Test/TestClass.c   | 93 ++
 runtime/core/Clownfish/Test/TestClass.cfh | 28 
 runtime/perl/t/core/010-class.t   | 23 +++
 5 files changed, 151 insertions(+), 5 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7cc75eb8/compiler/src/CFCBindCore.c
--
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index 4b2d3c6..7d43415 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -362,7 +362,7 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
 "\n"
 "%s" // Extra definitions.
 "%sVISIBLE void\n"
-"%sbootstrap_internal(void);\n"
+"%sbootstrap_internal(int force);\n"
 "\n"
 "%sVISIBLE void\n"
 "%sbootstrap_parcel(void);\n"
@@ -444,7 +444,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
 for (size_t i = 0; prereq_parcels[i]; ++i) {
 const char *prereq_prefix = CFCParcel_get_prefix(prereq_parcels[i]);
 prereq_bootstrap = CFCUtil_cat(prereq_bootstrap, "", prereq_prefix,
-   "bootstrap_internal();\n", NULL);
+   "bootstrap_internal(0);\n", NULL);
 }
 FREEMEM(prereq_parcels);
 
@@ -473,9 +473,9 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
 "%s" // spec_init_func
 "\n"
 "void\n"
-"%sbootstrap_internal() {\n"
+"%sbootstrap_internal(int force) {\n"
 "static int bootstrapped = 0;\n"
-"if (bootstrapped) { return; }\n"
+"if (bootstrapped && !force) { return; }\n"
 "S_bootstrap_specs();\n"
 "%sinit_parcel();\n"
 "bootstrapped = 1;\n"
@@ -484,7 +484,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
 "void\n"
 "%sbootstrap_parcel() {\n"
 "%s" // Bootstrap prerequisite parcels.
-"%sbootstrap_internal();\n"
+"%sbootstrap_internal(0);\n"
 "}\n"
 "\n"
 "%s\n";

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7cc75eb8/runtime/core/Clownfish/Test.c
--
diff --git a/runtime/core/Clownfish/Test.c b/runtime/core/Clownfish/Test.c
index 9f03448..a275b0c 100644
--- a/runtime/core/Clownfish/Test.c
+++ b/runtime/core/Clownfish/Test.c
@@ -26,6 +26,7 @@
 #include "Clownfish/Test/TestByteBuf.h"
 #include "Clownfish/Test/TestString.h"
 #include "Clownfish/Test/TestCharBuf.h"
+#include "Clownfish/Test/TestClass.h"
 #include "Clownfish/Test/TestErr.h"
 #include "Clownfish/Test/TestHash.h"
 #include "Clownfish/Test/TestHashIterator.h"
@@ -41,6 +42,7 @@ TestSuite*
 Test_create_test_suite() {
 TestSuite *suite = TestSuite_new();
 
+TestSuite_Add_Batch(suite, (TestBatch*)TestClass_new());
 TestSuite_Add_Batch(suite, (TestBatch*)TestVector_new());
 TestSuite_Add_Batch(suite, (TestBatch*)TestHash_new());
 TestSuite_Add_Batch(suite, (TestBatch*)TestHashIterator_new());

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7cc75eb8/runtime/core/Clownfish/Test/TestClass.c
--
diff --git a/runtime/core/Clownfish/Test/TestClass.c 
b/runtime/core/Clownfish/Test/TestClass.c
new file mode 100644
index 000..fc16a90
--- /dev/null
+++ b/runtime/core/Clownfish/Test/TestClass.c
@@ -0,0 +1,93 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * W

[13/14] lucy-clownfish git commit: Merge branch 'circular-refs'

2016-03-19 Thread nwellnhof
Merge branch 'circular-refs'

Fixes CLOWNFISH-36.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/94eed76c
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/94eed76c
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/94eed76c

Branch: refs/heads/master
Commit: 94eed76c4753273abe6aca06e921c8f4f5750870
Parents: f5139ff d9829fb
Author: Nick Wellnhofer 
Authored: Sat Mar 19 18:22:12 2016 +0100
Committer: Nick Wellnhofer 
Committed: Sat Mar 19 18:22:12 2016 +0100

--
 compiler/src/CFCPerlMethod.c|   2 +-
 compiler/src/CFCPerlTypeMap.c   |   2 +-
 runtime/c/src/clownfish.c   |  35 +--
 runtime/core/Clownfish/Blob.cfh |   2 +-
 runtime/core/Clownfish/Boolean.cfh  |   2 +-
 runtime/core/Clownfish/ByteBuf.cfh  |   2 +-
 runtime/core/Clownfish/Hash.cfh |   2 +-
 runtime/core/Clownfish/Num.cfh  |   4 +-
 runtime/core/Clownfish/Obj.cfh  |   2 +-
 runtime/core/Clownfish/PtrHash.c| 226 +
 runtime/core/Clownfish/PtrHash.h|  53 
 runtime/core/Clownfish/String.cfh   |   2 +-
 runtime/core/Clownfish/Test.c   |   2 +
 runtime/core/Clownfish/Test/TestPtrHash.c   | 108 
 runtime/core/Clownfish/Test/TestPtrHash.cfh |  29 +++
 runtime/core/Clownfish/Vector.cfh   |   2 +-
 runtime/example-lang/src/Clownfish/Obj.c|   2 +-
 runtime/go/ext/clownfish.c  |  38 +--
 .../perl/buildlib/Clownfish/Build/Binding.pm|  11 +-
 runtime/perl/t/binding/016-vector.t |  32 ++-
 runtime/perl/t/binding/017-hash.t   |  23 +-
 runtime/perl/t/core/050-ptrhash.t   |  23 ++
 runtime/perl/xs/XSBind.c| 252 ---
 runtime/perl/xs/XSBind.h|   2 +-
 runtime/python/cfext/CFBind.c   |  27 +-
 runtime/python/cfext/CFBind.h   |   4 +-
 26 files changed, 784 insertions(+), 105 deletions(-)
--