[splinter] Port test framework to xulrunner-2.0 API



commit f04868a2dc228fcee5453c66bc76580af33cd439
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Fri Feb 18 20:47:51 2011 -0500

    Port test framework to xulrunner-2.0 API
    
    - Switch to "fast natives"
    - Remove unneeded JS_AddRoot calls
    - Use JS_NewGlobalObject
    - Switch from JS_GetStringBytes to JS_EncodeString
    - Fix bugs that were causing modules not to properly
      encapsulated (include('Utils') caused Utils to be defined
      on the global object.

 jstest.c |   96 ++++++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 63 insertions(+), 33 deletions(-)
---
diff --git a/jstest.c b/jstest.c
index 2e05562..859bc9a 100644
--- a/jstest.c
+++ b/jstest.c
@@ -12,13 +12,7 @@ static JSClass global_class = {
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
-/* The class of module objects. */
-static JSClass module_class = {
-    "module", 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 fn_include(JSContext *cx, uintN argc, jsval *vp);
 
 /* The error reporter callback. */
 static void
@@ -76,7 +70,7 @@ load_module(JSContext *cx, const char *module_name, JSObject **module_out)
     char *src = NULL;
     gsize length;
     GError *error = NULL;
-    JSObject *module;
+    JSObject *module = NULL;
     jsval dummy;
 
     lower_name = g_strdup(module_name);
@@ -91,16 +85,27 @@ load_module(JSContext *cx, const char *module_name, JSObject **module_out)
     }
 
     /* Create the module object. */
-    module = JS_NewObject(cx, &module_class, JS_GetGlobalObject(cx), NULL);
+    module = JS_NewObject(cx, NULL, NULL, NULL);
     if (module == NULL)
         goto out;
 
+    /* We can't just define the include function as a global function since it
+     * needs to have the 'this' object pointing to the current module when
+     * called, so define it separately on each module object
+     */
+    JS_DefineFunction(cx, module,
+                      "include", fn_include, 1, 0);
+
+    /* https://bugzilla.mozilla.org/show_bug.cgi?id=599651 means we
+     * can't just pass in the global as the parent */
+    JS_SetParent(cx, module, JS_GetGlobalObject(cx));
+
     /* Define first to allow recursive imports */
     JS_DefineProperty(cx, get_modules_map(cx), module_name,
                       OBJECT_TO_JSVAL(module), NULL, NULL,
                       JSPROP_PERMANENT | JSPROP_READONLY);
 
-    if (!JS_EvaluateScript(cx, module, src, length, file_name, 0, &dummy)) {
+    if (!JS_EvaluateScript(cx, module, src, length, file_name, 1, &dummy)) {
         module = NULL;
         goto out;
     }
@@ -117,14 +122,17 @@ load_module(JSContext *cx, const char *module_name, JSObject **module_out)
 }
 
 static JSBool
-fn_include(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+fn_include(JSContext *cx, uintN argc, jsval *vp)
 {
-    const char *module_name;
+    JSString *module_name_js;
+    char *module_name = NULL;
     JSObject *module = NULL;
 
-    *rval = JSVAL_VOID;
+    if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &module_name_js))
+        goto out;
 
-    if (!JS_ConvertArguments(cx, argc, argv, "s", &module_name))
+    module_name = JS_EncodeString(cx, module_name_js);
+    if (module_name == NULL)
         goto out;
 
     if (strchr(module_name, '/') != NULL ||
@@ -146,23 +154,34 @@ fn_include(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 
  out:
     if (module != NULL)
-        JS_DefineProperty(cx, obj, module_name,
+        JS_DefineProperty(cx, JS_THIS_OBJECT(cx, vp), module_name,
                           OBJECT_TO_JSVAL(module), NULL, NULL,
                           JSPROP_PERMANENT | JSPROP_READONLY);
 
+    JS_free(cx, module_name);
+
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+
     return module != NULL;
 }
 
-JSBool fn_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+JSBool fn_load(JSContext *cx, uintN argc, jsval *vp)
 {
-    const char *filename;
+    JSString *filename_js;
+    char *filename = NULL;
     char *contents = NULL;
     gsize length;
     JSBool result = JS_FALSE;
     GError *error = NULL;
     JSString *jsstr;
 
-    if (!JS_ConvertArguments(cx, argc, argv, "s", &filename))
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+
+    if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &filename_js))
+        goto out;
+
+    filename = JS_EncodeString(cx, filename_js);
+    if (filename == NULL)
         goto out;
 
     if (!g_file_get_contents(filename, &contents, &length, &error)) {
@@ -178,36 +197,43 @@ JSBool fn_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rva
     }
 
     jsstr = JS_NewStringCopyN(cx, contents, length);
-    if (!rval)
+    if (!jsstr)
         goto out;
 
-    *rval = STRING_TO_JSVAL(jsstr);
+    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(jsstr));
 
     result = JS_TRUE;
 
  out:
+    JS_free(cx, filename);
     g_free(contents);
 
     return result;
 }
 
-JSBool fn_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+JSBool fn_log(JSContext *cx, uintN argc, jsval *vp)
 {
     GString *str = g_string_new(NULL);
     uintN i;
     JSBool result = JS_FALSE;
+    jsval *argv = JS_ARGV(cx, vp);
 
-    *rval = JSVAL_VOID;
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
 
     for (i = 0; i < argc; i++) {
         JSString *jsstr = JS_ValueToString(cx, argv[i]);
+        char *encoded;
         if (!jsstr)
             goto out;
 
         if (i != 0)
             g_string_append_c(str, ' ');
 
-        g_string_append(str, JS_GetStringBytes(jsstr));
+        encoded = JS_EncodeString(cx, jsstr);
+        if (!encoded)
+            goto out;
+        g_string_append(str, encoded);
+        JS_free(cx, encoded);
     }
 
     g_printerr("%s\n", str->str);
@@ -220,9 +246,9 @@ JSBool fn_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
 }
 
 static JSFunctionSpec global_functions[] = {
-    JS_FS("include", fn_include, 1, 0, 0),
-    JS_FS("load", fn_load, 1, 0, 0),
-    JS_FS("log", fn_log, 0, 0, 0),
+    JS_FS("include", fn_include, 1, 0),
+    JS_FS("load", fn_load, 1, 0),
+    JS_FS("log", fn_log, 0, 0),
     JS_FS_END
 };
 
@@ -231,6 +257,7 @@ get_string_property(JSContext *cx, JSObject *obj, const char *property, char **o
 {
     jsval value;
     JSString *jsstr;
+    char *encoded;
 
     if (!JS_GetProperty(cx, obj, property, &value))
         return JS_FALSE;
@@ -239,7 +266,12 @@ get_string_property(JSContext *cx, JSObject *obj, const char *property, char **o
         return JS_FALSE;
 
     jsstr = JS_ValueToString(cx, value);
-    *out = g_strdup(JS_GetStringBytes(jsstr));
+    encoded = JS_EncodeString(cx, jsstr);
+    if (encoded == NULL)
+        return JS_FALSE;
+
+    *out = g_strdup(encoded);
+    g_free(encoded);
 
     return JS_TRUE;
 }
@@ -376,14 +408,13 @@ int main(int argc, const char *argv[])
         if (cx == NULL)
             return 1;
         JS_SetOptions(cx,
-                      JSOPTION_VAROBJFIX |
                       JSOPTION_DONT_REPORT_UNCAUGHT |
                       JSOPTION_STRICT);
         JS_SetVersion(cx, JSVERSION_LATEST);
         JS_SetErrorReporter(cx, reportError);
 
         /* Create the global object. */
-        global = JS_NewObject(cx, &global_class, NULL, NULL);
+        global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
         if (global == NULL)
             return 1;
 
@@ -433,7 +464,6 @@ int main(int argc, const char *argv[])
                 JSObject *exception;
                 char *stack, *filename, *lineNumber, *message;
 
-                JS_AddRoot(cx, &exception_val);
                 JS_GetPendingException(cx, &exception_val);
                 JS_ClearPendingException(cx);
 
@@ -464,11 +494,11 @@ int main(int argc, const char *argv[])
                     g_free(message);
                 } else {
                     JSString *jsstr = JS_ValueToString(cx, exception_val);
-                    g_printerr("Exception: %s\n", JS_GetStringBytes(jsstr));
+                    char *encoded = JS_EncodeString(cx ,jsstr);
+                    g_printerr("Exception: %s\n", encoded);
+                    JS_free(cx, encoded);
 
                 }
-
-                JS_RemoveRoot(cx, &exception_val);
             }
         }
         g_free(src);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]