You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2015/05/12 18:37:14 UTC

[5/7] lucy-clownfish git commit: Eliminate StackString

Eliminate StackString

Use normal stack-allocated Strings instead of StackStrings.

The only downside is that there will be an invalid free instead of an
exception if someone tries to decref a stack String. But decref is
inherently dangerous. With heap-allocated objects, an unmatched decref
also results in a use-after-free which can't be guarded against.


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

Branch: refs/heads/master
Commit: 50fed28da1a26014dcca6b1a9904127d8e593bac
Parents: 02ba4bd
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat May 9 22:06:28 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue May 12 18:34:59 2015 +0200

----------------------------------------------------------------------
 compiler/src/CFCPerlSub.c                       |  2 +-
 compiler/src/CFCPerlTypeMap.c                   |  4 +--
 runtime/c/src/Clownfish/Obj.c                   |  2 +-
 runtime/core/Clownfish/Class.c                  | 16 +++++------
 runtime/core/Clownfish/Hash.c                   | 12 ++++----
 runtime/core/Clownfish/String.c                 | 24 ++++------------
 runtime/core/Clownfish/String.cfh               | 19 ++++---------
 runtime/core/Clownfish/Test/TestHash.c          | 30 ++++++++++----------
 runtime/core/Clownfish/Test/TestObj.c           |  6 ++--
 runtime/core/Clownfish/Test/TestVector.c        |  2 +-
 runtime/go/ext/clownfish.c                      |  2 +-
 .../perl/buildlib/Clownfish/Build/Binding.pm    |  7 ++---
 runtime/perl/lib/Clownfish.pm                   | 10 -------
 runtime/perl/xs/XSBind.c                        | 14 ++++-----
 runtime/perl/xs/XSBind.h                        | 10 +++----
 15 files changed, 63 insertions(+), 97 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/compiler/src/CFCPerlSub.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlSub.c b/compiler/src/CFCPerlSub.c
index d531044..1695b43 100644
--- a/compiler/src/CFCPerlSub.c
+++ b/compiler/src/CFCPerlSub.c
@@ -154,7 +154,7 @@ S_allot_params_arg(CFCType *type, const char *label, int required) {
             use_sv_buffer = true;
         }
         const char *allocation = use_sv_buffer
-                                 ? "CFISH_ALLOCA_OBJ(CFISH_STACKSTRING)"
+                                 ? "CFISH_ALLOCA_OBJ(CFISH_STRING)"
                                  : "NULL";
         const char pattern[] = "ALLOT_OBJ(&arg_%s, \"%s\", %u, %s, %s, %s)";
         char *arg = CFCUtil_sprintf(pattern, label, label, label_len,

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/compiler/src/CFCPerlTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlTypeMap.c b/compiler/src/CFCPerlTypeMap.c
index 349d79f..a07928c 100644
--- a/compiler/src/CFCPerlTypeMap.c
+++ b/compiler/src/CFCPerlTypeMap.c
@@ -47,7 +47,7 @@ CFCPerlTypeMap_from_perl(CFCType *type, const char *xs_var) {
            ) {
             // Share buffers rather than copy between Perl scalars and
             // Clownfish string types.
-            allocation = "CFISH_ALLOCA_OBJ(CFISH_STACKSTRING)";
+            allocation = "CFISH_ALLOCA_OBJ(CFISH_STRING)";
         }
         else {
             allocation = "NULL";
@@ -266,7 +266,7 @@ CFCPerlTypeMap_write_xs_typemap(CFCHierarchy *hierarchy) {
         if (strcmp(full_struct_sym, "cfish_String") == 0) {
             // Share buffers rather than copy between Perl scalars and
             // Clownfish string types.
-            allocation = "CFISH_ALLOCA_OBJ(CFISH_STACKSTRING)";
+            allocation = "CFISH_ALLOCA_OBJ(CFISH_STRING)";
         }
         else {
             allocation = "NULL";

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/c/src/Clownfish/Obj.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/Obj.c b/runtime/c/src/Clownfish/Obj.c
index cb9af10..4b753cb 100644
--- a/runtime/c/src/Clownfish/Obj.c
+++ b/runtime/c/src/Clownfish/Obj.c
@@ -38,7 +38,7 @@ SI_immortal(cfish_Class *klass) {
 
 static CFISH_INLINE bool
 SI_is_string_type(cfish_Class *klass) {
-    if (klass == CFISH_STRING || klass == CFISH_STACKSTRING) {
+    if (klass == CFISH_STRING) {
         return true;
     }
     return false;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index ed74bed..6752135 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -101,7 +101,6 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
             || spec->klass == &METHOD
             || spec->klass == &BOOLNUM
             || spec->klass == &STRING
-            || spec->klass == &STACKSTRING
            ) {
             klass->flags |= CFISH_fREFCOUNTSPECIAL;
         }
@@ -169,9 +168,8 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
         // Only store novel methods for now.
         for (size_t i = 0; i < spec->num_novel_meths; ++i) {
             const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
-            StackString *name
-                = SSTR_WRAP_UTF8(mspec->name, strlen(mspec->name));
-            Method *method = Method_new((String*)name, mspec->callback_func,
+            String *name = SSTR_WRAP_UTF8(mspec->name, strlen(mspec->name));
+            Method *method = Method_new(name, mspec->callback_func,
                                         *mspec->offset);
             klass->methods[i] = method;
         }
@@ -341,12 +339,12 @@ Class_add_alias_to_registry(Class *klass, const char *alias_ptr,
     if (Class_registry == NULL) {
         Class_init_registry();
     }
-    StackString *alias = SSTR_WRAP_UTF8(alias_ptr, alias_len);
-    if (LFReg_fetch(Class_registry, (String*)alias)) {
+    String *alias = SSTR_WRAP_UTF8(alias_ptr, alias_len);
+    if (LFReg_fetch(Class_registry, alias)) {
         return false;
     }
     else {
-        String *class_name = SStr_Clone(alias);
+        String *class_name = Str_Clone(alias);
         bool retval = LFReg_register(Class_registry, class_name, (Obj*)klass);
         DECREF(class_name);
         return retval;
@@ -366,12 +364,12 @@ void
 Class_Add_Host_Method_Alias_IMP(Class *self, const char *alias,
                              const char *meth_name) {
     Method *method = S_find_method(self, meth_name);
-    StackString *alias_cf = SSTR_WRAP_UTF8(alias, strlen(alias));
     if (!method) {
         fprintf(stderr, "Method %s not found\n", meth_name);
         abort();
     }
-    Method_Set_Host_Alias(method, (String*)alias_cf);
+    String *string = SSTR_WRAP_UTF8(alias, strlen(alias));
+    Method_Set_Host_Alias(method, string);
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/Hash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Hash.c b/runtime/core/Clownfish/Hash.c
index 68326a8..90e8959 100644
--- a/runtime/core/Clownfish/Hash.c
+++ b/runtime/core/Clownfish/Hash.c
@@ -158,14 +158,14 @@ Hash_Store_IMP(Hash *self, String *key, Obj *value) {
 
 void
 Hash_Store_Utf8_IMP(Hash *self, const char *key, size_t key_len, Obj *value) {
-    StackString *key_buf = SSTR_WRAP_UTF8((char*)key, key_len);
-    S_do_store(self, (String*)key_buf, value, SStr_Hash_Sum(key_buf), true);
+    String *key_buf = SSTR_WRAP_UTF8((char*)key, key_len);
+    S_do_store(self, key_buf, value, Str_Hash_Sum(key_buf), true);
 }
 
 Obj*
 Hash_Fetch_Utf8_IMP(Hash *self, const char *key, size_t key_len) {
-    StackString *key_buf = SSTR_WRAP_UTF8(key, key_len);
-    return Hash_Fetch_IMP(self, (String*)key_buf);
+    String *key_buf = SSTR_WRAP_UTF8(key, key_len);
+    return Hash_Fetch_IMP(self, key_buf);
 }
 
 static CFISH_INLINE HashEntry*
@@ -217,8 +217,8 @@ Hash_Delete_IMP(Hash *self, String *key) {
 
 Obj*
 Hash_Delete_Utf8_IMP(Hash *self, const char *key, size_t key_len) {
-    StackString *key_buf = SSTR_WRAP_UTF8(key, key_len);
-    return Hash_Delete_IMP(self, (String*)key_buf);
+    String *key_buf = SSTR_WRAP_UTF8(key, key_len);
+    return Hash_Delete_IMP(self, key_buf);
 }
 
 String*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/String.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/String.c b/runtime/core/Clownfish/String.c
index e077050..382ef6c 100644
--- a/runtime/core/Clownfish/String.c
+++ b/runtime/core/Clownfish/String.c
@@ -15,7 +15,6 @@
  */
 
 #define C_CFISH_STRING
-#define C_CFISH_STACKSTRING
 #define C_CFISH_STRINGITERATOR
 #define CFISH_USE_SHORT_NAMES
 
@@ -119,6 +118,12 @@ Str_new_wrap_trusted_utf8(const char *utf8, size_t size) {
 }
 
 String*
+Str_new_stack_string(void *allocation, const char *utf8, size_t size) {
+    String *self = (String*)Class_Init_Obj(STRING, allocation);
+    return Str_init_wrap_trusted_utf8(self, utf8, size);
+}
+
+String*
 Str_init_wrap_trusted_utf8(String *self, const char *ptr, size_t size) {
     self->ptr    = ptr;
     self->size   = size;
@@ -518,23 +523,6 @@ Str_Tail_IMP(String *self) {
 
 /*****************************************************************/
 
-StackString*
-SStr_wrap_utf8(void *allocation, const char *ptr, size_t size) {
-    StackString *self
-        = (StackString*)Class_Init_Obj(STACKSTRING, allocation);
-    self->size   = size;
-    self->ptr    = ptr;
-    self->origin = NULL;
-    return self;
-}
-
-void
-SStr_Destroy_IMP(StackString *self) {
-    THROW(ERR, "Can't destroy a StackString ('%o')", self);
-}
-
-/*****************************************************************/
-
 StringIterator*
 StrIter_new(String *string, size_t byte_offset) {
     StringIterator *self = (StringIterator*)Class_Make_Obj(STRINGITERATOR);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/String.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/String.cfh b/runtime/core/Clownfish/String.cfh
index 6ebccfe..64e7d22 100644
--- a/runtime/core/Clownfish/String.cfh
+++ b/runtime/core/Clownfish/String.cfh
@@ -77,6 +77,9 @@ class Clownfish::String nickname Str
     inert incremented String*
     new_wrap_trusted_utf8(const char *utf8, size_t size);
 
+    inert incremented String*
+    new_stack_string(void *allocation, const char *utf8, size_t size);
+
     /** Initialize the String which wraps an external buffer containing
      * UTF-8.  Do not check validity of supplied UTF-8.
      */
@@ -272,18 +275,6 @@ class Clownfish::String nickname Str
     Tail(String *self);
 }
 
-class Clownfish::StackString nickname SStr
-    inherits Clownfish::String {
-
-    inert incremented StackString*
-    wrap_utf8(void *allocation, const char *utf8, size_t size);
-
-    /** Throws an error.
-     */
-    public void
-    Destroy(StackString *self);
-}
-
 class Clownfish::StringIterator nickname StrIter
     inherits Clownfish::Obj {
 
@@ -393,10 +384,10 @@ class Clownfish::StringIterator nickname StrIter
 __C__
 
 #define CFISH_SSTR_BLANK() \
-   cfish_SStr_wrap_utf8(CFISH_ALLOCA_OBJ(CFISH_STACKSTRING), "", 0)
+    cfish_Str_new_stack_string(CFISH_ALLOCA_OBJ(CFISH_STRING), "", 0)
 
 #define CFISH_SSTR_WRAP_UTF8(ptr, size) \
-    cfish_SStr_wrap_utf8(CFISH_ALLOCA_OBJ(CFISH_STACKSTRING), ptr, size)
+    cfish_Str_new_stack_string(CFISH_ALLOCA_OBJ(CFISH_STRING), ptr, size)
 
 #define CFISH_STRITER_DONE  -1
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/Test/TestHash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestHash.c b/runtime/core/Clownfish/Test/TestHash.c
index 5c47c12..0fecb00 100644
--- a/runtime/core/Clownfish/Test/TestHash.c
+++ b/runtime/core/Clownfish/Test/TestHash.c
@@ -40,7 +40,7 @@ static void
 test_Equals(TestBatchRunner *runner) {
     Hash *hash  = Hash_new(0);
     Hash *other = Hash_new(0);
-    StackString *stuff = SSTR_WRAP_UTF8("stuff", 5);
+    String *stuff = SSTR_WRAP_UTF8("stuff", 5);
 
     TEST_TRUE(runner, Hash_Equals(hash, (Obj*)other),
               "Empty hashes are equal");
@@ -68,9 +68,9 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
     const uint32_t starting_cap = Hash_Get_Capacity(hash);
     Vector        *expected     = Vec_new(100);
     Vector        *got          = Vec_new(100);
-    StackString *twenty       = SSTR_WRAP_UTF8("20", 2);
-    StackString *forty        = SSTR_WRAP_UTF8("40", 2);
-    StackString *foo          = SSTR_WRAP_UTF8("foo", 3);
+    String        *twenty       = SSTR_WRAP_UTF8("20", 2);
+    String        *forty        = SSTR_WRAP_UTF8("40", 2);
+    String        *foo          = SSTR_WRAP_UTF8("foo", 3);
 
     for (int32_t i = 0; i < 100; i++) {
         String *str = Str_newf("%i32", i);
@@ -94,32 +94,32 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
     TEST_INT_EQ(runner, Hash_Get_Size(hash), 100,
                 "size incremented properly by Hash_Store");
 
-    TEST_TRUE(runner, Hash_Fetch(hash, (String*)foo) == NULL,
+    TEST_TRUE(runner, Hash_Fetch(hash, foo) == NULL,
               "Fetch against non-existent key returns NULL");
 
     Obj *stored_foo = INCREF(foo);
-    Hash_Store(hash, (String*)forty, stored_foo);
-    TEST_TRUE(runner, SStr_Equals(foo, Hash_Fetch(hash, (String*)forty)),
+    Hash_Store(hash, forty, stored_foo);
+    TEST_TRUE(runner, Str_Equals(foo, Hash_Fetch(hash, forty)),
               "Hash_Store replaces existing value");
     TEST_FALSE(runner, Hash_Equals(hash, (Obj*)dupe),
                "replacement value spoils equals");
     TEST_INT_EQ(runner, Hash_Get_Size(hash), 100,
                 "size unaffected after value replaced");
 
-    TEST_TRUE(runner, Hash_Delete(hash, (String*)forty) == stored_foo,
+    TEST_TRUE(runner, Hash_Delete(hash, forty) == stored_foo,
               "Delete returns value");
     DECREF(stored_foo);
     TEST_INT_EQ(runner, Hash_Get_Size(hash), 99,
                 "size decremented by successful Delete");
-    TEST_TRUE(runner, Hash_Delete(hash, (String*)forty) == NULL,
+    TEST_TRUE(runner, Hash_Delete(hash, forty) == NULL,
               "Delete returns NULL when key not found");
     TEST_INT_EQ(runner, Hash_Get_Size(hash), 99,
                 "size not decremented by unsuccessful Delete");
-    DECREF(Hash_Delete(dupe, (String*)forty));
+    DECREF(Hash_Delete(dupe, forty));
     TEST_TRUE(runner, Vec_Equals(got, (Obj*)expected), "Equals after Delete");
 
     Hash_Clear(hash);
-    TEST_TRUE(runner, Hash_Fetch(hash, (String*)twenty) == NULL, "Clear");
+    TEST_TRUE(runner, Hash_Fetch(hash, twenty) == NULL, "Clear");
     TEST_TRUE(runner, Hash_Get_Size(hash) == 0, "size is 0 after Clear");
 
     DECREF(hash);
@@ -153,11 +153,11 @@ test_Keys_Values(TestBatchRunner *runner) {
     Vec_Clear(values);
 
     {
-        StackString *forty = SSTR_WRAP_UTF8("40", 2);
-        StackString *nope  = SSTR_WRAP_UTF8("nope", 4);
-        String *key = Hash_Find_Key(hash, (String*)forty, SStr_Hash_Sum(forty));
+        String *forty = SSTR_WRAP_UTF8("40", 2);
+        String *nope  = SSTR_WRAP_UTF8("nope", 4);
+        String *key = Hash_Find_Key(hash, forty, Str_Hash_Sum(forty));
         TEST_TRUE(runner, Str_Equals(key, (Obj*)forty), "Find_Key");
-        key = Hash_Find_Key(hash, (String*)nope, SStr_Hash_Sum(nope)),
+        key = Hash_Find_Key(hash, nope, Str_Hash_Sum(nope)),
         TEST_TRUE(runner, key == NULL,
                   "Find_Key returns NULL for non-existent key");
     }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/Test/TestObj.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestObj.c b/runtime/core/Clownfish/Test/TestObj.c
index a930249..4924288 100644
--- a/runtime/core/Clownfish/Test/TestObj.c
+++ b/runtime/core/Clownfish/Test/TestObj.c
@@ -36,11 +36,11 @@ TestObj_new() {
 
 static Obj*
 S_new_testobj() {
-    StackString *class_name = SSTR_WRAP_UTF8("TestObj", 7);
+    String *class_name = SSTR_WRAP_UTF8("TestObj", 7);
     Obj *obj;
-    Class *klass = Class_fetch_class((String*)class_name);
+    Class *klass = Class_fetch_class(class_name);
     if (!klass) {
-        klass = Class_singleton((String*)class_name, OBJ);
+        klass = Class_singleton(class_name, OBJ);
     }
     obj = Class_Make_Obj(klass);
     return Obj_init(obj);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/core/Clownfish/Test/TestVector.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestVector.c b/runtime/core/Clownfish/Test/TestVector.c
index 7697f29..de21ee2 100644
--- a/runtime/core/Clownfish/Test/TestVector.c
+++ b/runtime/core/Clownfish/Test/TestVector.c
@@ -58,7 +58,7 @@ static void
 test_Equals(TestBatchRunner *runner) {
     Vector *array = Vec_new(0);
     Vector *other = Vec_new(0);
-    StackString *stuff = SSTR_WRAP_UTF8("stuff", 5);
+    String *stuff = SSTR_WRAP_UTF8("stuff", 5);
 
     TEST_TRUE(runner, Vec_Equals(array, (Obj*)array),
               "Array equal to self");

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/go/ext/clownfish.c
----------------------------------------------------------------------
diff --git a/runtime/go/ext/clownfish.c b/runtime/go/ext/clownfish.c
index e350689..e5d54e0 100644
--- a/runtime/go/ext/clownfish.c
+++ b/runtime/go/ext/clownfish.c
@@ -53,7 +53,7 @@ SI_immortal(cfish_Class *klass) {
 
 static CFISH_INLINE bool
 SI_is_string_type(cfish_Class *klass) {
-    if (klass == CFISH_STRING || klass == CFISH_STACKSTRING) {
+    if (klass == CFISH_STRING) {
         return true;
     }
     return false;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/perl/buildlib/Clownfish/Build/Binding.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/buildlib/Clownfish/Build/Binding.pm b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
index 8783afb..fa2f668 100644
--- a/runtime/perl/buildlib/Clownfish/Build/Binding.pm
+++ b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
@@ -590,9 +590,8 @@ CODE:
 {
     STRLEN size;
     char *ptr = SvPVutf8(class_name_sv, size);
-    cfish_StackString *class_name = CFISH_SSTR_WRAP_UTF8(ptr, size);
-    cfish_Class *klass
-        = cfish_Class_fetch_class((cfish_String*)class_name);
+    cfish_String *class_name = CFISH_SSTR_WRAP_UTF8(ptr, size);
+    cfish_Class *klass = cfish_Class_fetch_class(class_name);
     CFISH_UNUSED_VAR(unused_sv);
     RETVAL = klass ? (SV*)CFISH_Class_To_Host(klass) : &PL_sv_undef;
 }
@@ -609,7 +608,7 @@ CODE:
     bool args_ok
         = XSBind_allot_params(aTHX_ &(ST(0)), 1, items,
                               ALLOT_OBJ(&class_name, "class_name", 10, true,
-                                        CFISH_STRING, CFISH_ALLOCA_OBJ(CFISH_STACKSTRING)),
+                                        CFISH_STRING, CFISH_ALLOCA_OBJ(CFISH_STRING)),
                               ALLOT_OBJ(&parent, "parent", 6, false,
                                         CFISH_CLASS, NULL),
                               NULL);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/perl/lib/Clownfish.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish.pm b/runtime/perl/lib/Clownfish.pm
index 78bda7f..8ac8530 100644
--- a/runtime/perl/lib/Clownfish.pm
+++ b/runtime/perl/lib/Clownfish.pm
@@ -149,16 +149,6 @@ sub error {$Clownfish::Err::error}
 }
 
 {
-    package Clownfish::StackString;
-    our $VERSION = '0.004000';
-    $VERSION = eval $VERSION;
-    use Carp;
-    sub new { confess "StackString objects can only be created from C." }
-    no warnings 'redefine';
-    sub DESTROY { }
-}
-
-{
     package Clownfish::Err;
     our $VERSION = '0.004000';
     $VERSION = eval $VERSION;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index f96cecd..ef7069a 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -70,8 +70,8 @@ XSBind_new_blank_obj(pTHX_ SV *either_sv) {
         // Use the supplied class name string to find a Class.
         STRLEN len;
         char *ptr = SvPVutf8(either_sv, len);
-        cfish_StackString *class_name = CFISH_SSTR_WRAP_UTF8(ptr, len);
-        klass = cfish_Class_singleton((cfish_String*)class_name, NULL);
+        cfish_String *class_name = CFISH_SSTR_WRAP_UTF8(ptr, len);
+        klass = cfish_Class_singleton(class_name, NULL);
     }
 
     // Use the Class to allocate a new blank object of the right size.
@@ -103,15 +103,15 @@ XSBind_maybe_sv_to_cfish_obj(pTHX_ SV *sv, cfish_Class *klass,
             retval = INT2PTR(cfish_Obj*, tmp);
         }
         else if (allocation &&
-                 (klass == CFISH_STACKSTRING
-                  || klass == CFISH_STRING
+                 (klass == CFISH_STRING
                   || klass == CFISH_OBJ)
                 ) {
             // Wrap the string from an ordinary Perl scalar inside a
-            // StackString.
+            // stack String.
             STRLEN size;
             char *ptr = SvPVutf8(sv, size);
-            retval = (cfish_Obj*)cfish_SStr_wrap_utf8(allocation, ptr, size);
+            retval = (cfish_Obj*)cfish_Str_new_stack_string(
+                    allocation, ptr, size);
         }
         else if (SvROK(sv)) {
             // Attempt to convert Perl hashes and arrays into their Clownfish
@@ -616,7 +616,7 @@ SI_immortal(cfish_Class *klass) {
 
 static CFISH_INLINE bool
 SI_is_string_type(cfish_Class *klass) {
-    if (klass == CFISH_STRING || klass == CFISH_STACKSTRING) {
+    if (klass == CFISH_STRING) {
         return true;
     }
     return false;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/50fed28d/runtime/perl/xs/XSBind.h
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.h b/runtime/perl/xs/XSBind.h
index bba6ae4..93e0c03 100644
--- a/runtime/perl/xs/XSBind.h
+++ b/runtime/perl/xs/XSBind.h
@@ -62,8 +62,8 @@ cfish_XSBind_sv_defined(pTHX_ SV *sv) {
 
 /** If the SV contains a Clownfish object which passes an "isa" test against the
  * passed-in Class, return a pointer to it.  If not, but
- * `allocation` is non-NULL and a StackString would satisfy the
- * "isa" test, stringify the SV, create a StackString using
+ * `allocation` is non-NULL and a String would satisfy the
+ * "isa" test, stringify the SV, create a stack String using
  * `allocation`, assign the SV's string to it, and return that
  * instead.  If all else fails, throw an exception.
  */
@@ -162,8 +162,8 @@ cfish_XSBind_enable_overload(pTHX_ void *pobj);
  * a NULL-terminated series of ALLOT_ macros.
  *
  *     cfish_XSBind_allot_params(stack, start, num_stack_elems,
- *          ALLOT_OBJ(&field, "field", 5, CFISH_STRING, true, CFISH_ALLOCA_OBJ(CFISH_STACKSTRING),
- *          ALLOT_OBJ(&term, "term", 4, CFISH_STRING, true, CFISH_ALLOCA_OBJ(CFISH_STACKSTRING),
+ *          ALLOT_OBJ(&field, "field", 5, CFISH_STRING, true, CFISH_ALLOCA_OBJ(CFISH_STRING),
+ *          ALLOT_OBJ(&term, "term", 4, CFISH_STRING, true, CFISH_ALLOCA_OBJ(CFISH_STRING),
  *          NULL);
  *
  * The following ALLOT_ macros are available for primitive types:
@@ -201,7 +201,7 @@ cfish_XSBind_enable_overload(pTHX_ void *pobj);
  *
  * The "klass" argument must be the Class corresponding to the class of the
  * desired object.  The "allocation" argument must be a blob of memory
- * allocated on the stack sufficient to hold a StackString.  (Use
+ * allocated on the stack sufficient to hold a String.  (Use
  * CFISH_ALLOCA_OBJ to allocate the object.)
  *
  * To extract a Perl scalar, use the following ALLOT_ macro: