Closed Bug 320887 Opened 19 years ago Closed 9 years ago

|var x| can throw a ReferenceError

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 1217099

People

(Reporter: mrbkap, Unassigned)

References

()

Details

Attachments

(1 file, 2 obsolete files)

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.
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+
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
Flags: blocking1.9?
Obscure enough to not block on.
Flags: blocking1.9? → blocking1.9-
A fix for bug 442333 hides this bug, we need a better testcase.
Flags: in-testsuite+ → in-testsuite?
bug 446026 on tracemonkey unhides this bug.
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.
Blocks: es5
This is ugly, somebody should have a look at this.
The decompiler has gone the way of the dodo, so maybe this is easier to fix now. Anyone want to try?
Attached patch quick fix attempt (obsolete) (deleted) — Splinter Review
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
Wish I could, but I'm swamped with other stuff at the moment. :-)
Attachment #713107 - Attachment is obsolete: true
Evilpies, how about you? Free patch if you call from work or your parents house :-P. /be
I started looking at the code and your patch. But variable names like pn3 are annoying to work with.
(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
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 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 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 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: general → nobody
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.

Attachment

General

Created:
Updated:
Size: