Closed Bug 104077 Opened 23 years ago Closed 23 years ago

JS crash: with/finally/return.

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla0.9.7

People

(Reporter: chwu, Assigned: shaver)

Details

(Keywords: crash, verified1.8.1, Whiteboard: [bug 115717 is Rhino version of this])

Attachments

(21 files, 14 obsolete files)

1.92 KB, text/plain
Details
3.49 KB, text/plain
Details
2.33 KB, text/plain
Details
2.33 KB, text/plain
Details
2.12 KB, text/plain
Details
3.10 KB, text/plain
Details
778 bytes, text/plain
Details
6.75 KB, text/plain
Details
148 bytes, text/plain
Details
1.11 KB, text/plain
Details
786 bytes, text/plain
Details
375 bytes, text/plain
Details
10.72 KB, patch
Details | Diff | Splinter Review
3.87 KB, text/plain
Details
3.95 KB, text/plain
Details
15.61 KB, text/plain
Details
995 bytes, text/plain
Details
1.07 KB, text/plain
Details
983 bytes, text/plain
Details
26.37 KB, patch
jband_mozilla
: review+
shaver
: superreview+
Details | Diff | Splinter Review
182 bytes, text/plain
Details
I checked out the lastest main branch source codes from both mozilla/js and 
mozilla/nsprpub on Sun Solaris 2.6(10/09/2001), built js following the 
instructions. But if there is a return statement in the finally block inside of 
with block, js always coredump at jsinterp.c. Please help ASAP.

Thanks!


js test.js
Assertion failure: JSVAL_IS_OBJECT(rval), at jsinterp.c:1395
Abort (core dumped)


The following is the test program:




function addValues(dialog)
{
 var sum;
 with (dialog)
  {
   try
    {
      // doing something else
      sum = arg1 + arg2;
      //return sum;
    }
   finally
    {
     //Print(" sum = " + sum);
     return sum;
    }
  }
}


var i;
var _nextDialog = new Object();
_nextDialog.arg1 = 1;
_nextDialog.arg2 = 2;

i = addValues(_nextDialog);

//Print(" i = " + i);
Keywords: crash
Confirming crash in WinNT JS shell 2001-10-08. OS : Solaris --> All 

cc'ing Brendan on this one - 
Assignee: rogerl → khanson
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Solaris → All
Hardware: Sun → All
Summary: js coredump → JS crash at js_Interpret()
Ouch.  We need this in our testsuite!  Thanks, chwu.  I'll diagnose.

/be
Chingfa's testcase has been added to JS testsuite:

          mozilla/js/tests/js1_5/Regress/regress-104077.js

As reported, it crashes in both the debug and optimized SpiderMonkey shells.
Test passes in the rhino and rhinoi shells.
Attached file WinNT stack trace
This is probably my fault.  Sucky.
I crave shaver's help.  Here's the disassembly of addValues:

 HEAVYWEIGHT
main:
00000:  getvar 0
00003:  pop
00004:  getarg 0
00007:  enterwith
00008:  try
00009:  bindname "sum"
00012:  name "arg1"
00015:  name "arg2"
00018:  add
00019:  setname "sum"
00022:  popv
00023:  gosub 37 (14)
00026:  goto 46 (20)
00029:  setsp 1
00032:  gosub 37 (5)
00035:  exception
00036:  throw
00037:  finally
00038:  name "sum"
00041:  swap
00042:  leavewith
00043:  return
00044:  retsub
00045:  nop
00046:  leavewith

Source notes:
  0:     0 [   0] newline 
  1:     0 [   0] var     
  2:     4 [   4] newline 
  3:     8 [   4] newline 
  4:     8 [   0] newline 
  5:     9 [   1] newline 
  6:     9 [   0] setline  lineno 9
  8:    23 [  14] xdelta  
  9:    23 [   0] hidden  
 10:    26 [   3] hidden  
 11:    35 [   9] xdelta  
 12:    35 [   0] hidden  
 13:    36 [   1] hidden  
 14:    37 [   1] setline  lineno 13
 16:    38 [   1] setline  lineno 15
 18:    42 [   4] hidden  
 19:    45 [   3] endbrace

Exception table:
start
end
catch
  9	32	32

The dead code after bytecode 26 (goto 46) is one problem.  The lack of a setsp
before the finally can safely do its leavewith at 42 (which is where we assert
and die in jsinterp.c) is another, or could it be that the setsp is misplaced?

/be
/be
Exceptions are my baby.
Assignee: khanson → shaver
cc'ing Kenton - 
Assignee: shaver → khanson
OOPS - wrong field; try again -
Assignee: khanson → shaver
This baby better go for 0.9.6.
Status: NEW → ASSIGNED
Keywords: patch, review
Target Milestone: --- → mozilla0.9.6
Comment on attachment 54595 [details] [diff] [review]
swap-n-pop the retsub PC for non-local jumps, and misc tidying

sr=brendan@mozilla.org, much appreciated and overdue!

/be
Attachment #54595 - Flags: superreview+
Just need r= to get this in. Anyone? 
After I merged attachment 54595 [details] [diff] [review], my application does not work anymore. Finally 
I sorted out the following test program, whick did not work with the fix.

function test(a, b)
{
  var sum ;
  var i = 0;

  sum = a + b;
  while (sum < 10)
  {
    try
    {
     sum += 1;
     i += 1;
     print("sum = ", sum, "i = ", i);
    }
    finally
    {
     print("finally");
    }
  }
  return i;
}


var loop;

loop = test(1, 3);
print("loop = " , loop);
Yurk.  We're not backpatching correctly now.  I'm on it.
Comment on attachment 54595 [details] [diff] [review]
swap-n-pop the retsub PC for non-local jumps, and misc tidying

The important parts of the new patch are the new bits in these patch
stanzas: save and restore stmtInfo.catchJump so that we backpatch
correctly.

Question for reviewers: better to just store the catchJump target in a
local, and use that local as an argument to BackPatch, rather than do the
shuffling here?  Or should I use a savedStmtInfo structure and restore the
whole thing to make the reuse for STMT_SUBROUTINE undetectable outside that
block?

@@ -2935,11 +2940,14 @@
          * gosubs that might have been emitted before non-local jumps.
          */
         if (pn->pn_kid3) {
+            ptrdiff_t savedCatchJump = stmtInfo.catchJump;
             if (!BackPatch(cx, cg, &stmtInfo, stmtInfo.gosub, CG_NEXT(cg),
                            JSOP_GOSUB)) {
                 return JS_FALSE;
             }
-            js_PopStatementCG(cx, cg);
+            /* Now indicate that we're emitting a subroutine body. */
+            stmtInfo.type = STMT_SUBROUTINE;
+            SET_STATEMENT_TOP(&stmtInfo, CG_OFFSET(cg));
             if (!UpdateLinenoNotes(cx, cg, pn->pn_kid3))
                 return JS_FALSE;
             if (js_Emit1(cx, cg, JSOP_FINALLY) < 0 ||
@@ -2947,9 +2955,13 @@
                 js_Emit1(cx, cg, JSOP_RETSUB) < 0) {
                 return JS_FALSE;
             }
-        } else {
-            js_PopStatementCG(cx, cg);
+            /*
+             * Now repair catchJump, which is nuked by SET_STATEMENT_TOP.
+             * We need it for backpatching below.
+             */
+            stmtInfo.catchJump = savedCatchJump;
         }
+        js_PopStatementCG(cx, cg);
 
         if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 ||
             js_Emit1(cx, cg, JSOP_NOP) < 0) {


I also removed a dead-code JSOP_SETSP that the previous patch added before
the gosub to finally at the end of the try block: the stack had better be
balanced when we get to the end of that block, or we have problems that
JSOP_SETSP would just be papering over.

Review me, boys!
Attachment #54595 - Attachment is obsolete: true
Attachment #54595 - Flags: superreview+
Your stack trace shows an assert blowing at line 3753 of jsemit.c, which in my
patched tree is a case label (case TOK_PRIMARY).

Is your tree up-to-CVS-date?
Comment on attachment 55744 [details] [diff] [review]
repair stmtInfo.catchJump before backpatching

+            ptrdiff_t savedCatchJump = stmtInfo.catchJump;

Newline here please.

             if (!BackPatch(cx, cg, &stmtInfo, stmtInfo.gosub, CG_NEXT(cg),
                            JSOP_GOSUB)) {
                 return JS_FALSE;
             }
-            js_PopStatementCG(cx, cg);

And here, too.

+            /* Now indicate that we're emitting a subroutine body. */

I also mentioned the idea over IRC of inlining a specialized
SET_STATEMENT_TOP, which sets only the needed members -- then no need for
savedCatchJump.

/be
Attachment #55744 - Flags: needs-work+
I pushed further and found that there's no reason to set top or update in the
stmtInfo struct when changing type from STMT_FINALLY to STMT_SUBROUTINE.  What's
more, top is unused now (it once was, by an old version of the function now
called BackPatch).  shaver, bless him, is gonna eliminate JSStmtInfo.top, saving
a word per js_EmitTree stack frame.

/be
OK, I'll see your suggestion of removing JSStmtInfo.top, and raise you the
removal of the unused JSStmtInfo * parameter to BackPatch!

Now, to fix up the decompiler...
Can you give me the source to the function it's trying to decompile when it
crashes?  I'm not able to reproduce it easily here.

This one also loses the unused StmtInfo parameter to BackPatch.
Attachment #55744 - Attachment is obsolete: true
Attachment #55769 - Attachment is obsolete: true
You should file another bug about the decompiler crash, I think.
Summary: JS crash at js_Interpret() → JS crash: with/finally/return.
Comment on attachment 57229 [details] [diff] [review]
Latest fix, looking to slip into 0.9.6.

Nit: no need for multi-line condition and braces now:

-	     if (!BackPatch(cx, cg, &stmtInfo, stmtInfo.gosub, CG_NEXT(cg),
+	     if (!BackPatch(cx, cg, stmtInfo.gosub, CG_NEXT(cg),
			    JSOP_GOSUB)) {
		 return JS_FALSE;
	     }

Naughty of you not to fix the decompiler!  File that sequel bug for 0.9.7, ok? 
Or keep this one open.

sr=brendan@mozilla.org

/be
Attachment #57229 - Flags: superreview+
The decompiler is a different bug, I think, and I was hoping that Chingfa would
file it.  But I'll do that now, sure.
Sorry that I have not filed a new bug for the decompile problem, if Mike have 
not done it, I prefer do it myself.

The lastest fix does pass my test program, but I get another coredump. I will 
try to create a test case for this problem, right now I can only publish the 
core stack.

(dbx) where
current thread: t@1
  [1] __sigprocmask(0x0, 0x60946f88, 0x0, 0xffffffff, 0xffffffff, 0x0), at 0xef7
04c90
  [2] _resetsig(0xef717814, 0xef716b60, 0x0, 0x0, 0x1db544, 0x1db548), at 0xef6f
b9c8
  [3] _sigon(0xef71b600, 0xef71b5e0, 0x1db540, 0xefffc47c, 0x6, 0x1), at 0xef6fb
184
  [4] _thrp_kill(0x0, 0x1, 0x6, 0xef716b60, 0x1db4d8, 0x0), at 0xef6fdec0
  [5] abort(0xef6a563c, 0x53, 0xef6ace3c, 0xef6a8fa8, 0x58a, 0x0), at 0xef63b328
=>[6] JS_Assert(s = 0x19fe80 "OBJ_GET_CLASS(cx, withobj) == &js_WithClass", file
 = 0x19feac "jsinterp.c", ln = 1418), line 174 in "jsutil.c"
  [7] js_Interpret(cx = 0x1e1208, result = 0xefffc988), line 1418 in "jsinterp.c
"
  [8] js_Invoke(cx = 0x1e1208, argc = 3U, flags = 0), line 849 in "jsinterp.c"
  [9] js_Interpret(cx = 0x1e1208, result = 0xefffdef8), line 2791 in "jsinterp.c
"
  [10] js_Execute(cx = 0x1e1208, chain = 0x1e2b40, script = 0x293d58, down = (ni
l), special = 0, result = 0xefffdef8), line 1012 in "jsinterp.c"
  [11] JS_ExecuteScript(cx = 0x1e1208, obj = 0x1e2b40, script = 0x293d58, rval =
 0xefffdef8), line 3263 in "jsapi.c"
  [12] Process(cx = 0x1e1208, obj = 0x1e2b40, filename = 0xefffe2a7 "ftappEvent.
jsv"), line 407 in "js.c"
  [13] ProcessArgs(cx = 0x1e1208, obj = 0x1e2b40, argv = 0xefffe080, argc = 1),
line 607 in "js.c"
  [14] main(argc = 1, argv = 0xefffe080), line 2268 in "js.c"

First, I have to take back my last comment, apparently the latest fix does not 
fix the coredump in attachment 55929 [details].

More urgent problem related to the with statment, the test program is as 
follows:

function mytest(_doc)
{
var document = new Object();
var _ex;
var _arg;

with (document)
 {
  _arg = (_doc != null) ? "application" : "document";
  print("_arg = " + _arg);

  try
   {
     throw "test";
   }
  catch (_ex)
   {
     print("exception = " + _ex);
   }
 }
}
print(0);
mytest(null);
print(1);


Notice that if we took out the with statement, no coredump. If we took out 
the ?: statement, no coredump. If we took out the try block, no coredump.
Son of a spidermonkey.

I'm sick right now, but I'll print some jsemit.c and sit in bed with them for a
bit.  I fear we're going to miss 0.9.6, unless nyquil inspires me more than is
its habit.
Keywords: patch, review
Target Milestone: mozilla0.9.6 → mozilla0.9.7
Chingfa's recent examples added to testcase in JS testsuite:

          mozilla/js/tests/js1_5/Regress/regress-104077.js 

Note: the example at Comment 35 crashes in the current JS debug shell
on WinNT (no patches from this bug applied). It does not crash in 
the optimized JS shell.
I know this is not the place to ask this question, but YOU are the ONLY experts 
that can provide the info I am looking for.

I'd like to get familiar with js interpreter source code. Becides the public 
API reference, the guide and the tutorial, is there any other document 
available, especially those about how js script gets to be compiled? THANKS!

There isn't really any documentation other than the source, sadly.

I (finally, heh) looked at this again today, and found that if I change the ?:
to an explicit if-else, it works.

In the if-else case, the stack depth is 1 (correct) when we start generating the
try block, but in the ?: case the stack depth is 2 (incorrect) when we start
generating the try block.  This leads to the JSOP_SETSP resetting the stack
depth to the wrong value when we hit the catch block, and much hilarity ensues.

I'll look more at that codegen path in a bit.
Yeah, this looks like an old, old bug.  Both branches of the ?: expression
produce a value, and that means that we adjust cg->stackDepth upwards by two
when emitting the expression.  But execution will only take one path, so the
real stackDepth is one lower, and that's where our SETSP woes come from.

with-hook-try combinations have always been busted, and I wonder if there aren't
other such combinations lurking.  I couldn't find any, but then I didn't see
this back in 1999 either.

I'm going to merge in brendan's decompiler wizardry and post a new patch this
afternoon.  (Been up all night, because I'm stupid.)

Phil, I'll send along a minimal test case sample, in hopes that you can add it
to the test suite.

Brendan: does anything other than JSOP_SETSP generation for exceptions depend on
the accuracy of cg->stackDepth's value?
FWIW, none of the attached test cases do anything unexpected for me anymore. 
Dare I dream that this is The One?
Attachment #57229 - Attachment is obsolete: true
Attachment #57251 - Attachment is obsolete: true
shaver and I chatted via IRC and I believe we have a fix for chingfa's latest
testcase.  Shaver'll attach it soon, I bet (and I hope he changes "net-produce a
value" in that TOK_HOOK comment to "push a single value", after changing the if
(--cg->stackDepth < 0) {...} to a JS_ASSERT(cg->stackDepth >= 2);
cg->stackDepth--; sequence :-).

/be
I can now run 59359.  Chingfa, hit me again!

(The thing brendan and I talked about in IRC wasn't a fix, it turned out. 
Alas.)
Attachment #59347 - Attachment is obsolete: true
Attached file The coredump trace
Mike, really APPRECIATED your swift response, THANK YOU VERY MUCH. Your latest
fix does fix my all testcases.	However, one of our application is still
coredump in the same place seems due to the same season. I will try to get
another test case for this problem. Right now I have problem to figure out
where the coredump happened in my js scripts, could you please tell me how I
can figure it out? Thanks!
No, thank _you_ for your excellent test cases, exposing years of bogusness in my
exception code. =)

From js_Interpret, looking at "*script" and "(pc - script->code)" should tell us
enough to see what line it's crashing on, and of what script.
w/ and w/o attachment 59568 [details] [diff] [review] this crashes xpcshell:
try {throw new A()}catch(e){}finally {try {throw new A()}catch(e){}finally
{print("a")}print("a")}

should i file a new bug?
No, just attach the test case here so we don't forget to add it to the set.

*sigh*
Attached file decompiler error
As I said before, one of my application is still coredump, I try to figure out
a testcase for this one but have not got it yet. In this application, there is
no return stmtment in finaly block, no conditional operator(use if-else
instead), only an exception travels through many functions in many files. In
the way to search for it, I find your lastest fix has introduced a decompiler
error(see the attached testcase). Sorry about it, Mike.
Attached file bug with js
Nothing is special about this testcase as I said before, but js is coredump.
Notice that without with statement, no coredump, if the exception is thrown in
if block, no coredump. 

Although the place that our appication is curedump is different from the
testcase, hope they are caused by the same reason. 

Mike, could you please treat this one as higher priority than others? Thanks!
function testfunc()
{
 var document = new Object();
 with (document)
  {
   var _nextDialog = 100;
   var _doc = "abc" ;
   //var _doc = null ;

   if (_doc == null)
    {
     try
      {
       throw "authentication.0";
      }
     catch (_ex)
      {
      }
     finally
      {
      }
     return _nextDialog;
    }
   else
    {
     try
      {
        throw "authentication.0";
        //mytest();
      }
     catch (_ex)
      {
      }
     finally
      {
      }
     return _nextDialog;
    }
  }
}

var abc = testfunc();


A simpler testcase for the attach 59900. Notice if I comment throw and 
uncomment mytest(), js is also coredump.
No need to apologize.  I think I've found one part of the problem (SETSP is
using an incorrect stack depth), but I haven't figured out why yet.

Something must come of this bug over this weekend.  Thanks for the test cases,
Chingfa!
Attached patch Take that, Chingfa's test cases! (obsolete) — Splinter Review
Brendan found that I was only adjusting cg->stackDepth half as often as I
should have been, and I can now run all your deviant JS code from the shell.

Haven't looked at the decompiler error, yet.

Next!
Attachment #59568 - Attachment is obsolete: true
Chingfa's and timeless' recent examples added to testcase in JS testsuite:

          mozilla/js/tests/js1_5/Regress/regress-104077.js 


Note: to run the test without using the Perl test driver, just do this:

[//d/JS_TRUNK/mozilla/js/src/WINNT4.0_DBG.OBJ] ./js
js> load('../../tests/js1_5/shell.js')
js> load('../../tests/js1_5/Regress/regress-104077.js')
Chingfa's latest example added to testcase in JS testsuite:

          mozilla/js/tests/js1_5/Regress/regress-104077.js 

This now contains 7 of his examples, plus the one from timeless above. 
This testcase is currently passing in the rhino, rhinoi shells. 

I'd like to report how the patch in Comment #54 is doing on this,
bug I'm having NO LUCK in applying the patch either on WinNT or Linux. 
I get errors like this:

[ ] patch < 104077_59920.patch
patching file `js.c'
Hunk #1 succeeded at 1123 (offset -3 lines).
patching file `jsemit.c'
Hunk #1 succeeded at 324 (offset -865 lines).
Hunk #2 FAILED at 336.
Hunk #4 succeeded at 412 (offset -865 lines).
Hunk #5 FAILED at 430.
Hunk #6 FAILED at 479.
         etc.
         etc.
Testing and review needed.  Feel free to diff against the last posted patch (I
hope I based my work off that!).

/be
Yes, my patch was based on shaver's last one.

/be
Attachment #59920 - Attachment is obsolete: true
Attachment #60440 - Attachment is obsolete: true
Just like reiterating that the lastest attach have introduced a bug.

function entry_menu()
{
 var document = new Object();
 var dialog = new Object();
 var _nextDialog = 100;

 with (document)
  {
   //var dialog = new Object();
   with (dialog)
    {
     try
      {
       while (true)
        {
          return _nextDialog;
        }
      }
     finally
      {
      }
    }
  }
}

var abc;
abc = entry_menu();
//Print ("abc = " + abc);

Attachment #60466 - Attachment is obsolete: true
We don't need JSOP_SWAP now that we have JSOP_SETRVAL/JSOP_RETRVAL.  Either we
need the latter pair, with properly interleaved fixup ops (LEAVEWITH, POP2,
POP) and GOSUBs, for return-from-try-with-finally; or we aren't returning from
a try with a finally clause, so we can simply JSOP_RETURN and let the non-empty
stack die when its frame is popped.

/be
Attachment #60532 - Attachment is obsolete: true
Is the patch above (id=60704) self-contained? I would like to run the
testsuite against it, but I'm not sure if I have to apply one of the
previous patches first. Thanks - 
The comment in JSOP_FINALLY's case code in Decompile lied, referring to the
now-unused JSOP_SWAP opcode.

/be
Boy, talk about compensating fudge terms!  As I read the jsopcode.c
comments-only patch, the inconsistency of the decompiler's JSOP_SETSP case
leapt out at me.  The comment there babbled happily about how the decompiler
must adapt the code generator's stack depth model by subtracting the number of
open finally clauses, yet just above this comment, JSOP_FINALLY and JSOP_RETSUB
push and pop a cookie on the decompiler's string stack!  This cookie stands in
for the return address pushed by one or more JSOP_GOSUBs that call the
finally-clause subroutine.

So the adapting subtraction of ss->finallyLevel from the JSOP_SETSP operand
(which the code generator computed based on its model) must have been wrong. 
But removing it lead to string stack imbalance.  Therefore, I reviewed the code
in jsemit.c that generates catch and finally bytecode, and found that it had a
fudging adjustment upward of cg->stackDepth in two places, just before emitting
hidden JSOP_LEAVEWITHs.  The second LEAVEWITH was preceded in straight-line
fashion by an ENTERWITH, so the second fudge of cg->stackDepth was clearly
wrong.	Removing it still didn't save me, because the finally-clause code
generator failed to bump and (here a max computation is necessary; elsewhere it
can be asserted that the max is big enough already) compute the max stack depth
to include space for the JSOP_RETSUB return address.

I still wasn't out of the woods, because there was squirrelly code in the
try-catches-with-guards-only-[optional-finally] case that sets the last
(guarded) catch's JSOP_IFEQ jump offset to target rethrow code.  In this odd
case of guarded-only catch clauses, the last catch clause's scope object is not
modeled as on-stack, so we need to bump cg->stackDepth and emit a LEAVEWITH. 
The logic here was strange: it would set the jump offset for the weird case,
but it would emit the LEAVEWITH if *any* catch clauses (guarded or not) were
present -- and that would be bad for try-catch[noguards]-finally, which runs
through the same rethrow-generating logic and which would trigger a spurious
LEAVEWITH generation.

Testcases with catch-with-guard and two-catches-with-guards, based on chingfa's
testcase, coming up.

/be
Attachment #60704 - Attachment is obsolete: true
Attachment #60760 - Attachment is obsolete: true
The point about these testcases is that they add try-catch[with-guard]-finally
in a finally clause, which tests whether the compiler and decompiler stack
models agree.  There's a simpler testcase that adds a guard-free
try-catch-finally in the finally clause of chingfa's testcase, I'll attach that
next.

/be
attachment 60774 [details] [diff] [review] is the complete patch to apply, test, pour, nose, sip, savor,
and swallow!

/be
Brendan's recent examples added to testcase in JS testsuite:

          mozilla/js/tests/js1_5/Regress/regress-104077.js 

This testcase now contains a total of 11 different scenarios.


Attachment 60774 [details] [diff] tested out well on my WinNT box. No regressions
were introduced by the patch, and the testcase for this bug ran
without crashing, and passed, to boot. I'm getting one crazy 
date test failure, but it has nothing to do with the patch: 
I'm getting it with the unpatched engine as well. Will investigate.


One thing I don't understand: the last three test scenarios
all have:

function addValues(dialog)
{
  var sum = 0;
  with (dialog)
  {
    try
    {
      sum = arg1 + arg2;
      with (arg3)
      {
        while (sum < 10)
        {
          try 
          {
            if (sum > 5)
              return sum;
            sum += 1;
          }

             etc.



Now, sum increments up to 6 in each scenario, where I would have thought
the return statement would cause function execution to terminate.
Yet it doesn't; control passes to the finally block later on. 

Is that the way it's supposed to be? I thought ECMA specified that
a return statement causes function execution to terminate. 
finally trumps return, and all other control-flow constructs that cause program
execution to jump out of the try block: throw, break, etc.  Once you enter a try
block, you will execute the finally block after leaving the try, regardless of
what happens to make you leave the try.
Old bug, caught it when reviewing the patch.  The "rethrow exception after
gosub finally" code that's emitted right after a try block's closing goto
around the catch and/or finally clauses, which is also hooked up via the last
catch's ifeq jump offset if all catches are guarded, begins with a JSOP_SETSP. 
But alas, the long-standing code did not update its finallyCatch local to
capture the pc offset of this setsp, so something like the next testcase could
overflow the stack in its finally clause.

/be
Attachment #60774 - Attachment is obsolete: true
Brendan's latest example added to testcase in JS testsuite:

          mozilla/js/tests/js1_5/Regress/regress-104077.js
Comment on attachment 60893 [details] [diff] [review]
last patch, but with jsemit.c fix to set finallyCatch before emitting SETSP

I like it.  Assuming that it passes the Chingfa Test, sr=shaver.  Thanks a ton,
/be.
Attachment #60893 - Flags: superreview+
The lastest fix is great, it has passed all my testcases, and passed the 
applications that were crashed before.

Great job, thanks to all of you! Cheer!  --From Chingfa Wu
 
On WinNT, I have also had luck with the latest patch (id=60893):
In both the debug and optimized JS shell, the testcase for this bug
passed, and no new regressions were introduced by the patch.
I can't seem to get an r= yet from the people I've asked, but I'm going to check
this in today (and not at the last minute).  Grumble.  Maybe I can cite
r=chingfa if he's read the patch and understands it to some extent?

/be
Comment on attachment 60893 [details] [diff] [review]
last patch, but with jsemit.c fix to set finallyCatch before emitting SETSP

r=jband
Attachment #60893 - Flags: review+
Fix is in, thanks all, esp. chingfa for the great testing, shaver for the tag
teaming, and jband for the last minute r=.

/be
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Verified FIXED.

Using JS source pulled at 5PM PST today, the above testcase passes
in the debug, optimized JS shells built on WinNT, Linux, and Mac9.1.
Status: RESOLVED → VERIFIED
Whiteboard: [bug 115717 is Rhino version of this]
Flags: testcase+
fixed by Bug 336373 on the 1.8.1 branch. 
verified fixed 1.8.1 with windows/macppc/linux 20060707
Keywords: verified1.8.1
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: