couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Couchdb Wiki] Update of "AndroidCouchPatch" by MattAdams
Date Wed, 02 Feb 2011 23:18:59 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Couchdb Wiki" for change notification.

The "AndroidCouchPatch" page has been changed by MattAdams.
http://wiki.apache.org/couchdb/AndroidCouchPatch?action=diff&rev1=1&rev2=2

--------------------------------------------------

  
  {{{
  diff --git a/configure.ac b/configure.ac
- index c609a08..98bbfc2 100644
+ index c609a08..a31bc7b 100644
  --- a/configure.ac
  +++ b/configure.ac
+ @@ -118,6 +118,21 @@ Is the Mozilla SpiderMonkey library installed?])])])])])
+  
+  AC_SUBST(JS_LIB_BASE)
+  
+ +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_fgets],
+ +    AC_DEFINE([HAVE_JS_FGETS], [1], [Define whether js_fgets is available to use]))
+ +
+ +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]))
+ +
+  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
- @@ -189,6 +189,13 @@ AC_COMPILE_IFELSE(
+ @@ -189,6 +204,13 @@ AC_COMPILE_IFELSE(
   CFLAGS="$OLD_CFLAGS"
   AC_LANG_POP(C)
   
@@ -21, +43 @@

   AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PATH],
       [set PATH to the Win32 native ICU binaries directory])], [
       ICU_CONFIG="" # supposed to be a command to query options...
- @@ -200,13 +207,19 @@ AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PAT
+ @@ -200,13 +222,19 @@ AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PAT
       ICU_LOCAL_CFLAGS=`$ICU_CONFIG --cppflags-searchpath`
       ICU_LOCAL_LDFLAGS=`$ICU_CONFIG --ldflags-searchpath`
       ICU_LOCAL_BIN=
@@ -42, +64 @@

   AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH],
       [set PATH to the Win32 native curl directory])], [
       # default build on windows is a static lib, and that's what we want too
- @@ -216,12 +229,15 @@ AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH],
+ @@ -216,12 +244,15 @@ AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH],
   ], [
       AC_CHECK_CURL([7.18.0])
       CURL_LDFLAGS=-lcurl
@@ -59, +81 @@

   case "$(uname -s)" in
     Linux)
       LIBS="$LIBS -lcrypt"
- @@ -234,6 +250,7 @@ case "$(uname -s)" in
+ @@ -234,6 +265,7 @@ case "$(uname -s)" in
       LIBS="$LIBS -lcrypto"
     ;;
   esac
@@ -67, +89 @@

   
   AC_PATH_PROG([ERL], [erl])
   
+ diff --git a/src/couchdb/priv/couch_js/http.c b/src/couchdb/priv/couch_js/http.c
+ index 6c2a8a8..5a2112d 100644
+ --- a/src/couchdb/priv/couch_js/http.c
+ +++ b/src/couchdb/priv/couch_js/http.c
+ @@ -43,6 +43,10 @@ char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", NULL};
+  #define DELETE  4
+  #define COPY    5
+  
+ +#ifdef JSFUN_CONSTRUCTOR
+ +#define JSFUN_FAST_NATIVE 0
+ +#endif
+ +
+  static JSBool
+  go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t blen);
+  
+ @@ -50,10 +54,21 @@ static JSString*
+  str_from_binary(JSContext* cx, char* data, size_t length);
+  
+  static JSBool
+ +#ifdef JSFUN_CONSTRUCTOR
+ +constructor(JSContext* cx, uintN argc, jsval* vp)
+ +#else
+  constructor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+ +#endif
+  {
+      HTTPData* http = NULL;
+      JSBool ret = JS_FALSE;
+ +#ifdef JSFUN_CONSTRUCTOR
+ +    JSObject* obj = JS_NewObjectForConstructor(cx, vp);
+ +    if(!obj) {
+ +        JS_ReportError(cx, "Failed to create 'this' object");
+ +        goto error;
+ +    }
+ +#endif
+  
+      http = (HTTPData*) malloc(sizeof(HTTPData));
+      if(!http)
+ @@ -80,6 +95,9 @@ error:
+      if(http) free(http);
+  
+  success:
+ +#ifdef JSFUN_CONSTRUCTOR
+ +    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
+ +#endif
+      return ret;
+  }
+  
+ @@ -89,7 +107,8 @@ destructor(JSContext* cx, JSObject* obj)
+      HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+      if(!http)
+      {
+ -        fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n");
+ +        // Comment out -- this messes up CouchDB and doesn't seem to be a big deal anyway
+ +        //fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n");
+      }
+      else
+      {
+ @@ -100,13 +119,20 @@ 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)
+ +{
+ +    JSBool ret = JS_FALSE;
+ +    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+ +    if(!obj) {
+ +        JS_ReportError(cx, "No 'this' object");
+ +        goto done;
+ +    }
+ +
+      HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+      char* method = NULL;
+      char* url = NULL;
+ -    JSBool ret = JS_FALSE;
+      int methid;
+ +    jsval* argv = JS_ARGV(cx, vp);
+  
+      if(!http)
+      {
+ @@ -174,6 +200,7 @@ open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+      // 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:
+ @@ -182,14 +209,21 @@ done:
+  }
+  
+  static JSBool
+ -setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+ -{    
+ +setheader(JSContext* cx, uintN argc, jsval* vp)
+ +{
+ +    JSBool ret = JS_FALSE;
+ +    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+ +    if(!obj) {
+ +        JS_ReportError(cx, "No 'this' object");
+ +        goto done;
+ +    }
+ +
+      HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+      char* keystr = NULL;
+      char* valstr = NULL;
+      char* hdrbuf = NULL;
+      size_t hdrlen = -1;
+ -    JSBool ret = JS_FALSE;
+ +    jsval* argv = JS_ARGV(cx, vp);
+  
+      if(!http)
+      {
+ @@ -234,6 +268,7 @@ setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval*
rval)
+      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:
+ @@ -245,12 +280,19 @@ done:
+  }
+  
+  static JSBool
+ -sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+ +sendreq(JSContext* cx, uintN argc, jsval* vp)
+  {
+ +    JSBool ret = JS_FALSE;
+ +    JSObject* obj = JS_THIS_OBJECT(cx, vp);
+ +    if(!obj) {
+ +        JS_ReportError(cx, "No 'this' object");
+ +        goto done;
+ +    }
+ +
+      HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+      char* body = NULL;
+      size_t bodylen = 0;
+ -    JSBool ret = JS_FALSE;
+ +    jsval* argv = JS_ARGV(cx, vp);
+      
+      if(!http)
+      {
+ @@ -270,6 +312,9 @@ sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval*
rval)
+  
+      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;
+ @@ -285,7 +330,12 @@ status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
+          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 the 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);
+ @@ -296,6 +346,7 @@ status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
+          JS_ReportError(cx, "INTERNAL: Invalid last_status");
+          return JS_FALSE;
+      }
+ +#endif
+  }
+  
+  JSClass CouchHTTPClass = {
+ @@ -320,9 +371,9 @@ JSPropertySpec CouchHTTPProperties[] = {
+  };
+  
+  JSFunctionSpec CouchHTTPFunctions[] = {
+ -    {"_open", open, 3, 0, 0},
+ -    {"_setRequestHeader", setheader, 2, 0, 0},
+ -    {"_send", sendreq, 1, 0, 0},
+ +    {"_open", open, 3, JSFUN_FAST_NATIVE, 0},
+ +    {"_setRequestHeader", setheader, 2, JSFUN_FAST_NATIVE, 0},
+ +    {"_send", sendreq, 1, JSFUN_FAST_NATIVE, 0},
+      {0, 0, 0, 0, 0}
+  };
+  
  diff --git a/src/couchdb/priv/couch_js/main.c b/src/couchdb/priv/couch_js/main.c
- index 376aa15..63c12c1 100644
+ index 376aa15..f4bef7c 100644
  --- a/src/couchdb/priv/couch_js/main.c
  +++ b/src/couchdb/priv/couch_js/main.c
+ @@ -28,14 +28,38 @@ int gExitCode = 0;
+  #define FINISH_REQUEST(cx) \
+      JS_EndRequest(cx); \
+      JS_ClearContextThread(cx);
+ +#define FINISH_REQUEST_AND_DESTROY(cx) \
+ +    JS_EndRequest(cx); \
+ +    JS_DestroyContext(cx);
+  #else
+  #define SETUP_REQUEST(cx)
+  #define FINISH_REQUEST(cx)
+ +#define FINISH_REQUEST_AND_DESTROY(cx) \
+ +    JS_DestroyContext(cx);
+ +#endif
+ +
+ +#ifdef JSFUN_CONSTRUCTOR
+ +#define JSFUN_FAST_NATIVE 0
+  #endif
+  
+ +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 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;
- @@ -64,7 +64,7 @@ evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+ @@ -43,6 +67,9 @@ evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+      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 +86,70 @@ evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
*rval)
+  
+      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);
+          sandbox = JS_NewObject(subcx, NULL, NULL, NULL);
- +        sandbox = JS_NewGlobalObject(subcx, 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:
+ -    FINISH_REQUEST(subcx);
+ -    JS_DestroyContext(subcx);
+ +#ifdef HAVE_COMPARTMENTS
+ +    if(call)
+ +    {
+ +        JS_LeaveCrossCompartmentCall(call);
+ +    }
+ +#endif
+ +    /* Don't use FINISH_REQUEST before destroying a context
+ +     * Destroying a context without a thread asserts on threadsafe
+ +     * debug builds */
+ +    FINISH_REQUEST_AND_DESTROY(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 +164,52 @@ print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
*rval)
+  
+      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;
+  }
+  
+ +#ifndef HAVE_JS_FGETS
+ +/* js_fgets is not linkable from C consumers with libmozjs >= 2.0,
+ + * so we reimplement it here */
+ +#undef js_fgets
+ +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;
+ +}
+ +#define js_fgets couchjs_fgets
+ +#endif
+ +
+  static char*
+  readfp(JSContext* cx, FILE* fp, size_t* buflen)
+  {
- @@ -127,12 +127,22 @@ readfp(JSContext* cx, FILE* fp, size_t* buflen)
+ @@ -130,7 +221,6 @@ readfp(JSContext* cx, FILE* fp, size_t* buflen)
-      size_t used = 0;
-      size_t byteslen = 256;
-      size_t readlen = 0;
- +    int c;
   
       bytes = JS_malloc(cx, byteslen);
       if(bytes == NULL) return NULL;
-      
+ -    
- -    while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0)
+      while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0)
- +    while(JS_TRUE)
       {
- +	//js_fgets is no longer an external API in libjs (in hg).
- +	while(used < byteslen && (c = getc(stdin)) != EOF) 
- +	{ 
- +		bytes[used] = c;
- +		used++;
- +	}
- +	bytes[used] = '\0';
- +	if (c == EOF) break;
- +
           used += readlen;
+ @@ -157,7 +247,7 @@ readfp(JSContext* cx, FILE* fp, size_t* buflen)
+  }
   
-          if(bytes[used-1] == '\n')
+  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,9 +263,10 @@ readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
*rval) {
+      /* 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;
+ +        //return JS_TRUE;
+ +        return JS_FALSE;
+      }
+  
+      /* Shrink the buffer to the real size */
+ @@ -191,22 +282,32 @@ readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
*rval) {
+      JS_free(cx, bytes);
+  
+      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;
+  
+      if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
+          return JS_FALSE;
+ -    if (!target)
+ +    if (!target) {
+ +        JS_SET_RVAL(cx, vp, JSVAL_VOID);
+          return JS_TRUE;
+ -    return JS_SealObject(cx, target, deep);
+ +    }
+ +#ifdef HAVE_JS_FREEZE_OBJECT
+ +    JSBool res = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target);
+ +#else
+ +    JSBool res = JS_SealObject(cx, target, deep);
+ +#endif
+ +    if (res == JS_TRUE)
+ +        JS_SET_RVAL(cx, vp, JSVAL_VOID);
+ +
+ +    return res;
+  }
+  
+  static void
+ @@ -248,29 +349,15 @@ printerror(JSContext *cx, const char *mesg, JSErrorReport *report)
+  }
+  
+  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},
+ +    {"evalcx", evalcx, 0, JSFUN_FAST_NATIVE, 0},
+ +    {"gc", gc, 0, JSFUN_FAST_NATIVE, 0},
+ +    {"print", print, 0, JSFUN_FAST_NATIVE, 0},
+ +    {"quit", quit, 0, JSFUN_FAST_NATIVE, 0},
+ +    {"readline", readline, 0, JSFUN_FAST_NATIVE, 0},
+ +    {"seal", seal, 0, JSFUN_FAST_NATIVE, 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
+ -};
+ -
+  int
+  main(int argc, const char * argv[])
+  {
- @@ -291,7 +301,7 @@ main(int argc, const char * argv[])
+ @@ -290,9 +377,18 @@ main(int argc, const char * argv[])
+      JS_ToggleOptions(cx, JSOPTION_XML);
       
       SETUP_REQUEST(cx);
-  
+ -
+ +#ifdef HAVE_COMPARTMENTS
- -    global = JS_NewObject(cx, &global_class, NULL, NULL);
+ +    global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
+ +    if (!global) return 1;
+ +    JSCrossCompartmentCall *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++)
+ @@ -309,8 +405,6 @@ main(int argc, const char * argv[])
+      {
+          return 1;
+      }
+ -    
+ -    JS_SetGlobalObject(cx, global);
+  
+      if(argc > 2)
+      {
+ @@ -328,9 +422,15 @@ main(int argc, const char * argv[])
+          execute_script(cx, global, argv[1]);
+      }
+  
+ -    FINISH_REQUEST(cx);
+ +#ifdef HAVE_COMPARTMENTS
+ +    JS_LeaveCrossCompartmentCall(call);
+ +#endif
+ +
+ +    /* Don't use FINISH_REQUEST before destroying a context
+ +     * Destroying a context without a thread asserts on threadsafe
+ +     * debug builds */
+ +    FINISH_REQUEST_AND_DESTROY(cx);
+  
+ -    JS_DestroyContext(cx);
+      JS_DestroyRuntime(rt);
+      JS_ShutDown();
+  
+ diff --git a/src/couchdb/priv/couch_js/utf8.c b/src/couchdb/priv/couch_js/utf8.c
+ index 699a6fe..b088020 100644
+ --- a/src/couchdb/priv/couch_js/utf8.c
+ +++ b/src/couchdb/priv/couch_js/utf8.c
+ @@ -12,6 +12,8 @@
+  
+  #include <jsapi.h>
+  
+ +#include "config.h"
+ +
+  static int
+  enc_char(uint8 *utf8Buffer, uint32 ucs4Char)
+  {
+ @@ -129,8 +131,12 @@ enc_string(JSContext* cx, jsval arg, size_t* buflen)
+      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 +289,4 @@ error:
+  
+  success:
+      return str;
+ -}
+ \ No newline at end of file
+ +}
  }}}
  

Mime
View raw message