Bug 433529: Part 5 - Add jit-tests for the displayAtom() attribute of functions. r=jimb
authorAlex Crichton <acrichton@mozilla.com>
Sat, 18 Aug 2012 21:31:45 -0700
changeset 105150 d26a8e451fa2526e011de1ac6b77cd396bc81814
parent 105149 234d99170fbf1079c4561900e836d60f9e50f4df
child 105151 6735faf4d313655951b1557775e3c3da4439407c
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersjimb
bugs433529
milestone17.0a1
Bug 433529: Part 5 - Add jit-tests for the displayAtom() attribute of functions. r=jimb
js/src/builtin/TestingFunctions.cpp
js/src/jit-test/tests/basic/functionnames.js
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -750,16 +750,32 @@ EnableSPSProfilingAssertions(JSContext *
     SetRuntimeProfilingStack(cx->runtime, stack, &stack_size, 1000);
     cx->runtime->spsProfiler.enableSlowAssertions(args[0].toBoolean());
     cx->runtime->spsProfiler.enable(true);
 
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
+static JSBool
+DisplayName(JSContext *cx, unsigned argc, jsval *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if (argc == 0 || !args[0].isObject() || !args[0].toObject().isFunction()) {
+        RootedObject arg(cx, &args.callee());
+        ReportUsageError(cx, arg, "Must have one function argument");
+        return false;
+    }
+
+    JSFunction *fun = args[0].toObject().toFunction();
+    JSString *str = fun->displayAtom();
+    vp->setString(str == NULL ? cx->runtime->emptyString : str);
+    return true;
+}
+
 static JSFunctionSpecWithHelp TestingFunctions[] = {
     JS_FN_HELP("gc", ::GC, 0, 0,
 "gc([obj] | 'compartment')",
 "  Run the garbage collector. When obj is given, GC only its compartment.\n"
 "  If 'compartment' is given, GC any compartments that were scheduled for\n"
 "  GC via schedulegc."),
 
     JS_FN_HELP("gcparam", GCParameter, 2, 0,
@@ -863,16 +879,22 @@ static JSFunctionSpecWithHelp TestingFun
 
     JS_FN_HELP("enableSPSProfilingAssertions", EnableSPSProfilingAssertions, 1, 0,
 "enableSPSProfilingAssertions(slow)",
 "  Enables SPS instrumentation and corresponding assertions. If 'slow' is\n"
 "  true, then even slower assertions are enabled for all generated JIT code.\n"
 "  When 'slow' is false, then instrumentation is enabled, but the slow\n"
 "  assertions are disabled."),
 
+    JS_FN_HELP("displayName", DisplayName, 1, 0,
+"displayName(fn)",
+"  Gets the display name for a function, which can possibly be a guessed or\n"
+"  inferred name based on where the function was defined. This can be\n"
+"  different from the 'name' property on the function."),
+
     JS_FS_HELP_END
 };
 
 namespace js {
 
 bool
 DefineTestingFunctions(JSContext *cx, HandleObject obj)
 {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/functionnames.js
@@ -0,0 +1,116 @@
+/*
+ * Most of these test cases are adapted from:
+ * http://johnjbarton.github.com/nonymous/index.html
+ */
+
+function assertName(fn, name) {
+    assertEq(displayName(fn), name)
+}
+
+/* simple names */
+var a = function b() {};
+function c() {};
+assertName(a, 'b');
+assertName(c, 'c');
+
+var a = function(){},
+    b = function(){};
+assertName(a, 'a');
+assertName(b, 'b');
+
+/* nested names */
+var main = function() {
+    function Foo(a) { assertName(a, 'main/foo<') }
+    var foo = new Foo(function() {});
+};
+assertName(main, 'main')
+main();
+
+/* duplicated */
+var Baz = Bar = function(){}
+assertName(Baz, 'Bar');
+assertName(Bar, 'Bar');
+
+/* returned from an immediate function */
+var Foo = function (){
+    assertName(arguments.callee, 'Foo<')
+    return function(){};
+}();
+assertName(Foo, 'Foo');
+
+/* various properties and such */
+var x = {fox: { bax: function(){} } };
+assertName(x.fox.bax, 'x.fox.bax');
+var foo = {foo: {foo: {}}};
+foo.foo.foo = function(){};
+assertName(foo.foo.foo, 'foo.foo.foo');
+var z = {
+    foz: function() {
+             var baz = function() {
+                 var y = {bay: function() {}};
+                 assertName(y.bay, 'z.foz/baz/y.bay');
+             };
+             assertName(baz, 'z.foz/baz');
+             baz();
+         }
+};
+assertName(z.foz, 'z.foz');
+z.foz();
+
+var outer = function() {
+    x.fox.bax.nx = function(){};
+    var w = {fow: { baw: function(){} } };
+    assertName(x.fox.bax.nx, 'outer/x.fox.bax.nx')
+    assertName(w.fow.baw, 'outer/w.fow.baw');
+};
+assertName(outer, 'outer');
+outer();
+function Fuz(){};
+Fuz.prototype = {
+  add: function() {}
+}
+assertName(Fuz.prototype.add, 'Fuz.add');
+
+var x = 1;
+x = function(){};
+assertName(x, 'x');
+
+var a = {b: {}};
+a.b.c = (function() {
+    assertName(arguments.callee, 'a.b.c<')
+}());
+
+a.b = function() {
+    function foo(f) { assertName(f, 'a.b/<'); };
+    return foo(function(){});
+}
+a.b();
+
+var bar = 'bar';
+a.b[bar] = function(){};
+assertName(a.b.bar, 'a.b[bar]');
+
+a.b = function() {
+    assertName(arguments.callee, 'a.b<');
+    return { a: function() {} }
+}();
+assertName(a.b.a, 'a.b.a');
+
+a = {
+    b: function(a) {
+        if (a)
+            return function() {};
+        else
+            return function() {};
+    }
+};
+assertName(a.b, 'a.b');
+assertName(a.b(true), 'a.b/<')
+assertName(a.b(false), 'a.b/<')
+
+function f(g) {
+    assertName(g, 'x<');
+    return g();
+}
+var x = f(function () { return function() {}; });
+assertName(x, 'x</<');