Closed
Bug 320887
Opened 19 years ago
Closed 9 years ago
|var x| can throw a ReferenceError
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
DUPLICATE
of bug 1217099
People
(Reporter: mrbkap, Unassigned)
References
()
Details
Attachments
(1 file, 2 obsolete files)
4.28 KB,
patch
|
Details | Diff | Splinter Review |
STEPS TO REPRODUCE: 1. Try the testcase in the URL field. 2. Note that there is a JavaScript exception. Shutdown pointed out in bug 320172 comment 13 that this is incorrect behavior, per ECMA. We're failing because we emit a JSOP_NAME bytecode for the decompiler, and the lookup fails.
Comment 1•19 years ago
|
||
Checking in regress-320887.js; /cvsroot/mozilla/js/tests/js1_6/Array/regress-320887.js,v <-- regress-320887.js initial revision: 1.1
Flags: testcase+
Comment 2•19 years ago
|
||
note to self: this crashes the 1.8 branch with top 'o stack: Variables(JSContext * 0x03a4a818, JSTokenStream * 0x03df3378, JSTreeContext * 0x0012e81c) line 2164 + 3 bytes Fixed by Bug 320172
Updated•18 years ago
|
Flags: blocking1.9?
Comment 4•16 years ago
|
||
A fix for bug 442333 hides this bug, we need a better testcase.
Updated•16 years ago
|
Flags: in-testsuite+ → in-testsuite?
Comment 5•16 years ago
|
||
bug 446026 on tracemonkey unhides this bug.
Comment 6•13 years ago
|
||
Here's a test case. Object.defineProperty(this, "x", {get: function () { FAIL; }}); eval("var x;"); // throws FAIL Clearly against ES5. Waldo says we emit the erroneous JSOP_GET* opcode here for the decompiler's benefit. That being the case this will be a bit of a pain to fix.
Comment 7•13 years ago
|
||
This is ugly, somebody should have a look at this.
Comment 8•11 years ago
|
||
The decompiler has gone the way of the dodo, so maybe this is easier to fix now. Anyone want to try?
Comment 9•11 years ago
|
||
Here's a quick attempt at a fix. The removal of the statement decompiler did not remove unnecessary source notes, in this case for decompiling var x, y=42, z; and the like. Jeff, could you please take this bug and further simplify the code if possible, and do whatever else is needed for the given testcase (jorendorff's). /be
Comment 10•11 years ago
|
||
Wish I could, but I'm swamped with other stuff at the moment. :-)
Comment 11•11 years ago
|
||
Attachment #713107 -
Attachment is obsolete: true
Comment 12•11 years ago
|
||
Evilpies, how about you? Free patch if you call from work or your parents house :-P. /be
Comment 13•11 years ago
|
||
Attachment #713114 -
Attachment is obsolete: true
Comment 14•11 years ago
|
||
I started looking at the code and your patch. But variable names like pn3 are annoying to work with.
Comment 15•11 years ago
|
||
(In reply to Tom Schuster [:evilpie] from comment #14) > I started looking at the code and your patch. But variable names like pn3 > are annoying to work with. (a) That was already there, I just moved the declaration. (b) Our job is to make the engine better in minimum viable patches that don't get stalled by stop-energy complaints about variable names. Either fix it in a patch revision, or at least mention it _en passant_ while adding greater value than your comment does. :-( (c) It's *this bug's patch*, not "your patch" or "my patch". How about another look? /be
Comment 16•11 years ago
|
||
From my point of view the patch is okay, but I already asked Jason about this bug yesterday, and he agreed to review this.
Comment 17•11 years ago
|
||
Comment on attachment 714290 [details] [diff] [review] must satisfy the full PNX_POPVAR contract (all combos) Review of attachment 714290 [details] [diff] [review]: ----------------------------------------------------------------- I just noticed that I forgot to submit this review. ;) ::: js/src/frontend/BytecodeEmitter.cpp @@ +3055,5 @@ > { > JS_ASSERT(pn->isArity(PN_LIST)); > JS_ASSERT(isLet == (emitOption == PushInitialValues)); > > + ParseNode *pn3 = NULL; Initializer maybe? @@ +3232,5 @@ > if (pn->pn_xflags & PNX_POPVAR) { > + if (pn3 && Emit1(cx, bce, JSOP_POP) < 0) > + return false; > + } else { > + if (!pn3 && Emit1(cx, bce, JSOP_UNDEFINED) < 0) This or the whole if {} block need a comment about what it's doing. This !pn3 check seems to encode that the last variable had an initialize, I am wondering if we could do this a little bit cleaner and move pn3 inside the loop.
Comment 18•11 years ago
|
||
Comment on attachment 714290 [details] [diff] [review] must satisfy the full PNX_POPVAR contract (all combos) Jason said he would review this patch.
Attachment #714290 -
Flags: review?(jorendorff)
Comment 19•11 years ago
|
||
Comment on attachment 714290 [details] [diff] [review] must satisfy the full PNX_POPVAR contract (all combos) Review of attachment 714290 [details] [diff] [review]: ----------------------------------------------------------------- Clearing review flag. ::: js/src/frontend/BytecodeEmitter.cpp @@ +3055,5 @@ > { > JS_ASSERT(pn->isArity(PN_LIST)); > JS_ASSERT(isLet == (emitOption == PushInitialValues)); > > + ParseNode *pn3 = NULL; I agree with Tom about calling this lastInit or something. Your call. @@ -3233,5 @@ > if (!next) > break; > - off = tmp; > - noteIndex = NewSrcNote2(cx, bce, SRC_PCDELTA, 0); > - if (noteIndex < 0 || Emit1(cx, bce, JSOP_POP) < 0) Thanks for removing this. Filed follow-up bug 853178 to remove other unused PCDELTA notes. @@ +3229,1 @@ > return false; All this has gotten messy over the past few patches that touched it; would you mind recasting lines 3207-3229 as: if (pn3 && emitOption == InitializeVars) { JS_ASSERT_IF(pn2->isDefn(), pn3 == pn2->pn_expr); if (!pn2->pn_cookie.isFree()) { if (!EmitVarOp(cx, pn2, op, bce)) return false; } else { if (!EmitIndexOp(cx, op, atomIndex, bce)) return false; } #if JS_HAS_DESTRUCTURING emit_note_pop: #endif if (next) { if (Emit1(cx, bce, JSOP_POP) < 0) return false; } } This eliminates all the break or continue statements, but you would also have to add a condition in the loop head: >- for (ParseNode *pn2 = pn->pn_head; ; pn2 = next) { >+ for (ParseNode *pn2 = pn->pn_head; pn2; pn2 = next) { I can do this in a follow-up bug if you just want to get this landed. @@ +3229,5 @@ > return false; > } > > if (pn->pn_xflags & PNX_POPVAR) { > + if (pn3 && Emit1(cx, bce, JSOP_POP) < 0) I think something must be not quite right here, because the condition here does not match what happens in the loop. And a lot of tests do fail. For example, this test case asserts: for (let c in Array) {} dis(); with the following bytecode: main: 00000: undefined 00001: undefined 00002: getgname "Array" 00007: iter 1 00009: enterlet1 depth 1 {c: 0} 00014: goto 25 (+11) 00019: loophead 00020: iternext 00021: setlocal 1 00024: pop 00025: loopentry 00026: moreiter 00027: ifne 19 (-8) 00032: leaveforletin 00033: enditer 00034: popn 1 ...
Attachment #714290 -
Flags: review?(jorendorff)
Assignee | ||
Updated•10 years ago
|
Assignee: general → nobody
Comment 21•9 years ago
|
||
Duping forward to the bug that finally fixes this.
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → DUPLICATE
You need to log in
before you can comment on or make changes to this bug.
Description
•