You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2009/09/15 02:55:31 UTC
svn commit: r814946 - in /lucene/lucy/trunk: core/Lucy/Object/
core/Lucy/Test/Object/ perl/lib/Lucy/Object/ perl/t/core/ perl/xs/Lucy/
perl/xs/Lucy/Object/
Author: marvin
Date: Tue Sep 15 00:55:31 2009
New Revision: 814946
URL: http://svn.apache.org/viewvc?rev=814946&view=rev
Log:
Commit LUCY-41, adding Lucy::Object::Obj -- the class from which all
instantiable Lucy classes descend.
Added:
lucene/lucy/trunk/core/Lucy/Object/
lucene/lucy/trunk/core/Lucy/Object/Obj.bp (with props)
lucene/lucy/trunk/core/Lucy/Object/Obj.c (with props)
lucene/lucy/trunk/core/Lucy/Test/Object/
lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.bp (with props)
lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.c (with props)
lucene/lucy/trunk/perl/lib/Lucy/Object/
lucene/lucy/trunk/perl/lib/Lucy/Object/Obj.pm (with props)
lucene/lucy/trunk/perl/t/core/019-obj.t (with props)
lucene/lucy/trunk/perl/xs/Lucy/
lucene/lucy/trunk/perl/xs/Lucy/Object/
lucene/lucy/trunk/perl/xs/Lucy/Object/Obj.c (with props)
Added: lucene/lucy/trunk/core/Lucy/Object/Obj.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Obj.bp?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Obj.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Object/Obj.bp Tue Sep 15 00:55:31 2009
@@ -0,0 +1,209 @@
+parcel Lucy;
+
+/** Base class for all Lucy objects.
+ */
+
+class Lucy::Object::Obj {
+
+ VTable *vtable;
+ lucy_ref_t ref;
+
+ /** Abstract initializer.
+ */
+ public inert Obj*
+ init(Obj* self);
+
+ /** Zero argument factory constructor.
+ */
+ public abstract incremented Obj*
+ Make(Obj *self);
+
+ /** Return an object's refcount.
+ */
+ u32_t
+ Get_RefCount(Obj *self);
+
+ /** Increment an object's refcount.
+ *
+ * @return The object, allowing an assignment idiom.
+ */
+ incremented Obj*
+ Inc_RefCount(Obj *self);
+
+ /** NULL-safe invocation of Inc_RefCount().
+ *
+ * @return NULL if <code>self</code> is NULL, otherwise the return value
+ * of Inc_RefCount().
+ */
+ inert inline incremented Obj*
+ incref(Obj *self);
+
+ /** Decrement an object's refcount, calling Destroy() if it hits 0.
+ *
+ * @return the modified refcount.
+ */
+ u32_t
+ Dec_RefCount(Obj *self);
+
+ /** NULL-safe invocation of Dec_RefCount().
+ *
+ * @return NULL if <code>self</code> is NULL, otherwise the return value
+ * of Dec_RefCount().
+ */
+ inert inline u32_t
+ decref(Obj *self);
+
+ /** Return a host-language object wrapper for this object.
+ */
+ void*
+ To_Host(Obj *self);
+
+ /** Return a clone of the object.
+ */
+ public abstract incremented Obj*
+ Clone(Obj *self);
+
+ /** Generic destructor. Frees the struct itself but not any complex
+ * member elements.
+ */
+ public void
+ Destroy(Obj *self);
+
+ /** Invoke the Destroy() method found in <code>vtable</code> on
+ * <code>self</code>.
+ *
+ * TODO: Eliminate this function if we can arrive at a proper SUPER syntax.
+ */
+ inert inline void
+ super_destroy(Obj *self, VTable *vtable);
+
+ /** Indicate whether two objects are the same. By default, compares the
+ * memory address.
+ *
+ * @param other Another Obj.
+ */
+ public bool_t
+ Equals(Obj *self, Obj *other);
+
+ /** Indicate whether one object is less than, equal to, or greater than
+ * another.
+ *
+ * @param other Another Obj.
+ * @return 0 if the objects are equal, a negative number if
+ * <code>self</code> is less than <code>other</code>, and a positive
+ * number if <code>self</code> is greater than <code>other</code>.
+ */
+ public abstract i32_t
+ Compare_To(Obj *self, Obj *other);
+
+ /** Return a hash code for the object -- by default, the memory address.
+ */
+ public i32_t
+ Hash_Code(Obj *self);
+
+ /** Return the object's VTable.
+ */
+ public VTable*
+ Get_VTable(Obj *self);
+
+ /** Return the name of the class that the object belongs to.
+ */
+ public CharBuf*
+ Get_Class_Name(Obj *self);
+
+ /** Indicate whether the object is a descendent of <code>ancestor</code>.
+ */
+ public bool_t
+ Is_A(Obj *self, VTable *ancestor);
+
+ /** Generic stringification: "ClassName@hex_mem_address".
+ */
+ public incremented CharBuf*
+ To_String(Obj *self);
+
+ /** Convert the object to a 64-bit integer.
+ */
+ public abstract i64_t
+ To_I64(Obj *self);
+
+ /** Convert the object to a double precision floating point number.
+ */
+ public abstract double
+ To_F64(Obj *self);
+
+ /** Return a representation of the object using only scalars, hashes, and
+ * arrays. Some implementations support JSON serialization via Dump() and
+ * its companion method, Load(); for others, Dump() is only a debugging
+ * aid. The default simply calls To_String().
+ */
+ public incremented Obj*
+ Dump(Obj *self);
+
+ /** Create an object from the output of a call to Dump(). Implementations
+ * should not reference the caller.
+ *
+ * @param dump The output of Dump().
+ */
+ public abstract incremented Obj*
+ Load(Obj *self, Obj *dump);
+
+ /** Update the internal state of the object to mimic that of
+ * <code>other</code>.
+ */
+ public abstract void
+ Mimic(Obj *self, Obj *other);
+}
+
+__C__
+static CHY_INLINE void
+lucy_Obj_super_destroy(lucy_Obj *self, lucy_VTable *vtable)
+{
+ lucy_Obj_destroy_t super_destroy
+ = (lucy_Obj_destroy_t)LUCY_SUPER_METHOD(vtable, Obj, Destroy);
+ super_destroy(self);
+}
+
+#define LUCY_SUPER_DESTROY(_self, _vtable) \
+ lucy_Obj_super_destroy((lucy_Obj*)_self, _vtable)
+
+static CHY_INLINE lucy_Obj*
+lucy_Obj_incref(lucy_Obj *self)
+{
+ if (self != NULL) { return Lucy_Obj_Inc_RefCount(self); }
+ else { return NULL; }
+}
+
+#define LUCY_INCREF(_self) lucy_Obj_incref((lucy_Obj*)_self)
+
+static CHY_INLINE chy_u32_t
+lucy_Obj_decref(lucy_Obj *self)
+{
+ if (self != NULL) { return Lucy_Obj_Dec_RefCount(self); }
+ else { return 0; }
+}
+
+#define LUCY_DECREF(_self) lucy_Obj_decref((lucy_Obj*)_self)
+
+#ifdef LUCY_USE_SHORT_NAMES
+ #define SUPER_DESTROY(_self, _vtable) LUCY_SUPER_DESTROY(_self, _vtable)
+ #define INCREF(_self) LUCY_INCREF(_self)
+ #define DECREF(_self) LUCY_DECREF(_self)
+#endif
+
+__END_C__
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
Propchange: lucene/lucy/trunk/core/Lucy/Object/Obj.bp
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/lucy/trunk/core/Lucy/Object/Obj.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Obj.c?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Obj.c (added)
+++ lucene/lucy/trunk/core/Lucy/Object/Obj.c Tue Sep 15 00:55:31 2009
@@ -0,0 +1,96 @@
+#define C_LUCY_OBJ
+#define C_LUCY_VTABLE
+#define LUCY_USE_SHORT_NAMES
+#define CHY_USE_SHORT_NAMES
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "Lucy/Object/Obj.h"
+#include "Lucy/Object/CharBuf.h"
+#include "Lucy/Object/Err.h"
+#include "Lucy/Object/Hash.h"
+#include "Lucy/Object/VTable.h"
+#include "Lucy/Util/Memory.h"
+
+Obj*
+Obj_init(Obj *self)
+{
+ ABSTRACT_CLASS_CHECK(self, OBJ);
+ return self;
+}
+
+void
+Obj_destroy(Obj *self)
+{
+ Obj_Dec_RefCount(self->vtable);
+ FREEMEM(self);
+}
+
+i32_t
+Obj_hash_code(Obj *self)
+{
+ return (i32_t)self;
+}
+
+bool_t
+Obj_is_a(Obj *self, VTable *ancestor)
+{
+ VTable *vtable = self ? self->vtable : NULL;
+
+ while (vtable != NULL) {
+ if (vtable == ancestor)
+ return true;
+ vtable = vtable->parent;
+ }
+
+ return false;
+}
+
+bool_t
+Obj_equals(Obj *self, Obj *other)
+{
+ return (self == other);
+}
+
+CharBuf*
+Obj_to_string(Obj *self)
+{
+#if (SIZEOF_PTR == 4)
+ return CB_newf("%o@0x%x32", Obj_Get_Class_Name(self), self);
+#elif (SIZEOF_PTR == 8)
+ size_t address = self;
+ u32_t address_hi = address >> 32;
+ u32_t address_lo = address & 0xFFFFFFFF;
+ return CB_newf("%o@0x%x32%x32", Obj_Get_Class_Name(self), address_hi,
+ address_lo);
+#endif
+}
+
+Obj*
+Obj_dump(Obj *self)
+{
+ return (Obj*)Obj_To_String(self);
+}
+
+VTable*
+Obj_get_vtable(Obj *self) { return self->vtable; }
+CharBuf*
+Obj_get_class_name(Obj *self) { return VTable_Get_Name(self->vtable); }
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
Propchange: lucene/lucy/trunk/core/Lucy/Object/Obj.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.bp?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.bp Tue Sep 15 00:55:31 2009
@@ -0,0 +1,22 @@
+parcel Lucy;
+
+inert class Lucy::Test::Object::TestObj {
+ inert void
+ run_tests();
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
Propchange: lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.bp
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.c?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.c Tue Sep 15 00:55:31 2009
@@ -0,0 +1,138 @@
+#define C_LUCY_TESTOBJ
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Test.h"
+#include "Lucy/Test/Object/TestObj.h"
+
+static Obj*
+S_new_testobj()
+{
+ static ZombieCharBuf klass = ZCB_LITERAL("TestObj");
+ Obj *obj;
+ VTable *vtable = VTable_fetch_vtable((CharBuf*)&klass);
+ if (!vtable) {
+ vtable = VTable_singleton((CharBuf*)&klass, OBJ);
+ }
+ obj = VTable_Make_Obj(vtable);
+ return Obj_init(obj);
+}
+
+static void
+test_refcounts(TestBatch *batch)
+{
+ Obj *obj = S_new_testobj();
+
+ ASSERT_INT_EQ(batch, Obj_Get_RefCount(obj), 1,
+ "Correct starting refcount");
+
+ Obj_Inc_RefCount(obj);
+ ASSERT_INT_EQ(batch, Obj_Get_RefCount(obj), 2, "Inc_RefCount" );
+
+ Obj_Dec_RefCount(obj);
+ ASSERT_INT_EQ(batch, Obj_Get_RefCount(obj), 1, "Dec_RefCount" );
+
+ DECREF(obj);
+}
+
+static void
+test_To_String(TestBatch *batch)
+{
+ Obj *testobj = S_new_testobj();
+ CharBuf *string = Obj_To_String(testobj);
+ ZombieCharBuf temp = ZCB_make(string);
+ while(ZCB_Get_Size(&temp)) {
+ if (ZCB_Starts_With_Str(&temp, "TestObj", 7)) { break; }
+ ZCB_Nip_One(&temp);
+ }
+ ASSERT_TRUE(batch, ZCB_Starts_With_Str(&temp, "TestObj", 7), "To_String");
+ DECREF(string);
+ DECREF(testobj);
+}
+
+static void
+test_Dump(TestBatch *batch)
+{
+ Obj *testobj = S_new_testobj();
+ CharBuf *string = Obj_To_String(testobj);
+ Obj *dump = Obj_Dump(testobj);
+ ASSERT_TRUE(batch, Obj_Equals(dump, (Obj*)string),
+ "Default Dump returns To_String");
+ DECREF(dump);
+ DECREF(string);
+ DECREF(testobj);
+}
+
+static void
+test_Equals(TestBatch *batch)
+{
+ Obj *testobj = S_new_testobj();
+ Obj *other = S_new_testobj();
+
+ ASSERT_TRUE(batch, Obj_Equals(testobj, testobj),
+ "Equals is true for the same object");
+ ASSERT_FALSE(batch, Obj_Equals(testobj, other),
+ "Distinct objects are not equal");
+
+ DECREF(testobj);
+ DECREF(other);
+}
+
+static void
+test_Hash_Code(TestBatch *batch)
+{
+ Obj *testobj = S_new_testobj();
+ i32_t address = (i32_t)testobj;
+ ASSERT_TRUE(batch, (Obj_Hash_Code(testobj) == address),
+ "Hash_Code uses memory address");
+ DECREF(testobj);
+}
+
+static void
+test_Is_A(TestBatch *batch)
+{
+ CharBuf *charbuf = CB_new(0);
+ VTable *bb_vtable = CB_Get_VTable(charbuf);
+ CharBuf *klass = Obj_Get_Class_Name(charbuf);
+
+ ASSERT_TRUE(batch, Obj_Is_A(charbuf, CHARBUF), "CharBuf Is_A CharBuf.");
+ ASSERT_TRUE(batch, Obj_Is_A(charbuf, OBJ), "CharBuf Is_A Obj.");
+ ASSERT_TRUE(batch, bb_vtable == CHARBUF, "Get_VTable");
+ ASSERT_TRUE(batch, CB_Equals(VTable_Get_Name(CHARBUF), (Obj*)klass),
+ "Get_Class_Name");
+
+ DECREF(charbuf);
+}
+
+
+void
+TestObj_run_tests()
+{
+ TestBatch *batch = Test_new_batch("TestObj", 12, NULL);
+
+ PLAN(batch);
+
+ test_refcounts(batch);
+ test_To_String(batch);
+ test_Dump(batch);
+ test_Equals(batch);
+ test_Hash_Code(batch);
+ test_Is_A(batch);
+
+ batch->destroy(batch);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
Propchange: lucene/lucy/trunk/core/Lucy/Test/Object/TestObj.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/lucy/trunk/perl/lib/Lucy/Object/Obj.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Object/Obj.pm?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Object/Obj.pm (added)
+++ lucene/lucy/trunk/perl/lib/Lucy/Object/Obj.pm Tue Sep 15 00:55:31 2009
@@ -0,0 +1,78 @@
+use Lucy;
+
+1;
+
+__END__
+
+__BINDING__
+
+my $xs_code = <<'END_XS_CODE';
+MODULE = Lucy PACKAGE = Lucy::Object::Obj
+
+chy_bool_t
+is_a(self, class_name)
+ lucy_Obj *self;
+ lucy_ZombieCharBuf class_name;
+CODE:
+{
+ lucy_VTable *target = lucy_VTable_fetch_vtable((lucy_CharBuf*)&class_name);
+ RETVAL = Lucy_Obj_Is_A(self, target);
+}
+OUTPUT: RETVAL
+
+void
+DESTROY(self)
+ lucy_Obj *self;
+PPCODE:
+ /*
+ {
+ char *perl_class = HvNAME(SvSTASH(SvRV(ST(0))));
+ warn("Destroying: 0x%x %s", (unsigned)self, perl_class);
+ }
+ */
+ Lucy_Obj_Destroy(self);
+END_XS_CODE
+
+Boilerplater::Binding::Perl::Class->register(
+ parcel => "Lucy",
+ class_name => "Lucy::Object::Obj",
+ xs_code => $xs_code,
+ bind_methods => [
+ qw(
+ Get_RefCount
+ Inc_RefCount
+ Dec_RefCount
+ Get_VTable
+ To_String
+ To_I64
+ To_F64
+ Dump
+ _load|Load
+ Clone
+ Mimic
+ Equals
+ Hash_Code
+ Destroy
+ )
+ ],
+ bind_constructors => ["new"],
+);
+
+__COPYRIGHT__
+
+ /**
+ * Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
Propchange: lucene/lucy/trunk/perl/lib/Lucy/Object/Obj.pm
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/lucy/trunk/perl/t/core/019-obj.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/core/019-obj.t?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/core/019-obj.t (added)
+++ lucene/lucy/trunk/perl/t/core/019-obj.t Tue Sep 15 00:55:31 2009
@@ -0,0 +1,6 @@
+use strict;
+use warnings;
+
+use Lucy::Test;
+Lucy::Test::run_tests("TestObj");
+
Propchange: lucene/lucy/trunk/perl/t/core/019-obj.t
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/lucy/trunk/perl/xs/Lucy/Object/Obj.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/xs/Lucy/Object/Obj.c?rev=814946&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/xs/Lucy/Object/Obj.c (added)
+++ lucene/lucy/trunk/perl/xs/Lucy/Object/Obj.c Tue Sep 15 00:55:31 2009
@@ -0,0 +1,125 @@
+#define C_LUCY_OBJ
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "ppport.h"
+
+#include "Lucy/Object/Obj.h"
+#include "Lucy/Object/CharBuf.h"
+#include "Lucy/Object/Err.h"
+#include "Lucy/Object/VTable.h"
+#include "Lucy/Util/Memory.h"
+
+static void
+S_lazy_init_host_obj(lucy_Obj *self)
+{
+ size_t old_refcount = self->ref.count;
+
+ /* Find the Perl stash entry. */
+ lucy_CharBuf *class_name = Lucy_VTable_Get_Name(self->vtable);
+ HV *stash = gv_stashpvn((char*)Lucy_CB_Get_Ptr8(class_name),
+ Lucy_CB_Get_Size(class_name), TRUE);
+
+ /* In Perl, object SVs are never accessed directly; they are always
+ * wrapped within a reference SV. However, we have no need for the extra
+ * level of indirection, so we create the inner object directly and avoid
+ * the extra allocation. If and when we need to send the object back into
+ * Perl space, we'll create the RV (in To_Host).
+ *
+ * (Note: Some code cribbed from Perl_sv_bless, in sv.c.) */
+ SV *inner_obj = newSV(0);
+ SvOBJECT_on(inner_obj);
+ PL_sv_objcount++;
+ SvUPGRADE(inner_obj, SVt_PVMG);
+ SvSTASH_set(inner_obj, (HV*)SvREFCNT_inc(stash));
+ sv_setiv(inner_obj, PTR2IV(self));
+
+ /* Up till now we've been keeping track of the refcount in
+ * self->ref.count. We're replacing ref.count with ref.host_obj, which
+ * will assume responsibility for maintaining the refcount. ref.host_obj
+ * starts off with a refcount of 1, so we need to transfer any refcounts
+ * in excess of that. */
+ self->ref.host_obj = inner_obj;
+ while(old_refcount > 1) {
+ SvREFCNT_inc_simple_void_NN(inner_obj);
+ old_refcount--;
+ }
+}
+
+chy_u32_t
+lucy_Obj_get_refcount(lucy_Obj *self)
+{
+ return self->ref.count < 4
+ ? self->ref.count
+ : SvREFCNT((SV*)self->ref.host_obj);
+}
+
+lucy_Obj*
+lucy_Obj_inc_refcount(lucy_Obj *self)
+{
+ switch (self->ref.count) {
+ case 0:
+ LUCY_THROW(LUCY_ERR, "Illegal refcount of 0");
+ break; /* useless */
+ case 1:
+ case 2:
+ self->ref.count++;
+ break;
+ case 3:
+ S_lazy_init_host_obj(self);
+ /* fall through */
+ default:
+ SvREFCNT_inc_simple_void_NN((SV*)self->ref.host_obj);
+ }
+ return self;
+}
+
+chy_u32_t
+lucy_Obj_dec_refcount(lucy_Obj *self)
+{
+ chy_u32_t modified_refcount = I32_MAX;
+ switch (self->ref.count) {
+ case 0:
+ LUCY_THROW(LUCY_ERR, "Illegal refcount of 0");
+ break; /* useless */
+ case 1:
+ modified_refcount = 0;
+ Lucy_Obj_Destroy(self);
+ break;
+ case 2:
+ case 3:
+ modified_refcount = --self->ref.count;
+ break;
+ default:
+ modified_refcount = SvREFCNT((SV*)self->ref.host_obj) - 1;
+ /* If the SV's refcount falls to 0, DESTROY will be invoked from
+ * Perl-space.
+ */
+ SvREFCNT_dec((SV*)self->ref.host_obj);
+ }
+ return modified_refcount;
+}
+
+void*
+lucy_Obj_to_host(lucy_Obj *self)
+{
+ if (self->ref.count < 4) { S_lazy_init_host_obj(self); }
+ return newRV_inc((SV*)self->ref.host_obj);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
Propchange: lucene/lucy/trunk/perl/xs/Lucy/Object/Obj.c
------------------------------------------------------------------------------
svn:eol-style = native