
function lhs() {
    print('lhs');
}

function getenum1() {
    print('getenum1');
    return {};
}

function getenum2() {
    print('getenum2');
    return { 'foo': 'bar' };
}

function getint() {
    print('getint');
    return 10;
}

/*===
getenum1
done
getenum2
lhs
ReferenceError
===*/

/* The left-hand-side of a for-in may be a function call (and some other
 * expressions allowed by LeftHandSideExpression).  This is NOT a SyntaxError
 * and will only produce a ReferenceError when the actual assignment is
 * attempted.
 *
 * Note that at least Rhino and V8 won't call the lhs() function before
 * throwing a ReferenceError.  This seems technically incorrect: E5 Section
 * 12.6.4 steps 6.b and 6.c seem to indicate that the LHS should be evaluated
 * first, and only the actual attempt to PutValue() to an invalid reference
 * should throw a ReferenceError.  The specification does allow leeway in
 * whether or not the LHS is evaluated repeatedly though.
 *
 * In any case, the current implementation will evaluate the lhs() before
 * throwing a ReferenceError, so the test case now tests for that behavior.
 */

try {
    /* Here the enumerator will be empty, so no ReferenceError should happen.
     * The lhs() expression is not evaluated at all.
     */
 
    for (lhs() in getenum1()) {
        print('loop');
    }
    print('done');
} catch (e) {
    print(e.name);
}

try {
    /* Here empty() is called, but ReferenceError occurs on first assignment. */
 
    for (lhs() in getenum2()) {
        print('loop');
    }
    print('done');
} catch (e) {
    print(e.name);
}

/*===
getint
getenum2
foo
===*/

/* The variable initializer of a for-in statement may have a value.
 * That value is computed before the enumeration target is evaluated.
 */

try {
    for (var i = getint() in getenum2()) {
        print(i);
    }
} catch (e) {
    print(e.name);
}


