Fix two subtle bugs to-do with partial flat closures (545573, r=jorendorff).

This commit is contained in:
Brendan Eich 2010-02-11 14:56:59 -08:00
Родитель 99f75d684d
Коммит 33d4fdd4d2
5 изменённых файлов: 63 добавлений и 9 удалений

Просмотреть файл

@ -2492,10 +2492,18 @@ js_AllocFlatClosure(JSContext *cx, JSFunction *fun, JSObject *scopeChain)
JS_DEFINE_CALLINFO_3(extern, OBJECT, js_AllocFlatClosure,
CONTEXT, FUNCTION, OBJECT, 0, 0)
JSObject *
JS_REQUIRES_STACK JSObject *
js_NewFlatClosure(JSContext *cx, JSFunction *fun)
{
JSObject *closure = js_AllocFlatClosure(cx, fun, cx->fp->scopeChain);
/*
* Flat closures can be partial, they may need to search enclosing scope
* objects via JSOP_NAME, etc.
*/
JSObject *scopeChain = js_GetScopeChain(cx, cx->fp);
if (!scopeChain)
return NULL;
JSObject *closure = js_AllocFlatClosure(cx, fun, scopeChain);
if (!closure || fun->u.i.nupvars == 0)
return closure;

Просмотреть файл

@ -2195,20 +2195,16 @@ FlagHeavyweights(JSDefinition *dn, JSFunctionBox *funbox, uint32& tcflags)
static void
DeoptimizeUsesWithin(JSDefinition *dn, JSFunctionBox *funbox, uint32& tcflags)
{
JSParseNode **pnup = &dn->dn_uses;
uintN ndeoptimized = 0;
const JSTokenPos &pos = funbox->node->pn_body->pn_pos;
while (JSParseNode *pnu = *pnup) {
for (JSParseNode *pnu = dn->dn_uses; pnu; pnu = pnu->pn_link) {
JS_ASSERT(pnu->pn_used);
JS_ASSERT(!pnu->pn_defn);
const JSTokenPos &pos = funbox->node->pn_body->pn_pos;
if (pnu->pn_pos.begin >= pos.begin && pnu->pn_pos.end < pos.end) {
if (pnu->pn_pos.begin >= pos.begin && pnu->pn_pos.end <= pos.end) {
pnu->pn_dflags |= PND_DEOPTIMIZED;
*pnup = pnu->pn_link;
++ndeoptimized;
continue;
}
pnup = &pnu->pn_link;
}
if (ndeoptimized != 0)

Просмотреть файл

@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributor: Brendan Eich
*/
var gTestfile = 'expclo.js';
var summary = "Flat expression closure source coordinate fencepost test";
function f(a) {
if (a) {
let b = 42;
let c = function () a+b;
++b;
return c;
}
return null;
}
var expect = 44;
var actual = f(1)();
reportCompare(expect, actual, summary);

Просмотреть файл

@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributor: Brendan Eich
*/
var gTestfile = 'expclo.js';
var summary = "Partial flat expression closure upvar order test";
function f(a) {
if (a) {
let b = 42;
let c = function () b+a;
++b;
return c;
}
return null;
}
var expect = 44;
var actual = f(1)();
reportCompare(expect, actual, summary);

Просмотреть файл

@ -1,5 +1,7 @@
url-prefix ../../jsreftest.html?test=js1_8/extensions/
script dekker.js
script expclo.js
script expclo2.js
script for-in.js
script lamport.js
script peterson.js