8 #ifdef MOZ_TRACE_JSCALLS
11 static int enters = 0;
12 static int leaves = 0;
13 static int interpreted = 0;
16 funcTransition(const JSFunction *,
24 if (! JS_ON_TRACE(cx))
32 static JSBool called2 = false;
35 funcTransition2(const JSFunction *, const JSScript*, const JSContext*, int)
40 static int overlays = 0;
41 static JSFunctionCallback innerCallback = NULL;
43 funcTransitionOverlay(const JSFunction *fun,
44 const JSScript *script,
48 (*innerCallback)(fun, script, cx, entering);
53 BEGIN_TEST(testFuncCallback_bug507012)
55 #ifdef MOZ_TRACE_JSCALLS
56 // Call funcTransition() whenever a Javascript method is invoked
57 JS_SetFunctionCallback(cx, funcTransition);
59 EXEC("x = 0; function f (n) { if (n > 1) { f(n - 1); } }");
60 interpreted = enters = leaves = depth = 0;
62 // Check whether JS_Execute() tracking works
64 CHECK(enters == 1 && leaves == 1 && depth == 0);
65 interpreted = enters = leaves = depth = 0;
67 // Check whether the basic function tracking works
69 CHECK(enters == 1+1 && leaves == 1+1 && depth == 0);
71 // Can we switch to a different callback?
73 JS_SetFunctionCallback(cx, funcTransition2);
75 CHECK(called2 && enters == 777);
77 // Check whether we can turn off function tracing
78 JS_SetFunctionCallback(cx, NULL);
81 interpreted = enters = leaves = depth = 0;
83 // Check nested invocations
84 JS_SetFunctionCallback(cx, funcTransition);
85 enters = leaves = depth = 0;
87 CHECK(enters == 1+3 && leaves == 1+3 && depth == 0);
88 interpreted = enters = leaves = depth = 0;
90 // Check calls invoked while running on trace
91 EXEC("function g () { ++x; }");
92 interpreted = enters = leaves = depth = 0;
93 EXEC("for (i = 0; i < 50; ++i) { g(); }");
94 CHECK(enters == 1+50 && leaves == 1+50 && depth == 0);
96 // If this fails, it means that the code was interpreted rather
97 // than trace-JITted, and so is not testing what it's supposed to
98 // be testing. Which doesn't necessarily imply that the
99 // functionality is broken.
101 if (TRACING_ENABLED(cx))
102 CHECK(interpreted < enters);
105 // Test nesting callbacks via JS_GetFunctionCallback()
106 JS_SetFunctionCallback(cx, funcTransition);
107 innerCallback = JS_GetFunctionCallback(cx);
108 JS_SetFunctionCallback(cx, funcTransitionOverlay);
110 EXEC("x = 0; function f (n) { if (n > 1) { f(n - 1); } }");
111 interpreted = enters = leaves = depth = overlays = 0;
117 CHECK(overlays == enters + leaves);
118 interpreted = enters = leaves = depth = overlays = 0;
124 // Not strictly necessary, but part of the test attempts to check
125 // whether these callbacks still trigger when traced, so force
126 // JSOPTION_JIT just to be sure. Once the method jit and tracing jit
127 // are integrated, this'll probably have to change (and we'll probably
128 // want to test in all modes.)
130 JSContext *createContext()
132 JSContext *cx = JSAPITest::createContext();
134 JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT);
138 END_TEST(testFuncCallback_bug507012)