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 03:37:42 UTC

svn commit: r814959 - in /lucene/lucy/trunk: core/Lucy/Object/Host.bp perl/xs/Lucy/Object/Host.c

Author: marvin
Date: Tue Sep 15 01:37:42 2009
New Revision: 814959

URL: http://svn.apache.org/viewvc?rev=814959&view=rev
Log:
Commit LUCY-48, adding Lucy::Object::Host.

Added:
    lucene/lucy/trunk/core/Lucy/Object/Host.bp   (with props)
    lucene/lucy/trunk/perl/xs/Lucy/Object/Host.c   (with props)

Added: lucene/lucy/trunk/core/Lucy/Object/Host.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Host.bp?rev=814959&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Host.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Object/Host.bp Tue Sep 15 01:37:42 2009
@@ -0,0 +1,104 @@
+parcel Lucy;
+
+__C__
+#define LUCY_HOST_ARGTYPE_I32    (chy_i32_t)0x00000001
+#define LUCY_HOST_ARGTYPE_I64    (chy_i32_t)0x00000002
+#define LUCY_HOST_ARGTYPE_F32    (chy_i32_t)0x00000003
+#define LUCY_HOST_ARGTYPE_F64    (chy_i32_t)0x00000004
+#define LUCY_HOST_ARGTYPE_STR    (chy_i32_t)0x00000006
+#define LUCY_HOST_ARGTYPE_OBJ    (chy_i32_t)0x00000007
+#define LUCY_HOST_ARGTYPE_MASK              0x00000007
+
+#define LUCY_ARG_I32(_label, _value) \
+    LUCY_HOST_ARGTYPE_I32, (_label), ((chy_i32_t)_value)
+#define LUCY_ARG_I64(_label, _value) \
+    LUCY_HOST_ARGTYPE_I64, (_label), ((chy_i64_t)_value)
+#define LUCY_ARG_F32(_label, _value) \
+    LUCY_HOST_ARGTYPE_F32, (_label), ((double)_value)
+#define LUCY_ARG_F64(_label, _value) \
+    LUCY_HOST_ARGTYPE_F64, (_label), ((double)_value)
+#define LUCY_ARG_STR(_label, _value) \
+    LUCY_HOST_ARGTYPE_STR, (_label), ((lucy_CharBuf*)_value)
+#define LUCY_ARG_OBJ(_label, _value) \
+    LUCY_HOST_ARGTYPE_OBJ, (_label), ((lucy_Obj*)_value)
+
+#ifdef LUCY_USE_SHORT_NAMES
+  #define ARG_I32                 LUCY_ARG_I32
+  #define ARG_I64                 LUCY_ARG_I64
+  #define ARG_F32                 LUCY_ARG_F32
+  #define ARG_F64                 LUCY_ARG_F64
+  #define ARG_STR                 LUCY_ARG_STR
+  #define ARG_OBJ                 LUCY_ARG_OBJ
+#endif
+
+__END_C__
+
+/** Callbacks to the host environment.
+ * 
+ * All the callback functions are variadic, and all are designed to take a
+ * series of arguments using the ARG_XXX macros.
+ * 
+ *   i32_t area = (i32_t)Host_callback_i64(self, "calc_area", 2, 
+ *        ARG_I32("length", len),  ARG_I32("width", width) );
+ * 
+ * The first argument is void* to avoid the need for tiresome casting to Obj*,
+ * but must always be a Lucy object.
+ * 
+ * If the invoker is a VTable, it will be used to make a class
+ * callback rather than an object callback.
+ */
+inert class Lucy::Object::Host {
+ 
+    /** Invoke an object method in a void context.
+     */
+    inert void
+    callback(void *self, char *method, u32_t num_args, ...);
+
+    /** Invoke an object method, expecting an integer.
+     */
+    inert i64_t
+    callback_i64(void *self, char *method, u32_t num_args, ...);
+
+    /** Invoke an object method, expecting a 64-bit floating point return
+     * value.
+     */
+    inert double 
+    callback_f64(void *self, char *method, u32_t num_args, ...);
+
+    /** Invoke an object method, expecting a Obj-derived object back, or
+     * possibly NULL.  In order to ensure that the host environment doesn't
+     * reclaim the return value, it's refcount is increased by one, which the
+     * caller will have to deal with.
+     */
+    inert incremented Obj*
+    callback_obj(void *self, char *method, u32_t num_args, ...);
+
+    /** Invoke an object method, expecting a host string of some kind back,
+     * which will be converted into a newly allocated CharBuf.  May return
+     * NULL.
+     */
+    inert incremented CharBuf*
+    callback_str(void *self, char *method, u32_t num_args, ...);
+
+    /** Invoke an object method, expecting a host data structure back.  It's
+     * up to the caller to know how to process it.
+     */
+    inert void*
+    callback_host(void *self, char *method, u32_t num_args, ...);
+}
+
+/* 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/Host.bp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/perl/xs/Lucy/Object/Host.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/xs/Lucy/Object/Host.c?rev=814959&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/xs/Lucy/Object/Host.c (added)
+++ lucene/lucy/trunk/perl/xs/Lucy/Object/Host.c Tue Sep 15 01:37:42 2009
@@ -0,0 +1,253 @@
+#include "XSBind.h"
+
+#include "Lucy/Object/VTable.h"
+
+#include "Lucy/Object/Obj.h"
+#include "Lucy/Object/Host.h"
+#include "Lucy/Object/CharBuf.h"
+#include "Lucy/Object/Err.h"
+#include "Lucy/Util/Memory.h"
+
+static SV*
+S_do_callback_sv(void *vobj, char *method, chy_u32_t num_args, va_list args);
+
+/* Convert all arguments to Perl and place them on the Perl stack. 
+ */
+static CHY_INLINE void
+SI_push_args(void *vobj, va_list args, chy_u32_t num_args)
+{
+    lucy_Obj *obj = (lucy_Obj*)vobj;
+    SV *invoker;
+    chy_u32_t i;
+    dSP;
+    
+    if (Lucy_Obj_Is_A(obj, LUCY_VTABLE)) {
+        lucy_VTable *vtable = (lucy_VTable*)obj;
+        /* TODO: Creating a new class name SV every time is wasteful. */
+        invoker = XSBind_cb_to_sv(Lucy_VTable_Get_Name(vtable));
+    }
+    else {
+        invoker = (SV*)Lucy_Obj_To_Host(obj);
+    }
+
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs( sv_2mortal(invoker) );
+
+    for (i = 0; i < num_args; i++) {
+        chy_u32_t arg_type = va_arg(args, chy_u32_t);
+        char *label = va_arg(args, char*);
+        if (num_args > 1) {
+            XPUSHs( sv_2mortal( newSVpvn(label, strlen(label)) ) );
+        }
+        switch (arg_type & LUCY_HOST_ARGTYPE_MASK) {
+        case LUCY_HOST_ARGTYPE_I32: {
+                chy_i32_t value = va_arg(args, chy_i32_t);
+                XPUSHs( sv_2mortal( newSViv(value) ) );
+            }
+            break;
+        case LUCY_HOST_ARGTYPE_I64: {
+                chy_i32_t value = va_arg(args, chy_i64_t);
+                if (sizeof(IV) == 8) {
+                    XPUSHs( sv_2mortal( newSViv(value) ) );
+                }
+                else {
+                    /* lossy */
+                    XPUSHs( sv_2mortal( newSVnv((double)value) ) );
+                }
+            }
+            break;
+        case LUCY_HOST_ARGTYPE_F32:
+        case LUCY_HOST_ARGTYPE_F64: {
+                /* Floats are promoted to doubles by variadic calling. */
+                double value = va_arg(args, double);
+                XPUSHs( sv_2mortal( newSVnv(value) ) );
+            }
+            break;
+        case LUCY_HOST_ARGTYPE_STR: {
+                lucy_CharBuf *string = va_arg(args, lucy_CharBuf*);
+                XPUSHs( sv_2mortal( XSBind_cb_to_sv(string) ) );
+            }
+            break;
+        case LUCY_HOST_ARGTYPE_OBJ: {
+                lucy_Obj* anObj = va_arg(args, lucy_Obj*);
+                SV *arg_sv = anObj == NULL
+                    ? newSV(0)
+                    : XSBind_lucy_to_perl(anObj);
+                XPUSHs( sv_2mortal(arg_sv) );
+            }
+            break;
+        default:
+            LUCY_THROW(LUCY_ERR, "Unrecognized arg type: %u32", arg_type);
+        }
+    }
+
+    PUTBACK;
+}
+
+void
+lucy_Host_callback(void *vobj, char *method, chy_u32_t num_args, ...) 
+{
+    va_list args;
+    
+    va_start(args, num_args);
+    SI_push_args(vobj, args, num_args);
+    va_end(args);
+    
+    {
+        dSP;
+        int count = call_method(method, G_VOID|G_DISCARD);
+        if (count != 0) {
+            LUCY_THROW(LUCY_ERR, "callback '%s' returned too many values: %i32", 
+                method, (chy_i32_t)count);
+        }
+        PUTBACK;
+        FREETMPS;
+        LEAVE;
+    }
+}
+
+chy_i64_t
+lucy_Host_callback_i64(void *vobj, char *method, chy_u32_t num_args, ...) 
+{
+    va_list args;
+    SV *return_sv;
+    chy_i64_t retval;
+
+    va_start(args, num_args);
+    return_sv = S_do_callback_sv(vobj, method, num_args, args);
+    va_end(args);
+    if (sizeof(IV) == 8) {
+        retval = (chy_i64_t)SvIV(return_sv);
+    }
+    else {
+        if (SvIOK(return_sv)) {
+            /* It's already no more than 32 bits, so don't convert. */
+            retval = SvIV(return_sv);
+        }
+        else {
+            /* Maybe lossy. */
+            double temp = SvNV(return_sv);
+            retval = (chy_i64_t)temp;
+        }
+    }
+
+    FREETMPS;
+    LEAVE;
+
+    return retval;
+}
+
+double
+lucy_Host_callback_f64(void *vobj, char *method, chy_u32_t num_args, ...) 
+{
+    va_list args;
+    SV *return_sv;
+    double retval;
+
+    va_start(args, num_args);
+    return_sv = S_do_callback_sv(vobj, method, num_args, args);
+    va_end(args);
+    retval = SvNV(return_sv);
+
+    FREETMPS;
+    LEAVE;
+
+    return retval;
+}
+
+lucy_Obj*
+lucy_Host_callback_obj(void *vobj, char *method, 
+                         chy_u32_t num_args, ...) 
+{
+    va_list args;
+    SV *temp_retval;
+    lucy_Obj *retval = NULL;
+
+    va_start(args, num_args);
+    temp_retval = S_do_callback_sv(vobj, method, num_args, args);
+    va_end(args);
+
+    retval = XSBind_perl_to_lucy(temp_retval);
+
+    FREETMPS;
+    LEAVE;
+
+    return retval;
+}
+
+lucy_CharBuf*
+lucy_Host_callback_str(void *vobj, char *method, chy_u32_t num_args, ...)
+{
+    va_list args;
+    SV *temp_retval;
+    lucy_CharBuf *retval = NULL;
+
+    va_start(args, num_args);
+    temp_retval = S_do_callback_sv(vobj, method, num_args, args);
+    va_end(args);
+
+    /* Make a stringified copy. */
+    if (temp_retval && XSBind_sv_defined(temp_retval)) {
+        STRLEN len;
+        char *ptr = SvPVutf8(temp_retval, len);
+        retval = lucy_CB_new_from_trusted_utf8(ptr, len);
+    }
+
+    FREETMPS;
+    LEAVE;
+
+    return retval;
+}
+
+void*
+lucy_Host_callback_host(void *vobj, char *method, chy_u32_t num_args, ...)
+{
+    va_list args;
+    SV *retval;
+
+    va_start(args, num_args);
+    retval = S_do_callback_sv(vobj, method, num_args, args);
+    va_end(args);
+    SvREFCNT_inc(retval);
+
+    FREETMPS;
+    LEAVE;
+
+    return retval;
+}
+
+static SV*
+S_do_callback_sv(void *vobj, char *method, chy_u32_t num_args, va_list args) 
+{
+    SV *return_val;
+    SI_push_args(vobj, args, num_args);
+    {
+        int num_returned = call_method(method, G_SCALAR);
+        dSP;
+        if (num_returned != 1) {
+            LUCY_THROW(LUCY_ERR, "Bad number of return vals from %s: %i32", method,
+                (chy_i32_t)num_returned);
+        }
+        return_val = POPs;
+        PUTBACK;
+    }
+    return return_val;
+}
+
+/* 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/Host.c
------------------------------------------------------------------------------
    svn:eol-style = native