michael@0: // getLineOffsets works with extended instructions, such as JSOP_GOTOX. michael@0: michael@0: var g = newGlobal(); michael@0: g.line0 = null; michael@0: var dbg = Debugger(g); michael@0: var where; michael@0: dbg.onDebuggerStatement = function (frame) { michael@0: var s = frame.script; michael@0: var offs; michael@0: var lineno = g.line0 + where; michael@0: offs = s.getLineOffsets(lineno); michael@0: for (var i = 0; i < offs.length; i++) { michael@0: assertEq(s.getOffsetLine(offs[i]), lineno); michael@0: s.setBreakpoint(offs[i], {hit: function (frame) { g.log += 'B'; }}); michael@0: } michael@0: g.log += 'A'; michael@0: }; michael@0: michael@0: function test(s) { michael@0: assertEq(s.charAt(s.length - 1) !== '\n', true); michael@0: var count = s.split(/\n/).length; // number of lines in s michael@0: g.i = 0; michael@0: g.log = ''; michael@0: where = 1 + count; michael@0: g.eval("line0 = Error().lineNumber;\n" + michael@0: "debugger;\n" + // line0 + 1 michael@0: s + // line0 + 2 ... line0 + where michael@0: " log += 'C';\n"); michael@0: assertEq(g.log, 'ABC'); michael@0: } michael@0: michael@0: function repeat(s) { michael@0: return Array((1 << 14) + 1).join(s); // 16K copies of s michael@0: } michael@0: var long_expr = "i" + repeat(" + i"); michael@0: var long_throw_stmt = "throw " + long_expr + ";\n"; michael@0: michael@0: // long break (JSOP_GOTOX) michael@0: test("for (;;) {\n" + michael@0: " if (i === 0)\n" + michael@0: " break;\n" + michael@0: " " + long_throw_stmt + michael@0: "}"); michael@0: michael@0: // long continue (JSOP_GOTOX) michael@0: test("do {\n" + michael@0: " if (i === 0)\n" + michael@0: " continue;\n" + michael@0: " " + long_throw_stmt + michael@0: "} while (i !== 0);"); michael@0: michael@0: // long if consequent (JSOP_IFEQX) michael@0: test("if (i === 2) {\n" + michael@0: " " + long_throw_stmt + michael@0: "}"); michael@0: michael@0: // long catch-block with finally (JSOP_GOSUBX) michael@0: test("try {\n" + michael@0: " i = 0;\n" + michael@0: "} catch (exc) {\n" + michael@0: " throw " + long_expr + ";\n" + michael@0: "} finally {\n" + michael@0: " i = 1;\n" + michael@0: "}"); michael@0: michael@0: // long case (JSOP_TABLESWITCHX) michael@0: test("switch (i) {\n" + michael@0: " default:\n" + michael@0: " case 1: " + long_throw_stmt + michael@0: " case 0: i++; }"); michael@0: michael@0: test("switch (i) {\n" + michael@0: " case 1: case 2: case 3: " + long_throw_stmt + michael@0: " default: i++; }"); michael@0: michael@0: // long case (JSOP_LOOKUPSWITCHX) michael@0: test("switch ('' + i) {\n" + michael@0: " default:\n" + michael@0: " case '1': " + long_throw_stmt + michael@0: " case '0': i++; }"); michael@0: michael@0: test("switch (i) {\n" + michael@0: " case '1': case '2': case '3': " + long_throw_stmt + michael@0: " default: i++; }"); michael@0: michael@0: // long case or case-expression (JSOP_CASEX) michael@0: test("switch (i) {\n" + michael@0: " case i + 1 - i:\n" + michael@0: " default:\n" + michael@0: " " + long_throw_stmt + michael@0: " case i + i:\n" + michael@0: " i++; break; }"); michael@0: michael@0: // long case when JSOP_CASE is used (JSOP_DEFAULTX) michael@0: test("switch (i) {\n" + michael@0: " case i + 1 - i:\n" + michael@0: " " + long_throw_stmt + michael@0: " default:\n" + michael@0: " i++; break; }");