Closed Bug 351070 Opened 18 years ago Closed 18 years ago

Scope of let declaration changes during decompilation

Categories

(Core :: JavaScript Engine, defect, P2)

defect

Tracking

()

VERIFIED FIXED
mozilla1.8.1

People

(Reporter: nanto, Assigned: brendan)

References

Details

(Keywords: verified1.8.1)

Attachments

(3 files, 6 obsolete files)

js> function f() { var a = 2; if (!!true) let a = 3; return a; }
js> f()
3
js> f
function f() {
    var a = 2;
    if (!!true) {
        let a = 3;
    }
    return a;
}
js> eval(uneval(f))
js> f()
2

I don't know where the scope of a let declaration in a statement without curly brackets should be.
Decompiler always braces, for simplicity -- obviously that changes the scope of let (let declarations, e.g. let a = 3, bind in the nearest enclosing block, or the function body if no such block).

Contrast with bug 349634, where unnecessary-before-let-was-introduced braces are elided by the decompiler.

/be
Assignee: general → brendan
Blocks: js1.7let
OS: Windows XP → All
Priority: -- → P2
Hardware: PC → All
Target Milestone: --- → mozilla1.8.1
This turned out decently, after some noodling.

/be
Attachment #237550 - Flags: review?(mrbkap)
Attached file js shell generated source testcase (obsolete) —
This could be beefed up to test, for all the table entries, that braces do make the let a = 3 block-local and therefore change the expected return value.

/be
Attached patch fix, v2 (obsolete) — Splinter Review
I fussed a bit, and eliminated a vacuous if (DONT_BRACE => braceOffset >= 0).  I'm pretty happy with this now.

/be
Attachment #237550 - Attachment is obsolete: true
Attachment #237562 - Flags: review?(mrbkap)
Attachment #237550 - Flags: review?(mrbkap)
Attached patch fix, v3 (obsolete) — Splinter Review
Couldn't resist fussing once more: why unroll the memmove with an explicit store of the '\n' over the space before the brace, when it can be included in the move for free?

/be
Attachment #237562 - Attachment is obsolete: true
Attachment #237565 - Flags: review?(mrbkap)
Attachment #237562 - Flags: review?(mrbkap)
Attached file fixed js shell test
D'oh, the test was broken.  This is better, and gives visual results (should be testable against reference decompilations).

/be
Attachment #237551 - Attachment is obsolete: true
Attached patch fix, v4 (obsolete) — Splinter Review
Fixed to cope with JS_DONT_PRETTY_PRINT option, which suppresses newlines.  Thus the memmove must handle moving the newline down two chars in the pretty case.

/be
Attachment #237565 - Attachment is obsolete: true
Attachment #237568 - Flags: review?(mrbkap)
Attachment #237565 - Flags: review?(mrbkap)
Attached patch fix, v5 (obsolete) — Splinter Review
Final fix, I missed early output from the test:

function f1() {
    var n = 2, a = 2;
    if (!!true)
        let a = 3;
else {
        foopy();
    }
    return a;
}

Easily handled by js_printf'ing the "else" with the "\t} ", leaving the " {\n" to be js_printf'd separately with SET_MAYBE_BRACE(jp).

Dangling else works, as ever:

js> version(170)
0
js> function f(x){if (x) if (y) z; else let w }
js> f
function f(x) {
    if (x) {
        if (y) {
            z;
        } else
            let w;
    }
}
js> function f(x){if (x){ if (y) z;} else let w  }
js> f
function f(x) {
    if (x) {
        if (y) {
            z;
        }
    } else
        let w;
}
js> function f(x){if (x){ if (y) let z;} else let w  }
js> f
function f(x) {
    if (x) {
        if (y)
            let z;
    } else
        let w;
}

/be
Attachment #237568 - Attachment is obsolete: true
Attachment #237569 - Flags: review?(mrbkap)
Attachment #237568 - Flags: review?(mrbkap)
This is important given let declarations for block scope in JS1.7.

/be
Status: NEW → ASSIGNED
Flags: blocking1.8.1?
Attached patch fix, v6Splinter Review
Oops, I knew I forgot something that I thought of (like pink, best thoughts come in the shower, but no dive whiteboard or rubber memo-duck yet), then forgot:

js> version(170)
0
js> function f(){var a = 2; if (x) {let a = 3; print(a)} return a}
js> f
function f() {
    var a = 2;
    if (x)
        let a = 3;
        print(a);
    return a;
}

With this patch, it's all good:

js> function f(){var a = 2; if (x) {let a = 3; print(a)} return a}
js> f
function f() {
    var a = 2;
    if (x) {
        let a = 3;
        print(a);
    }
    return a;
}
js> function f(){var a = 2; if (x) {print(a);let a = 3} return a}
js> f
function f() {
    var a = 2;
    if (x) {
        print(a);
        let a = 3;
    }
    return a;
}
js> function f(){var a = 2; if (x) {let a = 3} return a}
js> f
function f() {
    var a = 2;
    if (x) {
        let a = 3;
    }
    return a;
}
js> function f(){var a = 2; if (x) let a = 3; return a}
js> f
function f() {
    var a = 2;
    if (x)
        let a = 3;
    return a;
}

Interdiff to the see the one crucial line.

/be
Attachment #237569 - Attachment is obsolete: true
Attachment #237570 - Flags: review?(mrbkap)
Attachment #237569 - Flags: review?(mrbkap)
Flags: blocking1.8.1? → blocking1.8.1+
Comment on attachment 237570 [details] [diff] [review]
fix, v6

>+#if JS_HAS_BLOCK_SCOPE
>+                        if (jp->braceState == MAYBE_BRACE &&
>+                            pc + 1 == endpc &&
>+                            !strncmp(rval, var_prefix[SRC_DECL_LET], 4) &&
>+                            rval[4] != '(') {
>+                            SetDontBrace(jp);
>+                        }
>+#endif

Comment on what this is doing and r=mrbkap.
Attachment #237570 - Flags: review?(mrbkap) → review+
This merged up to tip, to get the patch for bug 352026 that was just committed.

/be
Attachment #237788 - Flags: review+
Attachment #237788 - Flags: approval1.8.1?
Fixed on trunk.

/be
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Blocks: 352217
Comment on attachment 237788 [details] [diff] [review]
fix, v6 with comment and updated to track trunk

a=schrep for drivers.
Attachment #237788 - Flags: approval1.8.1? → approval1.8.1+
Whiteboard: [checkin needed (1.8 branch)]
Fixed on the 1.8 branch.

/be
Keywords: fixed1.8.1
Checking in regress-351070-01.js;
/cvsroot/mozilla/js/tests/js1_7/block/regress-351070-01.js,v  <--  regress-351070-01.js
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/js/tests/js1_7/block/regress-351070-02.js,v
done
Checking in regress-351070-02.js;
/cvsroot/mozilla/js/tests/js1_7/block/regress-351070-02.js,v  <--  regress-351070-02.js
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/js/tests/js1_7/block/regress-351070-03.js,v
done
Checking in regress-351070-03.js;
/cvsroot/mozilla/js/tests/js1_7/block/regress-351070-03.js,v  <--  regress-351070-03.js
initial revision: 1.1
done
Flags: in-testsuite+
verified fixed 1.8 20060914 windows/linux 1.9 20060914 windows/mac*/linux
Status: RESOLVED → VERIFIED
Whiteboard: [checkin needed (1.8 branch)]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: