couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1166526 - in /couchdb/branches/1.1.x/src/couchdb/priv/couch_js: sm170.c sm180.c sm185.c util.c util.h
Date Thu, 08 Sep 2011 05:05:20 GMT
Author: davisp
Date: Thu Sep  8 05:05:19 2011
New Revision: 1166526

URL: http://svn.apache.org/viewvc?rev=1166526&view=rev
Log:
And the rest of the commit/

SVN != Git. Forgot to check svn status before committing.


Added:
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm170.c
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm180.c
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm185.c
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.c
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.h

Added: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm170.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm170.c?rev=1166526&view=auto
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm170.c (added)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm170.c Thu Sep  8 05:05:19 2011
@@ -0,0 +1,378 @@
+// 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.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <jsapi.h>
+#include "http.h"
+#include "utf8.h"
+#include "util.h"
+
+
+#ifdef JS_THREADSAFE
+#define SETUP_REQUEST(cx) \
+    JS_SetContextThread(cx); \
+    JS_BeginRequest(cx);
+#define FINISH_REQUEST(cx) \
+    JS_EndRequest(cx); \
+    JS_ClearContextThread(cx);
+#else
+#define SETUP_REQUEST(cx)
+#define FINISH_REQUEST(cx)
+#endif
+
+
+static JSBool
+req_ctor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    return http_ctor(cx, obj);
+}
+
+
+static void 
+req_dtor(JSContext* cx, JSObject* obj)
+{
+    http_dtor(cx, obj);
+}
+
+
+static JSBool
+req_open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    JSBool ret = JS_FALSE;
+
+    if(argc == 2) {
+        ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE);
+    } else if(argc == 3) {
+        ret = http_open(cx, obj, argv[0], argv[1], argv[2]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.open");
+    }
+
+    *rval = JSVAL_VOID;
+    return ret;
+}
+
+
+static JSBool
+req_set_hdr(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    JSBool ret = JS_FALSE;
+    if(argc == 2) {
+        ret = http_set_hdr(cx, obj, argv[0], argv[1]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.set_header");
+    }
+
+    *rval = JSVAL_VOID;
+    return ret;
+}
+
+
+static JSBool
+req_send(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    JSBool ret = JS_FALSE;
+    if(argc == 1) {
+        ret = http_send(cx, obj, argv[0]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.send");
+    }
+
+    *rval = JSVAL_VOID;
+    return ret;
+}
+
+
+static JSBool
+req_status(JSContext* cx, JSObject* obj, jsval idval, jsval* rval)
+{
+    int status = http_status(cx, obj);
+    if(status < 0)
+        return JS_FALSE;
+
+    if(INT_FITS_IN_JSVAL(status)) {
+        *rval = INT_TO_JSVAL(status);
+        return JS_TRUE;
+    } else {
+        JS_ReportError(cx, "Invalid HTTP status.");
+        return JS_FALSE;
+    }
+}
+
+
+static JSBool
+evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    JSObject *sandbox;
+    JSContext *subcx;
+    const jschar *src;
+    size_t srclen;
+    JSBool ret = JS_FALSE;
+
+    sandbox = NULL;
+    if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox)) {
+        return JS_FALSE;
+    }
+
+    subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L);
+    if(!subcx) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    SETUP_REQUEST(subcx);
+
+    src = JS_GetStringChars(str);
+    srclen = JS_GetStringLength(str);
+
+    if(!sandbox) {
+        sandbox = JS_NewObject(subcx, NULL, NULL, NULL);
+        if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) {
+            goto done;
+        }
+    }
+
+    if(srclen == 0) {
+        *rval = OBJECT_TO_JSVAL(sandbox);
+    } else {
+        JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval);
+    }
+    
+    ret = JS_TRUE;
+
+done:
+    FINISH_REQUEST(subcx);
+    JS_DestroyContext(subcx);
+    return ret;
+}
+
+
+static JSBool
+gc(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    JS_GC(cx);
+    *rval = JSVAL_VOID;
+    return JS_TRUE;
+}
+
+
+static JSBool
+print(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    couch_print(cx, argc, argv);
+    *rval = JSVAL_VOID;
+    return JS_TRUE;
+}
+
+
+static JSBool
+quit(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    int exit_code = 0;
+    JS_ConvertArguments(cx, argc, argv, "/i", &exit_code);
+    exit(exit_code);
+}
+
+
+static JSBool
+readline(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    JSString* line;
+
+    /* GC Occasionally */
+    JS_MaybeGC(cx);
+
+    line = couch_readline(cx, stdin);
+    if(line == NULL) return JS_FALSE;
+
+    *rval = STRING_TO_JSVAL(line);
+    return JS_TRUE;
+}
+
+
+static JSBool
+seal(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    JSObject *target;
+    JSBool deep = JS_FALSE;
+
+    if(!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
+        return JS_FALSE;
+
+    if(!target) {
+        *rval = JSVAL_VOID;
+        return JS_TRUE;
+    }
+
+    if(JS_SealObject(cx, obj, deep) != JS_TRUE)
+        return JS_FALSE;
+
+    *rval = JSVAL_VOID;
+    return JS_TRUE;
+}
+
+
+JSClass CouchHTTPClass = {
+    "CouchHTTP",
+    JSCLASS_HAS_PRIVATE
+        | JSCLASS_CONSTRUCT_PROTOTYPE
+        | JSCLASS_HAS_RESERVED_SLOTS(2),
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    req_dtor,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+JSPropertySpec CouchHTTPProperties[] = {
+    {"status", 0, JSPROP_READONLY, req_status, NULL},
+    {0, 0, 0, 0, 0}
+};
+
+
+JSFunctionSpec CouchHTTPFunctions[] = {
+    {"_open", req_open, 3, 0, 0},
+    {"_setRequestHeader", req_set_hdr, 2, 0, 0},
+    {"_send", req_send, 1, 0, 0},
+    {0, 0, 0, 0, 0}
+};
+
+
+static JSClass global_class = {
+    "GlobalClass",
+    JSCLASS_GLOBAL_FLAGS,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+static JSFunctionSpec global_functions[] = {
+    {"evalcx", evalcx, 0, 0, 0},
+    {"gc", gc, 0, 0, 0},
+    {"print", print, 0, 0, 0},
+    {"quit", quit, 0, 0, 0},
+    {"readline", readline, 0, 0, 0},
+    {"seal", seal, 0, 0, 0},
+    {0, 0, 0, 0, 0}
+};
+
+
+int
+main(int argc, const char* argv[])
+{
+    JSRuntime* rt = NULL;
+    JSContext* cx = NULL;
+    JSObject* global = NULL;
+    JSObject* klass = NULL;
+    JSScript* script;
+    JSString* scriptsrc;
+    jschar* schars;
+    size_t slen;
+    jsval sroot;
+    jsval result;
+
+    couch_args* args = couch_parse_args(argc, argv);
+    
+    rt = JS_NewRuntime(64L * 1024L * 1024L);
+    if(rt == NULL)
+        return 1;
+
+    cx = JS_NewContext(rt, args->stack_size);
+    if(cx == NULL)
+        return 1;
+
+    JS_SetErrorReporter(cx, couch_error);
+    JS_ToggleOptions(cx, JSOPTION_XML);
+    
+    SETUP_REQUEST(cx);
+
+    global = JS_NewObject(cx, &global_class, NULL, NULL);
+    if(global == NULL)
+        return 1;
+
+    JS_SetGlobalObject(cx, global);
+    
+    if(!JS_InitStandardClasses(cx, global))
+        return 1;
+
+    if(couch_load_funcs(cx, global, global_functions) != JS_TRUE)
+        return 1;
+ 
+    if(args->use_http) {
+        http_check_enabled();
+
+        klass = JS_InitClass(
+            cx, global,
+            NULL,
+            &CouchHTTPClass, req_ctor,
+            0,
+            CouchHTTPProperties, CouchHTTPFunctions,
+            NULL, NULL
+        );
+
+        if(!klass)
+        {
+            fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
+            exit(2);
+        }
+    } 
+
+    // Convert script source to jschars.
+    scriptsrc = dec_string(cx, args->script, strlen(args->script));
+    if(!scriptsrc)
+        return 1;
+
+    schars = JS_GetStringChars(scriptsrc);
+    slen = JS_GetStringLength(scriptsrc);
+    
+    // Root it so GC doesn't collect it.
+    sroot = STRING_TO_JSVAL(scriptsrc); 
+    if(JS_AddRoot(cx, &sroot) != JS_TRUE) {
+        fprintf(stderr, "Internal root error.\n");
+        return 1;
+    }
+
+    // Compile and run
+    script = JS_CompileUCScript(cx, global, schars, slen, args->script_name, 1);
+    if(!script) {
+        fprintf(stderr, "Failed to compile script.\n");
+        return 1;
+    }
+    
+    JS_ExecuteScript(cx, global, script, &result);
+    
+    // Warning message if we don't remove it.
+    JS_RemoveRoot(cx, &sroot);
+
+    FINISH_REQUEST(cx);
+    JS_DestroyContext(cx);
+    JS_DestroyRuntime(rt);
+    JS_ShutDown();
+
+    return 0;
+}

Added: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm180.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm180.c?rev=1166526&view=auto
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm180.c (added)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm180.c Thu Sep  8 05:05:19 2011
@@ -0,0 +1,387 @@
+// 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.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <jsapi.h>
+#include "http.h"
+#include "utf8.h"
+#include "util.h"
+
+
+#define SETUP_REQUEST(cx) \
+    JS_SetContextThread(cx); \
+    JS_BeginRequest(cx);
+#define FINISH_REQUEST(cx) \
+    JS_EndRequest(cx); \
+    JS_ClearContextThread(cx);
+
+
+static JSBool
+req_ctor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+{
+    return http_ctor(cx, obj);
+}
+
+
+static void 
+req_dtor(JSContext* cx, JSObject* obj)
+{
+    http_dtor(cx, obj);
+}
+
+
+static JSBool
+req_open(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+    jsval* argv = JS_ARGV(cx, vp);
+    JSBool ret = JS_FALSE;
+
+    if(argc == 2) {
+        ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE);
+    } else if(argc == 3) {
+        ret = http_open(cx, obj, argv[0], argv[1], argv[2]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.open");
+    }
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+static JSBool
+req_set_hdr(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+    jsval* argv = JS_ARGV(cx, vp);
+    JSBool ret = JS_FALSE;
+
+    if(argc == 2) {
+        ret = http_set_hdr(cx, obj, argv[0], argv[1]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.set_header");
+    }
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+static JSBool
+req_send(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+    jsval* argv = JS_ARGV(cx, vp);
+    JSBool ret = JS_FALSE;
+
+    if(argc == 1) {
+        ret = http_send(cx, obj, argv[0]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.send");
+    }
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+static JSBool
+req_status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
+{
+    int status = http_status(cx, obj);
+    if(status < 0)
+        return JS_FALSE;
+
+    if(INT_FITS_IN_JSVAL(status)) {
+        JS_SET_RVAL(cx, vp, INT_TO_JSVAL(status));
+        return JS_TRUE;
+    } else {
+        JS_ReportError(cx, "Invalid HTTP status.");
+        return JS_FALSE;
+    }
+}
+
+
+static JSBool
+evalcx(JSContext *cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    JSString *str;
+    JSObject *sandbox;
+    JSContext *subcx;
+    const jschar *src;
+    size_t srclen;
+    jsval rval;
+    JSBool ret = JS_FALSE;
+
+    sandbox = NULL;
+    if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox)) {
+        return JS_FALSE;
+    }
+
+    subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L);
+    if(!subcx) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    SETUP_REQUEST(subcx);
+
+    src = JS_GetStringChars(str);
+    srclen = JS_GetStringLength(str);
+
+    if(!sandbox) {
+        sandbox = JS_NewObject(subcx, NULL, NULL, NULL);
+        if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) {
+            goto done;
+        }
+    }
+
+    if(srclen == 0) {
+        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(sandbox));
+    } else {
+        JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, &rval);
+        JS_SET_RVAL(cx, vp, rval);
+    }
+    
+    ret = JS_TRUE;
+
+done:
+    FINISH_REQUEST(subcx);
+    JS_DestroyContext(subcx);
+    return ret;
+}
+
+
+static JSBool
+gc(JSContext* cx, uintN argc, jsval* vp)
+{
+    JS_GC(cx);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return JS_TRUE;
+}
+
+
+static JSBool
+print(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    couch_print(cx, argc, argv);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return JS_TRUE;
+}
+
+
+static JSBool
+quit(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    int exit_code = 0;
+    JS_ConvertArguments(cx, argc, argv, "/i", &exit_code);
+    exit(exit_code);
+}
+
+
+static JSBool
+readline(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSString* line;
+
+    /* GC Occasionally */
+    JS_MaybeGC(cx);
+
+    line = couch_readline(cx, stdin);
+    if(line == NULL) return JS_FALSE;
+
+    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(line));
+    return JS_TRUE;
+}
+
+
+static JSBool
+seal(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    JSObject *target;
+    JSBool deep = JS_FALSE;
+
+    if(!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
+        return JS_FALSE;
+
+    if(!target) {
+        JS_SET_RVAL(cx, vp, JSVAL_VOID);
+        return JS_TRUE;
+    }
+
+    if(JS_SealObject(cx, target, deep) != JS_TRUE)
+        return JS_FALSE;
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return JS_TRUE;
+}
+
+
+JSClass CouchHTTPClass = {
+    "CouchHTTP",
+    JSCLASS_HAS_PRIVATE
+        | JSCLASS_CONSTRUCT_PROTOTYPE
+        | JSCLASS_HAS_RESERVED_SLOTS(2),
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    req_dtor,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+JSPropertySpec CouchHTTPProperties[] = {
+    {"status", 0, JSPROP_READONLY, req_status, NULL},
+    {0, 0, 0, 0, 0}
+};
+
+
+JSFunctionSpec CouchHTTPFunctions[] = {
+    JS_FS("_open", (JSNative) req_open, 3, JSFUN_FAST_NATIVE, 0),
+    JS_FS("_setRequestHeader", (JSNative) req_set_hdr, 2, JSFUN_FAST_NATIVE, 0),
+    JS_FS("_send", (JSNative) req_send, 1, JSFUN_FAST_NATIVE, 0),
+    JS_FS_END
+};
+
+
+static JSClass global_class = {
+    "GlobalClass",
+    JSCLASS_GLOBAL_FLAGS,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+static JSFunctionSpec global_functions[] = {
+    JS_FS("evalcx", (JSNative) evalcx, 0, JSFUN_FAST_NATIVE, 0),
+    JS_FS("gc", (JSNative) gc, 0, JSFUN_FAST_NATIVE, 0),
+    JS_FS("print", (JSNative) print, 0, JSFUN_FAST_NATIVE, 0),
+    JS_FS("quit", (JSNative) quit, 0, JSFUN_FAST_NATIVE, 0),
+    JS_FS("readline", (JSNative) readline, 0, JSFUN_FAST_NATIVE, 0),
+    JS_FS("seal", (JSNative) seal, 0, JSFUN_FAST_NATIVE, 0),
+    JS_FS_END
+};
+
+
+int
+main(int argc, const char* argv[])
+{
+    JSRuntime* rt = NULL;
+    JSContext* cx = NULL;
+    JSObject* global = NULL;
+    JSObject* klass = NULL;
+    JSScript* script;
+    JSString* scriptsrc;
+    jschar* schars;
+    size_t slen;
+    jsval sroot;
+    jsval result;
+
+    couch_args* args = couch_parse_args(argc, argv);
+    
+    rt = JS_NewRuntime(64L * 1024L * 1024L);
+    if(rt == NULL)
+        return 1;
+
+    cx = JS_NewContext(rt, args->stack_size);
+    if(cx == NULL)
+        return 1;
+
+    JS_SetErrorReporter(cx, couch_error);
+    JS_ToggleOptions(cx, JSOPTION_XML);
+    
+    SETUP_REQUEST(cx);
+
+    global = JS_NewObject(cx, &global_class, NULL, NULL);
+    if(global == NULL)
+        return 1;
+
+    JS_SetGlobalObject(cx, global);
+    
+    if(!JS_InitStandardClasses(cx, global))
+        return 1;
+
+    if(couch_load_funcs(cx, global, global_functions) != JS_TRUE)
+        return 1;
+ 
+    if(args->use_http) {
+        http_check_enabled();
+
+        klass = JS_InitClass(
+            cx, global,
+            NULL,
+            &CouchHTTPClass, req_ctor,
+            0,
+            CouchHTTPProperties, CouchHTTPFunctions,
+            NULL, NULL
+        );
+
+        if(!klass)
+        {
+            fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
+            exit(2);
+        }
+    } 
+
+    // Convert script source to jschars.
+    scriptsrc = dec_string(cx, args->script, strlen(args->script));
+    if(!scriptsrc)
+        return 1;
+
+    schars = JS_GetStringChars(scriptsrc);
+    slen = JS_GetStringLength(scriptsrc);
+    
+    // Root it so GC doesn't collect it.
+    sroot = STRING_TO_JSVAL(scriptsrc); 
+    if(JS_AddRoot(cx, &sroot) != JS_TRUE) {
+        fprintf(stderr, "Internal root error.\n");
+        return 1;
+    }
+
+    // Compile and run
+    script = JS_CompileUCScript(cx, global, schars, slen, args->script_name, 1);
+    if(!script) {
+        fprintf(stderr, "Failed to compile script.\n");
+        return 1;
+    }
+    
+    JS_ExecuteScript(cx, global, script, &result);
+
+    // Warning message if we don't remove it.
+    JS_RemoveRoot(cx, &sroot);
+
+    FINISH_REQUEST(cx);
+    JS_DestroyContext(cx);
+    JS_DestroyRuntime(rt);
+    JS_ShutDown();
+
+    return 0;
+}

Added: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm185.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm185.c?rev=1166526&view=auto
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm185.c (added)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/sm185.c Thu Sep  8 05:05:19 2011
@@ -0,0 +1,401 @@
+// 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.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <jsapi.h>
+#include "http.h"
+#include "utf8.h"
+#include "util.h"
+
+
+#define SETUP_REQUEST(cx) \
+    JS_SetContextThread(cx); \
+    JS_BeginRequest(cx);
+#define FINISH_REQUEST(cx) \
+    JS_EndRequest(cx); \
+    JS_ClearContextThread(cx);
+
+
+static JSClass global_class = {
+    "GlobalClass",
+    JSCLASS_GLOBAL_FLAGS,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_StrictPropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+static JSBool
+req_ctor(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSBool ret;
+    JSObject* obj = JS_NewObjectForConstructor(cx, vp);
+    if(!obj) {
+        JS_ReportError(cx, "Failed to create CouchHTTP instance.\n");
+        return JS_FALSE;
+    }
+    ret = http_ctor(cx, obj);
+    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
+    return ret;
+}
+
+
+static void 
+req_dtor(JSContext* cx, JSObject* obj)
+{
+    http_dtor(cx, obj);
+}
+
+
+static JSBool
+req_open(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+    jsval* argv = JS_ARGV(cx, vp);
+    JSBool ret = JS_FALSE;
+
+    if(argc == 2) {
+        ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE);
+    } else if(argc == 3) {
+        ret = http_open(cx, obj, argv[0], argv[1], argv[2]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.open");
+    }
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+static JSBool
+req_set_hdr(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+    jsval* argv = JS_ARGV(cx, vp);
+    JSBool ret = JS_FALSE;
+
+    if(argc == 2) {
+        ret = http_set_hdr(cx, obj, argv[0], argv[1]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.set_header");
+    }
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+static JSBool
+req_send(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+    jsval* argv = JS_ARGV(cx, vp);
+    JSBool ret = JS_FALSE;
+
+    if(argc == 1) {
+        ret = http_send(cx, obj, argv[0]);
+    } else {
+        JS_ReportError(cx, "Invalid call to CouchHTTP.send");
+    }
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+static JSBool
+req_status(JSContext* cx, JSObject* obj, jsid pid, jsval* vp)
+{
+    int status = http_status(cx, obj);
+    if(status < 0)
+        return JS_FALSE;
+
+    JS_SET_RVAL(cx, vp, INT_TO_JSVAL(status));
+    return JS_TRUE;
+}
+
+
+static JSBool
+evalcx(JSContext *cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    JSString* str;
+    JSObject* sandbox;
+    JSObject* global;
+    JSContext* subcx;
+    JSCrossCompartmentCall* call = NULL;
+    const jschar* src;
+    size_t srclen;
+    jsval rval;
+    JSBool ret = JS_FALSE;
+
+    sandbox = NULL;
+    if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox)) {
+        return JS_FALSE;
+    }
+
+    subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L);
+    if(!subcx) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    SETUP_REQUEST(subcx);
+
+    src = JS_GetStringCharsAndLength(cx, str, &srclen);
+
+    // Re-use the compartment associated with the main context,
+    // rather than creating a new compartment */
+    global = JS_GetGlobalObject(cx);
+    if(global == NULL) goto done;
+    call = JS_EnterCrossCompartmentCall(subcx, global);
+
+    if(!sandbox) {
+        sandbox = JS_NewGlobalObject(subcx, &global_class);
+        if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) {
+            goto done;
+        }
+    }
+
+    if(srclen == 0) {
+        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(sandbox));
+    } else {
+        JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, &rval);
+        JS_SET_RVAL(cx, vp, rval);
+    }
+    
+    ret = JS_TRUE;
+
+done:
+    JS_LeaveCrossCompartmentCall(call);
+    FINISH_REQUEST(subcx);
+    JS_DestroyContext(subcx);
+    return ret;
+}
+
+
+static JSBool
+gc(JSContext* cx, uintN argc, jsval* vp)
+{
+    JS_GC(cx);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return JS_TRUE;
+}
+
+
+static JSBool
+print(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    couch_print(cx, argc, argv);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return JS_TRUE;
+}
+
+
+static JSBool
+quit(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    int exit_code = 0;
+    JS_ConvertArguments(cx, argc, argv, "/i", &exit_code);
+    exit(exit_code);
+}
+
+
+static JSBool
+readline(JSContext* cx, uintN argc, jsval* vp)
+{
+    JSString* line;
+
+    /* GC Occasionally */
+    JS_MaybeGC(cx);
+
+    line = couch_readline(cx, stdin);
+    if(line == NULL) return JS_FALSE;
+
+    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(line));
+    return JS_TRUE;
+}
+
+
+static JSBool
+seal(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    JSObject *target;
+    JSBool deep = JS_FALSE;
+    JSBool ret;
+
+    if(!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
+        return JS_FALSE;
+
+    if(!target) {
+        JS_SET_RVAL(cx, vp, JSVAL_VOID);
+        return JS_TRUE;
+    }
+
+    
+    ret = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return ret;
+}
+
+
+JSClass CouchHTTPClass = {
+    "CouchHTTP",
+    JSCLASS_HAS_PRIVATE
+        | JSCLASS_CONSTRUCT_PROTOTYPE
+        | JSCLASS_HAS_RESERVED_SLOTS(2),
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_StrictPropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    req_dtor,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+
+JSPropertySpec CouchHTTPProperties[] = {
+    {"status", 0, JSPROP_READONLY, req_status, NULL},
+    {0, 0, 0, 0, 0}
+};
+
+
+JSFunctionSpec CouchHTTPFunctions[] = {
+    JS_FS("_open", req_open, 3, 0),
+    JS_FS("_setRequestHeader", req_set_hdr, 2, 0),
+    JS_FS("_send", req_send, 1, 0),
+    JS_FS_END
+};
+
+
+static JSFunctionSpec global_functions[] = {
+    JS_FS("evalcx", evalcx, 0, 0),
+    JS_FS("gc", gc, 0, 0),
+    JS_FS("print", print, 0, 0),
+    JS_FS("quit", quit, 0, 0),
+    JS_FS("readline", readline, 0, 0),
+    JS_FS("seal", seal, 0, 0),
+    JS_FS_END
+};
+
+
+int
+main(int argc, const char* argv[])
+{
+    JSRuntime* rt = NULL;
+    JSContext* cx = NULL;
+    JSObject* global = NULL;
+    JSCrossCompartmentCall *call = NULL;
+    JSObject* klass = NULL;
+    JSObject* script;
+    JSString* scriptsrc;
+    const jschar* schars;
+    size_t slen;
+    jsval sroot;
+    jsval result;
+
+    couch_args* args = couch_parse_args(argc, argv);
+
+    rt = JS_NewRuntime(64L * 1024L * 1024L);
+    if(rt == NULL)
+        return 1;
+
+    cx = JS_NewContext(rt, args->stack_size);
+    if(cx == NULL)
+        return 1;
+
+    JS_SetErrorReporter(cx, couch_error);
+    JS_ToggleOptions(cx, JSOPTION_XML);
+    
+    SETUP_REQUEST(cx);
+
+    global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
+    if(global == NULL)
+        return 1;
+
+    call = JS_EnterCrossCompartmentCall(cx, global);
+
+    JS_SetGlobalObject(cx, global);
+    
+    if(!JS_InitStandardClasses(cx, global))
+        return 1;
+
+    if(couch_load_funcs(cx, global, global_functions) != JS_TRUE)
+        return 1;
+ 
+    if(args->use_http) {
+        http_check_enabled();
+
+        klass = JS_InitClass(
+            cx, global,
+            NULL,
+            &CouchHTTPClass, req_ctor,
+            0,
+            CouchHTTPProperties, CouchHTTPFunctions,
+            NULL, NULL
+        );
+
+        if(!klass)
+        {
+            fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
+            exit(2);
+        }
+    } 
+
+    // Convert script source to jschars.
+    scriptsrc = dec_string(cx, args->script, strlen(args->script));
+    if(!scriptsrc)
+        return 1;
+
+    schars = JS_GetStringCharsAndLength(cx, scriptsrc, &slen);
+    
+    // Root it so GC doesn't collect it.
+    sroot = STRING_TO_JSVAL(scriptsrc); 
+    if(JS_AddValueRoot(cx, &sroot) != JS_TRUE) {
+        fprintf(stderr, "Internal root error.\n");
+        return 1;
+    }
+
+    // Compile and run
+    script = JS_CompileUCScript(cx, global, schars, slen, args->script_name, 1);
+    if(!script) {
+        fprintf(stderr, "Failed to compile script.\n");
+        return 1;
+    }
+    
+    JS_ExecuteScript(cx, global, script, &result);
+
+    // Warning message if we don't remove it.
+    JS_RemoveValueRoot(cx, &sroot);
+
+    JS_LeaveCrossCompartmentCall(call);
+    FINISH_REQUEST(cx);
+    JS_DestroyContext(cx);
+    JS_DestroyRuntime(rt);
+    JS_ShutDown();
+
+    return 0;
+}

Added: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.c?rev=1166526&view=auto
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.c (added)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.c Thu Sep  8 05:05:19 2011
@@ -0,0 +1,237 @@
+// 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.
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <jsapi.h>
+
+#include "util.h"
+#include "utf8.h"
+
+
+char*
+slurp_file(char* buf, const char* file)
+{
+    FILE* fp;
+    char fbuf[16384];
+    char* tmp;
+    size_t nread = 0;
+    size_t buflen = 0;
+
+    if(strcmp(file, "-") == 0) {
+        fp = stdin;
+    } else {
+        fp = fopen(file, "r");
+        if(fp == NULL) {
+            fprintf(stderr, "Failed to read file: %s\n", file);
+            exit(3);
+        }
+    }
+
+    while((nread = fread(fbuf, 1, 16384, fp)) > 0) {
+        if(buf == NULL) {
+            buflen = nread;
+            buf = (char*) malloc(nread + 1);
+            if(buf == NULL) {
+                fprintf(stderr, "Out of memory.\n");
+                exit(3);
+            }
+            memcpy(buf, fbuf, buflen);
+            buf[buflen] = '\0';
+        } else {
+            buflen = strlen(buf);
+            tmp = (char*) malloc(buflen + nread + 1);
+            if(tmp == NULL) {
+                fprintf(stderr, "Out of memory.\n");
+                exit(3);
+            }
+            memcpy(tmp, buf, buflen);
+            memcpy(tmp+buflen, fbuf, nread);
+            tmp[buflen+nread] = '\0';
+            free(buf);
+            buf = tmp;
+        }
+    }
+    return buf;
+}
+
+couch_args*
+couch_parse_args(int argc, const char* argv[])
+{
+    couch_args* args;
+    int i = 1;
+
+    args = (couch_args*) malloc(sizeof(couch_args));
+    if(args == NULL)
+        return NULL;
+
+    memset(args, '\0', sizeof(couch_args));
+    args->stack_size = 8L * 1024L;
+
+    while(i < argc) {
+        if(strcmp("--http", argv[i]) == 0) {
+            args->use_http = 1;
+        } else if(strcmp("--stack-size", argv[i]) == 0) {
+            args->stack_size = atoi(argv[i+1]);
+            if(args->stack_size <= 0) {
+                fprintf(stderr, "Invalid stack size.\n");
+                exit(2);
+            }
+        } else {
+            args->script = slurp_file(args->script, argv[i]);
+            if(args->script_name == NULL) {
+                if(strcmp(argv[i], "-") == 0) {
+                    args->script_name = "<stdin>";
+                } else {
+                    args->script_name = argv[i];
+                }
+            } else {
+                args->script_name = "<multiple_files>";
+            }
+        }
+        i++;
+    }
+
+    if(args->script_name == NULL || args->script == NULL) {
+        fprintf(stderr, "No script provided.\n");
+        exit(3);
+    }
+
+    return args;
+}
+
+
+int
+couch_fgets(char* buf, int size, FILE* fp)
+{
+    int n, i, c;
+
+    if(size <= 0) return -1;
+    n = size - 1;
+
+    for(i = 0; i < n && (c = getc(fp)) != EOF; i++) {
+        buf[i] = c;
+        if(c == '\n') {
+            i++;
+            break;
+        }
+    }
+
+    buf[i] = '\0';
+    return i;
+}
+
+
+JSString*
+couch_readline(JSContext* cx, FILE* fp)
+{
+    JSString* str;
+    char* bytes = NULL;
+    char* tmp = NULL;
+    size_t used = 0;
+    size_t byteslen = 256;
+    size_t readlen = 0;
+
+    bytes = JS_malloc(cx, byteslen);
+    if(bytes == NULL) return NULL;
+    
+    while((readlen = couch_fgets(bytes+used, byteslen-used, fp)) > 0) {
+        used += readlen;
+        
+        if(bytes[used-1] == '\n') {
+            bytes[used-1] = '\0';
+            break;
+        }
+        
+        // Double our buffer and read more.
+        byteslen *= 2;
+        tmp = JS_realloc(cx, bytes, byteslen);
+        if(!tmp) {
+            JS_free(cx, bytes);
+            return NULL;
+        }
+        
+        bytes = tmp;
+    }
+
+    // Treat empty strings specially
+    if(used == 0) {
+        JS_free(cx, bytes);
+        return JSVAL_TO_STRING(JS_GetEmptyStringValue(cx));
+    }
+
+    // Shring the buffer to the actual data size
+    tmp = JS_realloc(cx, bytes, used);
+    if(!tmp) {
+        JS_free(cx, bytes);
+        return NULL;
+    }
+    bytes = tmp;
+    byteslen = used;
+
+    str = dec_string(cx, bytes, byteslen);
+    JS_free(cx, bytes);
+    return str;
+}
+
+
+JSObject*
+couch_readfile(JSContext* cx, FILE* fp)
+{
+    return NULL;    
+}
+
+
+void
+couch_print(JSContext* cx, uintN argc, jsval* argv)
+{
+    char *bytes;
+    uintN i;
+
+    for(i = 0; i < argc; i++)
+    {
+        bytes = enc_string(cx, argv[i], NULL);
+        if(!bytes) return;
+
+        fprintf(stdout, "%s%s", i ? " " : "", bytes);
+        JS_free(cx, bytes);
+    }
+
+    fputc('\n', stdout);
+    fflush(stdout);
+}
+
+
+void
+couch_error(JSContext* cx, const char* mesg, JSErrorReport* report)
+{
+    if(!report || !JSREPORT_IS_WARNING(report->flags))
+    {
+        fprintf(stderr, "[couchjs] %s\n", mesg);
+    }
+}
+
+
+JSBool
+couch_load_funcs(JSContext* cx, JSObject* obj, JSFunctionSpec* funcs)
+{
+    JSFunctionSpec* f;
+    for(f = funcs; f->name != NULL; f++) {
+        if(!JS_DefineFunction(cx, obj, f->name, f->call, f->nargs, f->flags))
{
+            fprintf(stderr, "Failed to create function: %s\n", f->name);
+            return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+

Added: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.h
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.h?rev=1166526&view=auto
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.h (added)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/util.h Thu Sep  8 05:05:19 2011
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef COUCHJS_UTIL_H
+#define COUCHJS_UTIL_H
+
+#include <jsapi.h>
+
+typedef struct {
+    int         use_http;
+    int         stack_size;
+    const char* script_name;
+    char*       script;
+} couch_args;
+
+void couch_usage();
+couch_args* couch_parse_args(int argc, const char* argv[]);
+int couch_fgets(char* buf, int size, FILE* fp);
+JSString* couch_readline(JSContext* cx, FILE* fp);
+void couch_print(JSContext* cx, uintN argc, jsval* argv);
+void couch_error(JSContext* cx, const char* mesg, JSErrorReport* report);
+JSBool couch_load_funcs(JSContext* cx, JSObject* obj, JSFunctionSpec* funcs);
+
+
+#endif // Included util.h



Mime
View raw message