couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rand...@apache.org
Subject svn commit: r1137464 - in /couchdb/trunk: THANKS configure.ac src/couchdb/priv/couch_js/http.c src/couchdb/priv/couch_js/jscompat.h src/couchdb/priv/couch_js/main.c src/couchdb/priv/couch_js/utf8.c
Date Sun, 19 Jun 2011 23:09:43 GMT
Author: randall
Date: Sun Jun 19 23:09:42 2011
New Revision: 1137464

URL: http://svn.apache.org/viewvc?rev=1137464&view=rev
Log:
Fix COUCHDB-1078 - Port couchjs to newest libmozjs

As usually, please test and report any build system problems as I
cannot test every configuration.

Thanks to Chris Coulson for the original patch.

Added:
    couchdb/trunk/src/couchdb/priv/couch_js/jscompat.h
Modified:
    couchdb/trunk/THANKS
    couchdb/trunk/configure.ac
    couchdb/trunk/src/couchdb/priv/couch_js/http.c
    couchdb/trunk/src/couchdb/priv/couch_js/main.c
    couchdb/trunk/src/couchdb/priv/couch_js/utf8.c

Modified: couchdb/trunk/THANKS
URL: http://svn.apache.org/viewvc/couchdb/trunk/THANKS?rev=1137464&r1=1137463&r2=1137464&view=diff
==============================================================================
--- couchdb/trunk/THANKS (original)
+++ couchdb/trunk/THANKS Sun Jun 19 23:09:42 2011
@@ -83,6 +83,7 @@ suggesting improvements or submitting ch
  * Nathan Vander Wilt <natevw@yahoo.com>
  * Caolan McMahon <caolan.mcmahon@googlemail.com>
  * Andrey Somov <trophybase@gmail.com>
+ * Chris Coulson <chrisccoulson.googlemail.com>
  
 
 For a list of authors see the `AUTHORS` file.

Modified: couchdb/trunk/configure.ac
URL: http://svn.apache.org/viewvc/couchdb/trunk/configure.ac?rev=1137464&r1=1137463&r2=1137464&view=diff
==============================================================================
--- couchdb/trunk/configure.ac (original)
+++ couchdb/trunk/configure.ac Sun Jun 19 23:09:42 2011
@@ -121,15 +121,19 @@ AC_ARG_WITH([erlang], [AC_HELP_STRING([-
 ])
 AC_SUBST(ERLANG_FLAGS)
 
-PKG_CHECK_MODULES([JS], [mozilla-js >= 1.7], [
-    JS_LIB_DIR="$(${PKG_CONFIG} --variable=sdkdir mozilla-js)/lib"
+PKG_CHECK_MODULES([JS], [mozjs185], [
+    JS_LIB_DIR="$(${PKG_CONFIG} --variable=libdir mozjs185)"
+], [
+    PKG_CHECK_MODULES([JS], [mozilla-js >= 1.7], [
+        JS_LIB_DIR="$(${PKG_CONFIG} --variable=sdkdir mozilla-js)/lib"
     ], [
-    JS_LIB_DIR="${libdir}"
-    JS_CFLAGS="-I/usr/include"
-    JS_CFLAGS="$JS_CFLAGS -I/usr/include/js"
-    JS_CFLAGS="$JS_CFLAGS -I/usr/include/mozjs"
-    JS_CFLAGS="$JS_CFLAGS -I/usr/local/include/js"
-    JS_CFLAGS="$JS_CFLAGS -I/opt/local/include/js"
+        JS_LIB_DIR="${libdir}"
+        JS_CFLAGS="-I/usr/include"
+        JS_CFLAGS="$JS_CFLAGS -I/usr/include/js"
+        JS_CFLAGS="$JS_CFLAGS -I/usr/include/mozjs"
+        JS_CFLAGS="$JS_CFLAGS -I/usr/local/include/js"
+        JS_CFLAGS="$JS_CFLAGS -I/opt/local/include/js"
+    ])
 ])
 
 AC_ARG_WITH([js-include], [AC_HELP_STRING([--with-js-include=PATH],
@@ -175,16 +179,40 @@ AM_CONDITIONAL([WINDOWS], [test x$IS_WIN
 
 OLD_LIBS="$LIBS"
 LIBS="$JS_LIBS $LIBS"
-AC_CHECK_LIB([mozjs], [JS_NewContext], [JS_LIB_BASE=mozjs], [
-    AC_CHECK_LIB([js], [JS_NewContext], [JS_LIB_BASE=js], [
-        AC_CHECK_LIB([js3250], [JS_NewContext], [JS_LIB_BASE=js3250], [
-            AC_CHECK_LIB([js32], [JS_NewContext], [JS_LIB_BASE=js32], [
-                AC_MSG_ERROR([Could not find the js library.
-
-Is the Mozilla SpiderMonkey library installed?])])])])])
+AC_CHECK_LIB([mozjs185], [JS_NewContext], [JS_LIB_BASE=mozjs185], [
+    AC_CHECK_LIB([mozjs], [JS_NewContext], [JS_LIB_BASE=mozjs], [
+        AC_CHECK_LIB([js], [JS_NewContext], [JS_LIB_BASE=js], [
+            AC_CHECK_LIB([js3250], [JS_NewContext], [JS_LIB_BASE=js3250], [
+                AC_CHECK_LIB([js32], [JS_NewContext], [JS_LIB_BASE=js32], [
+                    AC_MSG_ERROR([Could not find the js library.
+
+Is the Mozilla SpiderMonkey library installed?])])])])])])
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_FreezeObject],
+    AC_DEFINE([HAVE_JS_FREEZE_OBJECT], [1],
+        [Define whether we have JS_FreezeObject]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_NewGlobalObject],
+    AC_DEFINE([HAVE_JS_NEW_GLOBAL_OBJECT], [1],
+        [Define whether we have JS_NewGlobalObject]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_GetStringCharsAndLength],
+    AC_DEFINE([HAVE_JS_GET_STRING_CHARS_AND_LENGTH], [1],
+        [Define whether we have JS_GetStringCharsAndLength]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_NewCompartmentAndGlobalObject],
+    AC_DEFINE([HAVE_COMPARTMENTS], [1],
+        [Define whether we have JS_NewCompartmentAndGlobalObject]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_StrictPropertyStub],
+    AC_DEFINE([HAVE_JS_STRICT_PROPERTY_STUB], [1],
+        [Define whether we have JS_StrictPropertyStub]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_DestroyScript],
+    AC_DEFINE([HAVE_SCRIPT_TYPE], [1],
+        [Define whether scripts have a special JSScript type]))
 LIBS="$OLD_LIBS"
 
-
 if test x${IS_WINDOWS} = xTRUE; then
     if test -f "$JS_LIB_DIR/$JS_LIB_BASE.dll"; then
         # seamonkey 1.7- build layout on Windows
@@ -247,7 +275,7 @@ CPPFLAGS="$OLD_CPPFLAGS"
 
 AC_LANG_PUSH(C)
 OLDCFLAGS="$CFLAGS"
-CFLAGS="-Werror-implicit-function-declaration $CFLAGS"
+CFLAGS="-Werror-implicit-function-declaration $JS_CFLAGS $OLDCFLAGS"
 AC_COMPILE_IFELSE(
     [AC_LANG_PROGRAM(
         [[#include <jsapi.h>]],
@@ -255,6 +283,26 @@ AC_COMPILE_IFELSE(
     )],
     AC_DEFINE([USE_JS_SETOPCB], [], [Use new JS_SetOperationCallback])
 )
+CFLAGS="$JS_CFLAGS $OLDCFLAGS"
+AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM(
+        [[#include <jsapi.h>]],
+        [[static JSFunctionSpec fs;
+          fs.extra = 0;]]
+    )],
+    AC_DEFINE([JS_FS_HAS_EXTRA], [1], [JSFunctionSpec has an extra member])
+)
+CFLAGS="$JS_CFLAGS $OLDCFLAGS -Werror"
+AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM(
+        [[#include <jsapi.h>
+          static JSBool op(JSContext* cx, JSObject* obj, jsid id, jsval* vp) {}]],
+        [[static JSPropertySpec spec;
+          spec.getter = op;]]
+    )],
+    AC_DEFINE([JS_PROPERTY_OP_HAS_ID_AS_JSID], [1],
+        [The type of "id" in the prototype for JSPropertyOp is a jsid])
+)
 CFLAGS="$OLD_CFLAGS"
 AC_LANG_POP(C)
 

Modified: couchdb/trunk/src/couchdb/priv/couch_js/http.c
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/priv/couch_js/http.c?rev=1137464&r1=1137463&r2=1137464&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/priv/couch_js/http.c (original)
+++ couchdb/trunk/src/couchdb/priv/couch_js/http.c Sun Jun 19 23:09:42 2011
@@ -10,12 +10,11 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-#include "config.h"
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <jsapi.h>
+#include "config.h"
 
 #ifndef HAVE_CURL
 
@@ -34,6 +33,7 @@ install_http(JSContext* cx, JSObject* gl
 #include <curl/curl.h>
 
 #include "utf8.h"
+#include "jscompat.h"
 
 #ifdef XP_WIN
 // Map some of the string function names to things which exist on Windows
@@ -66,12 +66,14 @@ go(JSContext* cx, JSObject* obj, HTTPDat
 static JSString*
 str_from_binary(JSContext* cx, char* data, size_t length);
 
-static JSBool
-constructor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+COUCHJS_CONSTRUCTOR_DECLARE(constructor)
 {
+    COUCHJS_CONSTRUCTOR_INIT_VARS
     HTTPData* http = NULL;
     JSBool ret = JS_FALSE;
 
+    COUCHJS_CONSTRUCTOR_CONSTRUCT
+
     http = (HTTPData*) malloc(sizeof(HTTPData));
     if(!http)
     {
@@ -89,7 +91,8 @@ constructor(JSContext* cx, JSObject* obj
         JS_ReportError(cx, "Failed to set private CouchHTTP data.");
         goto error;
     }
-    
+
+    COUCHJS_CONSTRUCTOR_FINISH
     ret = JS_TRUE;
     goto success;
 
@@ -106,7 +109,10 @@ destructor(JSContext* cx, JSObject* obj)
     HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
     if(!http)
     {
-        fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n");
+        // mozjs185 seems to create a ghost object that gets finalized
+        // No messing about with flags seems to prevent this or ensure it's
+        // constructed properly.
+        fprintf(stderr, "No valid CouchHTTP instance to destroy [harmless].\n");
     }
     else
     {
@@ -117,8 +123,9 @@ destructor(JSContext* cx, JSObject* obj)
 }
 
 static JSBool
-open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{    
+open(JSContext* cx, uintN argc, jsval* vp)
+{
+    COUCHJS_NATIVE_INIT_VARS(argv, obj)
     HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
     char* method = NULL;
     char* url = NULL;
@@ -191,6 +198,7 @@ open(JSContext* cx, JSObject* obj, uintN
     // Disable Expect: 100-continue
     http->req_headers = curl_slist_append(http->req_headers, "Expect:");
 
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     ret = JS_TRUE;
 
 done:
@@ -199,8 +207,9 @@ done:
 }
 
 static JSBool
-setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{    
+setheader(JSContext* cx, uintN argc, jsval* vp)
+{
+    COUCHJS_NATIVE_INIT_VARS(argv, obj)
     HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
     char* keystr = NULL;
     char* valstr = NULL;
@@ -251,6 +260,7 @@ setheader(JSContext* cx, JSObject* obj, 
     snprintf(hdrbuf, hdrlen, "%s: %s", keystr, valstr);
     http->req_headers = curl_slist_append(http->req_headers, hdrbuf);
 
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     ret = JS_TRUE;
 
 done:
@@ -262,8 +272,9 @@ done:
 }
 
 static JSBool
-sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+sendreq(JSContext* cx, uintN argc, jsval* vp)
 {
+    COUCHJS_NATIVE_INIT_VARS(argv, obj)
     HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
     char* body = NULL;
     size_t bodylen = 0;
@@ -286,14 +297,15 @@ sendreq(JSContext* cx, JSObject* obj, ui
     }
 
     ret = go(cx, obj, http, body, bodylen);
+    if (ret == JS_TRUE)
+      JS_SET_RVAL(cx, vp, JSVAL_VOID);
 
 done:
     if(body) free(body);
     return ret;
 }
 
-static JSBool
-status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
+COUCHJS_GETTER_DECLARE(status)
 {
     HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
     
@@ -302,7 +314,13 @@ status(JSContext* cx, JSObject* obj, jsv
         JS_ReportError(cx, "Invalid CouchHTTP instance.");
         return JS_FALSE;
     }
-    
+
+#ifndef INT_FITS_IN_JSVAL
+    // jsval's are 64-bits wide in mozjs >= 2.0, so a jsint can use a full
+    // 32-bits now no bits are reserved for tagging
+    *vp = INT_TO_JSVAL(http->last_status);
+    return JS_TRUE;
+#else
     if(INT_FITS_IN_JSVAL(http->last_status))
     {
         *vp = INT_TO_JSVAL(http->last_status);
@@ -313,6 +331,7 @@ status(JSContext* cx, JSObject* obj, jsv
         JS_ReportError(cx, "INTERNAL: Invalid last_status");
         return JS_FALSE;
     }
+#endif
 }
 
 JSClass CouchHTTPClass = {
@@ -323,7 +342,7 @@ JSClass CouchHTTPClass = {
     JS_PropertyStub,
     JS_PropertyStub,
     JS_PropertyStub,
-    JS_PropertyStub,
+    JS_SETPROPERTY_PROPERTY_STUB,
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub,
@@ -337,10 +356,10 @@ JSPropertySpec CouchHTTPProperties[] = {
 };
 
 JSFunctionSpec CouchHTTPFunctions[] = {
-    {"_open", open, 3, 0, 0},
-    {"_setRequestHeader", setheader, 2, 0, 0},
-    {"_send", sendreq, 1, 0, 0},
-    {0, 0, 0, 0, 0}
+    JS_FS("_open", COUCHJS_NATIVE_FUNC(open), 3, JSFUN_FAST_NATIVE),
+    JS_FS("_setRequestHeader", COUCHJS_NATIVE_FUNC(setheader), 2, JSFUN_FAST_NATIVE),
+    JS_FS("_send", COUCHJS_NATIVE_FUNC(sendreq), 1, JSFUN_FAST_NATIVE),
+    JS_FS_END
 };
 
 JSObject*

Added: couchdb/trunk/src/couchdb/priv/couch_js/jscompat.h
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/priv/couch_js/jscompat.h?rev=1137464&view=auto
==============================================================================
--- couchdb/trunk/src/couchdb/priv/couch_js/jscompat.h (added)
+++ couchdb/trunk/src/couchdb/priv/couch_js/jscompat.h Sun Jun 19 23:09:42 2011
@@ -0,0 +1,91 @@
+// 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 COUCH_JS_JS_COMPAT_H
+#define COUCH_JS_JS_COMPAT_H
+
+#ifdef JS_FS_HAS_EXTRA
+# undef JS_FS
+# undef JS_FS_END
+# define JS_FS(name,call,nargs,flags) {name, call, nargs, flags, 0}
+# define JS_FS_END JS_FS(0, 0, 0, 0)
+#endif
+
+#ifdef JSFUN_CONSTRUCTOR
+# define JSFUN_FAST_NATIVE 0
+# define COUCHJS_CONSTRUCTOR_DECLARE(name) \
+    static JSBool \
+    name(JSContext* cx, uintN argc, jsval* vp)
+# define COUCHJS_CONSTRUCTOR_INIT_VARS \
+    JSObject *obj = NULL; \
+    jsval *argv = JS_ARGV(cx, vp);
+# define COUCHJS_CONSTRUCTOR_CONSTRUCT \
+    obj = JS_NewObjectForConstructor(cx, vp); \
+    if(!obj) { \
+        JS_ReportError(cx, "Failed to create 'this' object"); \
+        return JS_FALSE; \
+    }
+# define COUCHJS_CONSTRUCTOR_FINISH \
+    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
+# define COUCHJS_NATIVE_FUNC(func) func
+#else
+# define COUCHJS_CONSTRUCTOR_DECLARE(name) \
+    static JSBool \
+    name(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+# define COUCHJS_CONSTRUCTOR_INIT_VARS
+# define COUCHJS_CONSTRUCTOR_CONSTRUCT
+# define COUCHJS_CONSTRUCTOR_FINISH
+# define COUCHJS_NATIVE_FUNC(func) (JSNative) func
+#endif
+
+#ifdef HAVE_JS_STRICT_PROPERTY_STUB
+# define JS_SETPROPERTY_PROPERTY_STUB JS_StrictPropertyStub
+#else
+# define JS_SETPROPERTY_PROPERTY_STUB JS_PropertyStub
+#endif
+
+#ifdef HAVE_SCRIPT_TYPE
+# define COUCHJS_SCRIPT JSScript
+# define COUCHJS_DESTROY_SCRIPT(cx, script) \
+    JS_DestroyScript(cx, script)
+#else
+# define COUCHJS_SCRIPT JSObject
+# define COUCHJS_DESTROY_SCRIPT(cx, script)
+#endif
+
+#ifdef HAVE_JS_FREEZE_OBJECT
+# define COUCHJS_SEAL_OBJECT(res, cx, target, deep) \
+    res = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target);
+#else
+# define COUCHJS_SEAL_OBJECT(res, cx, target, deep) \
+    res = JS_SealObject(cx, target, deep);
+#endif
+
+#define COUCHJS_NATIVE_INIT_VARS(argv, obj) \
+    jsval* argv = JS_ARGV(cx, vp); \
+    JSObject* obj = JS_THIS_OBJECT(cx, vp); \
+    if (!obj) { \
+        JS_ReportError(cx, "No 'this' object"); \
+        return JS_FALSE; \
+    }
+
+#ifdef JS_PROPERTY_OP_HAS_ID_AS_JSID
+# define COUCHJS_GETTER_DECLARE(name) \
+    static JSBool \
+    status(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
+#else
+# define COUCHJS_GETTER_DECLARE(name) \
+    static JSBool \
+    status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
+#endif
+
+#endif

Modified: couchdb/trunk/src/couchdb/priv/couch_js/main.c
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/priv/couch_js/main.c?rev=1137464&r1=1137463&r2=1137464&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/priv/couch_js/main.c (original)
+++ couchdb/trunk/src/couchdb/priv/couch_js/main.c Sun Jun 19 23:09:42 2011
@@ -18,6 +18,7 @@
 
 #include "utf8.h"
 #include "http.h"
+#include "jscompat.h"
 
 int gExitCode = 0;
 
@@ -33,9 +34,25 @@ int gExitCode = 0;
 #define FINISH_REQUEST(cx)
 #endif
 
+
+static JSClass global_class = {
+    "GlobalClass",
+    JSCLASS_GLOBAL_FLAGS,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_SETPROPERTY_PROPERTY_STUB,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
 static JSBool
-evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+evalcx(JSContext* cx, uintN argc, jsval* vp)
 {
+    jsval* argv = JS_ARGV(cx, vp);
     JSString *str;
     JSObject *sandbox;
     JSContext *subcx;
@@ -43,6 +60,9 @@ evalcx(JSContext *cx, JSObject *obj, uin
     size_t srclen;
     JSBool ret = JS_FALSE;
     jsval v;
+#ifdef HAVE_COMPARTMENTS
+    JSCrossCompartmentCall *call = NULL;
+#endif
 
     sandbox = NULL;
     if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox))
@@ -59,42 +79,69 @@ evalcx(JSContext *cx, JSObject *obj, uin
 
     SETUP_REQUEST(subcx);
 
+#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH
+    src = JS_GetStringCharsAndLength(cx, str, &srclen);
+#else
     src = JS_GetStringChars(str);
     srclen = JS_GetStringLength(str);
+#endif
+
+#ifdef HAVE_COMPARTMENTS
+    // Re-use the compartment associated with the main context,
+    // rather than creating a new compartment */
+    JSObject *global = JS_GetGlobalObject(cx);
+    if(!global)
+    {
+       goto done;
+    }
+    call = JS_EnterCrossCompartmentCall(subcx, global);
+#endif
 
     if(!sandbox)
     {
+#ifdef HAVE_JS_NEW_GLOBAL_OBJECT
+        sandbox = JS_NewGlobalObject(subcx, &global_class);
+#else
         sandbox = JS_NewObject(subcx, NULL, NULL, NULL);
+#endif
         if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) goto done;
     }
 
     if(srclen == 0)
     {
-        *rval = OBJECT_TO_JSVAL(sandbox);
+        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(sandbox));
     }
     else
     {
-        JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval);
+        JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, &JS_RVAL(cx, vp));
     }
     
     ret = JS_TRUE;
 
 done:
+#ifdef HAVE_COMPARTMENTS
+    if(call)
+    {
+        JS_LeaveCrossCompartmentCall(call);
+    }
+#endif
     FINISH_REQUEST(subcx);
     JS_DestroyContext(subcx);
     return ret;
 }
 
 static JSBool
-gc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+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, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+print(JSContext *cx, uintN argc, jsval *vp)
 {
+    jsval *argv = JS_ARGV(cx, vp);
     uintN i;
     char *bytes;
 
@@ -109,16 +156,47 @@ print(JSContext *cx, JSObject *obj, uint
 
     fputc('\n', stdout);
     fflush(stdout);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+quit(JSContext *cx, uintN argc, jsval *vp)
 {
+    jsval *argv = JS_ARGV(cx, vp);
     JS_ConvertArguments(cx, argc, argv, "/ i", &gExitCode);
     return JS_FALSE;
 }
 
+static int
+couchjs_fgets(char *buf, int size, FILE *file)
+{
+    int n, i, c;
+    JSBool crflag;
+
+    n = size - 1;
+    if (n < 0)
+        return -1;
+
+    crflag = JS_FALSE;
+    for (i = 0; i < n && (c = getc(file)) != EOF; i++)
+    {
+        buf[i] = c;
+        if (c == '\n') {        /* any \n ends a line */
+            i++;                /* keep the \n; we know there is room for \0 */
+            break;
+        }
+        if (crflag) {           /* \r not followed by \n ends line at the \r */
+            ungetc(c, file);
+            break;              /* and overwrite c in buf with \0 */
+        }
+        crflag = (c == '\r');
+    }
+
+    buf[i] = '\0';
+    return i;
+}
+
 static char*
 readfp(JSContext* cx, FILE* fp, size_t* buflen)
 {
@@ -131,7 +209,7 @@ readfp(JSContext* cx, FILE* fp, size_t* 
     bytes = JS_malloc(cx, byteslen);
     if(bytes == NULL) return NULL;
     
-    while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0)
+    while((readlen = couchjs_fgets(bytes+used, byteslen-used, stdin)) > 0)
     {
         used += readlen;
 
@@ -157,7 +235,7 @@ readfp(JSContext* cx, FILE* fp, size_t* 
 }
 
 static JSBool
-readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
+readline(JSContext *cx, uintN argc, jsval *vp) {
     jschar *chars;
     JSString *str;
     char* bytes;
@@ -173,7 +251,7 @@ readline(JSContext *cx, JSObject *obj, u
     /* Treat the empty string specially */
     if(byteslen == 0)
     {
-        *rval = JS_GetEmptyStringValue(cx);
+        JS_SET_RVAL(cx, vp, JS_GetEmptyStringValue(cx));
         JS_free(cx, bytes);
         return JS_TRUE;
     }
@@ -192,27 +270,37 @@ readline(JSContext *cx, JSObject *obj, u
 
     if(!str) return JS_FALSE;
 
-    *rval = STRING_TO_JSVAL(str);
+    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
 
     return JS_TRUE;
 }
 
 static JSBool
-seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
+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;
-    return JS_SealObject(cx, target, deep);
+    }
+
+    COUCHJS_SEAL_OBJECT(ret, cx, target, deep);
+    if (ret == JS_TRUE)
+        JS_SET_RVAL(cx, vp, JSVAL_VOID);
+
+    return ret;
 }
 
 static void
 execute_script(JSContext *cx, JSObject *obj, const char *filename) {
     FILE *file;
-    JSScript *script;
+    COUCHJS_SCRIPT *script;
     jsval result;
 
     if(!filename || strcmp(filename, "-") == 0)
@@ -234,7 +322,7 @@ execute_script(JSContext *cx, JSObject *
     if(script)
     {
         JS_ExecuteScript(cx, obj, script, &result);
-        JS_DestroyScript(cx, script);
+        COUCHJS_DESTROY_SCRIPT(cx, script);
     }
 }
 
@@ -248,27 +336,13 @@ printerror(JSContext *cx, const char *me
 }
 
 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}
-};
-
-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
+    JS_FS("evalcx", COUCHJS_NATIVE_FUNC(evalcx), 0, JSFUN_FAST_NATIVE),
+    JS_FS("gc", COUCHJS_NATIVE_FUNC(gc), 0, JSFUN_FAST_NATIVE),
+    JS_FS("print", COUCHJS_NATIVE_FUNC(print), 0, JSFUN_FAST_NATIVE),
+    JS_FS("quit", COUCHJS_NATIVE_FUNC(quit), 0, JSFUN_FAST_NATIVE),
+    JS_FS("readline", COUCHJS_NATIVE_FUNC(readline), 0, JSFUN_FAST_NATIVE),
+    JS_FS("seal", COUCHJS_NATIVE_FUNC(seal), 0, JSFUN_FAST_NATIVE),
+    JS_FS_END
 };
 
 int
@@ -284,6 +358,9 @@ main(int argc, const char * argv[])
     JSRuntime* rt = NULL;
     JSContext* cx = NULL;
     JSObject* global = NULL;
+#ifdef HAVE_COMPARTMENTS
+    JSCrossCompartmentCall *call = NULL;
+#endif
     JSFunctionSpec* sp = NULL;
     const char* script_name = NULL;
     int use_http = 0;
@@ -325,8 +402,18 @@ main(int argc, const char * argv[])
     
     SETUP_REQUEST(cx);
 
+#ifdef HAVE_COMPARTMENTS
+    global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
+    if (!global) return 1;
+    call = JS_EnterCrossCompartmentCall(cx, global);
+#elif HAVE_JS_NEW_GLOBAL_OBJECT
+    global = JS_NewGlobalObject(cx, &global_class);
+    if (!global) return 1;
+#else
     global = JS_NewObject(cx, &global_class, NULL, NULL);
     if (!global) return 1;
+    JS_SetGlobalObject(cx, global);
+#endif
     if (!JS_InitStandardClasses(cx, global)) return 1;
     
     for(sp = global_functions; sp->name != NULL; sp++)
@@ -344,9 +431,11 @@ main(int argc, const char * argv[])
         return 2;
     }
 
-    JS_SetGlobalObject(cx, global);
     execute_script(cx, global, script_name);
 
+#ifdef HAVE_COMPARTMENTS
+    JS_LeaveCrossCompartmentCall(call);
+#endif
     FINISH_REQUEST(cx);
 
     JS_DestroyContext(cx);

Modified: couchdb/trunk/src/couchdb/priv/couch_js/utf8.c
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/priv/couch_js/utf8.c?rev=1137464&r1=1137463&r2=1137464&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/priv/couch_js/utf8.c (original)
+++ couchdb/trunk/src/couchdb/priv/couch_js/utf8.c Sun Jun 19 23:09:42 2011
@@ -11,6 +11,7 @@
 // the License.
 
 #include <jsapi.h>
+#include "config.h"
 
 static int
 enc_char(uint8 *utf8Buffer, uint32 ucs4Char)
@@ -121,7 +122,7 @@ char*
 enc_string(JSContext* cx, jsval arg, size_t* buflen)
 {
     JSString* str = NULL;
-    jschar* src = NULL;
+    const jschar* src = NULL;
     char* bytes = NULL;
     size_t srclen = 0;
     size_t byteslen = 0;
@@ -129,8 +130,12 @@ enc_string(JSContext* cx, jsval arg, siz
     str = JS_ValueToString(cx, arg);
     if(!str) goto error;
 
+#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH
+    src = JS_GetStringCharsAndLength(cx, str, &srclen);
+#else
     src = JS_GetStringChars(str);
     srclen = JS_GetStringLength(str);
+#endif
 
     if(!enc_charbuf(src, srclen, NULL, &byteslen)) goto error;
     
@@ -283,4 +288,4 @@ error:
 
 success:
     return str;
-}
\ No newline at end of file
+}



Mime
View raw message