Bug 721611 - evalWithLocation, r=Waldo
authorDave Herman <dherman@mozilla.com>
Thu, 26 Jan 2012 11:26:59 -0500
changeset 86709 8d39654512d58e9990035f3e7e60f2a4c9bbfb70
parent 86708 e7142decacd5b7ffec3fb2d4f027f4c71ff64903
child 86710 40f3a8423c893a41232f9c88af2c33482444f837
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs721611
milestone12.0a1
Bug 721611 - evalWithLocation, r=Waldo
js/src/shell/js.cpp
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -780,16 +780,69 @@ Load(JSContext *cx, uintN argc, jsval *v
             return false;
     }
 
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static JSBool
+EvaluateWithLocation(JSContext *cx, uintN argc, jsval *vp)
+{
+    if (argc != 3) {
+        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
+                             argc > 3 ? JSSMSG_TOO_MANY_ARGS : JSSMSG_NOT_ENOUGH_ARGS,
+                             "evalWithLocation");
+        return false;
+    }
+
+    JSString *code = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
+    if (!code)
+        return false;
+    JS::Anchor<JSString *> a_code(code);
+
+    size_t codeLength;
+    const jschar *codeChars = JS_GetStringCharsAndLength(cx, code, &codeLength);
+    if (!codeChars)
+        return false;
+
+    JSString *filename = JS_ValueToString(cx, JS_ARGV(cx, vp)[1]);
+    if (!filename)
+        return false;
+
+    uint32_t lineno;
+    if (!JS_ValueToECMAUint32(cx, JS_ARGV(cx, vp)[2], &lineno))
+        return false;
+
+    JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
+    if (!thisobj)
+        return false;
+
+    if ((JS_GET_CLASS(cx, thisobj)->flags & JSCLASS_IS_GLOBAL) != JSCLASS_IS_GLOBAL) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
+                             "this-value passed to evalWithLocation()", "not a global object");
+        return false;
+    }
+
+    char *filenameBytes = JS_EncodeString(cx, filename);
+    if (!filenameBytes)
+        return false;
+
+    jsval rval;
+    bool ok = JS_EvaluateUCScript(cx, thisobj, codeChars, codeLength, filenameBytes, lineno, &rval);
+    JS_free(cx, filenameBytes);
+
+    if (!ok)
+        return false;
+
+    JS_SET_RVAL(cx, vp, rval);
+    return true;
+}
+
+static JSBool
 Evaluate(JSContext *cx, uintN argc, jsval *vp)
 {
     if (argc != 1 || !JSVAL_IS_STRING(JS_ARGV(cx, vp)[0])) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
                              (argc != 1) ? JSSMSG_NOT_ENOUGH_ARGS : JSSMSG_INVALID_ARGS,
                              "evaluate");
         return false;
     }
@@ -3924,16 +3977,17 @@ Terminate(JSContext *cx, uintN arg, jsva
 }
 
 static JSFunctionSpec shell_functions[] = {
     JS_FN("version",        Version,        0,0),
     JS_FN("revertVersion",  RevertVersion,  0,0),
     JS_FN("options",        Options,        0,0),
     JS_FN("load",           Load,           1,0),
     JS_FN("evaluate",       Evaluate,       1,0),
+    JS_FN("evalWithLocation", EvaluateWithLocation, 3,0),
     JS_FN("run",            Run,            1,0),
     JS_FN("readline",       ReadLine,       0,0),
     JS_FN("print",          Print,          0,0),
     JS_FN("printErr",       PrintErr,       0,0),
     JS_FN("putstr",         PutStr,         0,0),
     JS_FN("dateNow",        Now,            0,0),
     JS_FN("help",           Help,           0,0),
     JS_FN("quit",           Quit,           0,0),
@@ -4019,16 +4073,18 @@ static const char shell_help_header[] =
 "=======                  ===========\n";
 
 static const char *const shell_help_messages[] = {
 "version([number])        Get or force a script compilation version number",
 "revertVersion()          Revert previously set version number",
 "options([option ...])    Get or toggle JavaScript options",
 "load(['foo.js' ...])     Load files named by string arguments",
 "evaluate(code)           Evaluate code as though it were the contents of a file",
+"evalWithLocation(code, filename, lineno)\n"
+"  Eval code as if loaded from the given filename and line number",
 "run('foo.js')\n"
 "  Run the file named by the first argument, returning the number of\n"
 "  of milliseconds spent compiling and executing it",
 "readline()               Read a single line from stdin",
 "print([exp ...])         Evaluate and print expressions to stdout",
 "printErr([exp ...])      Evaluate and print expressions to stderr",
 "putstr([exp])            Evaluate and print expression without newline",
 "dateNow()                    Return the current time with sub-ms precision",