michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "js/OldDebugAPI.h" michael@0: #include "jsapi-tests/tests.h" michael@0: michael@0: static int emptyTrapCallCount = 0; michael@0: michael@0: static JSTrapStatus michael@0: EmptyTrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, michael@0: jsval closureArg) michael@0: { michael@0: JS::RootedValue closure(cx, closureArg); michael@0: JS_GC(JS_GetRuntime(cx)); michael@0: if (JSVAL_IS_STRING(closure)) michael@0: ++emptyTrapCallCount; michael@0: return JSTRAP_CONTINUE; michael@0: } michael@0: michael@0: BEGIN_TEST(testTrap_gc) michael@0: { michael@0: static const char source[] = michael@0: "var i = 0;\n" michael@0: "var sum = 0;\n" michael@0: "while (i < 10) {\n" michael@0: " sum += i;\n" michael@0: " ++i;\n" michael@0: "}\n" michael@0: "({ result: sum });\n" michael@0: ; michael@0: michael@0: // compile michael@0: JS::CompileOptions options(cx); michael@0: options.setFileAndLine(__FILE__, 1); michael@0: JS::RootedScript script(cx, JS_CompileScript(cx, global, source, michael@0: strlen(source), options)); michael@0: CHECK(script); michael@0: michael@0: // execute michael@0: JS::RootedValue v2(cx); michael@0: CHECK(JS_ExecuteScript(cx, global, script, &v2)); michael@0: CHECK(v2.isObject()); michael@0: CHECK_EQUAL(emptyTrapCallCount, 0); michael@0: michael@0: // Enable debug mode michael@0: CHECK(JS_SetDebugMode(cx, true)); michael@0: michael@0: static const char trapClosureText[] = "some trap closure"; michael@0: michael@0: // scope JSScript usage to make sure that it is not used after michael@0: // JS_ExecuteScript. This way we avoid using Anchor. michael@0: JS::RootedString trapClosure(cx); michael@0: { michael@0: jsbytecode *line2 = JS_LineNumberToPC(cx, script, 1); michael@0: CHECK(line2); michael@0: michael@0: jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5); michael@0: CHECK(line2); michael@0: michael@0: trapClosure = JS_NewStringCopyZ(cx, trapClosureText); michael@0: CHECK(trapClosure); michael@0: JS::RootedValue closureValue(cx, JS::StringValue(trapClosure)); michael@0: JS_SetTrap(cx, script, line2, EmptyTrapHandler, closureValue); michael@0: JS_SetTrap(cx, script, line6, EmptyTrapHandler, closureValue); michael@0: michael@0: JS_GC(rt); michael@0: michael@0: CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText)); michael@0: } michael@0: michael@0: // execute michael@0: CHECK(JS_ExecuteScript(cx, global, script, &v2)); michael@0: CHECK_EQUAL(emptyTrapCallCount, 11); michael@0: michael@0: JS_GC(rt); michael@0: michael@0: CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText)); michael@0: michael@0: return true; michael@0: } michael@0: END_TEST(testTrap_gc) michael@0: