Merge backout of bug 495331 patch

This commit is contained in:
David Mandelin 2009-10-05 18:32:06 -07:00
Родитель 7bab72d85f 46c3eb9356
Коммит 34e47d71cb
10 изменённых файлов: 105 добавлений и 14 удалений

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

@ -6269,26 +6269,39 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
case TOK_NEW:
case TOK_LP:
{
bool callop = (PN_TYPE(pn) == TOK_LP);
uintN oldflags;
/*
* Emit function call or operator new (constructor call) code.
* Emit callable invocation or operator new (constructor call) code.
* First, emit code for the left operand to evaluate the callable or
* constructable object expression.
*
* For operator new applied to other expressions than E4X ones, we emit
* JSOP_GETPROP instead of JSOP_CALLPROP, etc. This is necessary to
* interpose the lambda-initialized method read barrier -- see the code
* in jsops.cpp for JSOP_LAMBDA followed by JSOP_{SET,INIT}PROP.
*
* Then (or in a call case that has no explicit reference-base object)
* we emit JSOP_NULL as a placeholder local GC root to hold the |this|
* parameter: in the operator new case, the newborn instance; in the
* base-less call case, a cookie meaning "use the global object as the
* |this| value" (or in ES5 strict mode, "use undefined", so we should
* use JSOP_PUSH instead of JSOP_NULL -- see bug 514570).
*/
pn2 = pn->pn_head;
switch (pn2->pn_type) {
case TOK_NAME:
if (!EmitNameOp(cx, cg, pn2, JS_TRUE))
if (!EmitNameOp(cx, cg, pn2, callop))
return JS_FALSE;
break;
case TOK_DOT:
if (!EmitPropOp(cx, pn2, PN_OP(pn2), cg, JS_TRUE))
if (!EmitPropOp(cx, pn2, PN_OP(pn2), cg, callop))
return JS_FALSE;
break;
case TOK_LB:
JS_ASSERT(pn2->pn_op == JSOP_GETELEM);
if (!EmitElemOp(cx, pn2, JSOP_CALLELEM, cg))
if (!EmitElemOp(cx, pn2, callop ? JSOP_CALLELEM : JSOP_GETELEM, cg))
return JS_FALSE;
break;
case TOK_UNARYOP:
@ -6296,6 +6309,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
if (pn2->pn_op == JSOP_XMLNAME) {
if (!EmitXMLName(cx, pn2, JSOP_CALLXMLNAME, cg))
return JS_FALSE;
callop = true; /* suppress JSOP_NULL after */
break;
}
#endif
@ -6307,9 +6321,11 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
*/
if (!js_EmitTree(cx, cg, pn2))
return JS_FALSE;
if (js_Emit1(cx, cg, JSOP_NULL) < 0)
return JS_FALSE;
callop = false; /* trigger JSOP_NULL after */
break;
}
if (!callop && js_Emit1(cx, cg, JSOP_NULL) < 0)
return JS_FALSE;
/* Remember start of callable-object bytecode for decompilation hint. */
off = top;

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

@ -1410,10 +1410,14 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
fun = GET_FUNCTION_PRIVATE(cx, obj);
/*
* No need to reflect fun.prototype in 'fun.prototype = ... '.
* No need to reflect fun.prototype in 'fun.prototype = ... '. Assert that
* fun is not a compiler-created function object, which must never leak to
* script or embedding code and then be mutated.
*/
if (flags & JSRESOLVE_ASSIGNING)
if (flags & JSRESOLVE_ASSIGNING) {
JS_ASSERT(!js_IsInternalFunctionObject(obj));
return JS_TRUE;
}
/*
* Ok, check whether id is 'prototype' and bootstrap the function object's
@ -1421,7 +1425,7 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
*/
atom = cx->runtime->atomState.classPrototypeAtom;
if (id == ATOM_KEY(atom)) {
JSObject *proto;
JS_ASSERT(!js_IsInternalFunctionObject(obj));
/*
* Beware of the wacky case of a user function named Object -- trying
@ -1434,7 +1438,8 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
* Make the prototype object to have the same parent as the function
* object itself.
*/
proto = js_NewObject(cx, &js_ObjectClass, NULL, OBJ_GET_PARENT(cx, obj));
JSObject *proto =
js_NewObject(cx, &js_ObjectClass, NULL, OBJ_GET_PARENT(cx, obj));
if (!proto)
return JS_FALSE;
@ -1457,6 +1462,8 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
atom = OFFSET_TO_ATOM(cx->runtime, lfp->atomOffset);
if (id == ATOM_KEY(atom)) {
JS_ASSERT(!js_IsInternalFunctionObject(obj));
if (!js_DefineNativeProperty(cx, obj,
ATOM_TO_JSID(atom), JSVAL_VOID,
fun_getProperty, JS_PropertyStub,

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

@ -160,8 +160,8 @@ struct JSFunction : public JSObject {
} u;
JSAtom *atom; /* name for diagnostics and decompiling */
bool optimizedClosure() { return FUN_KIND(this) > JSFUN_INTERPRETED; }
bool needsWrapper() { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; }
bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
uintN countArgsAndVars() const {
JS_ASSERT(FUN_INTERPRETED(this));
@ -221,6 +221,19 @@ extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
(JS_ASSERT(HAS_FUNCTION_CLASS(funobj)), \
(JSFunction *) (funobj)->getPrivate())
/*
* Return true if this is a compiler-created internal function accessed by
* its own object. Such a function object must not be accessible to script
* or embedding code.
*/
inline bool
js_IsInternalFunctionObject(JSObject *funobj)
{
JS_ASSERT(HAS_FUNCTION_CLASS(funobj));
JSFunction *fun = (JSFunction *) funobj->getPrivate();
return funobj == fun && (fun->flags & JSFUN_LAMBDA) && !funobj->getParent();
}
struct js_ArgsPrivateNative;
inline js_ArgsPrivateNative *

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

@ -590,7 +590,7 @@ TraceRecorder::slurpBoolSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
INS_CONSTWORD(JSVAL_SPECIAL)),
exit);
LIns* bool_ins = lir->ins2(LIR_pilsh, val_ins, INS_CONSTWORD(JSVAL_TAGBITS));
LIns* bool_ins = lir->ins2(LIR_pirsh, val_ins, INS_CONSTWORD(JSVAL_TAGBITS));
bool_ins = p2i(bool_ins);
return bool_ins;
}

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

@ -46,7 +46,7 @@ var expect = '';
printBugNumber(BUGNUMBER);
START(summary);
expect = 'TypeError: XML.prototype.hasOwnProperty called on incompatible Object';
expect = 'TypeError: <x/>.hasOwnProperty is not a constructor';
actual = '';
try

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

@ -2,3 +2,4 @@ url-prefix ../../jsreftest.html?test=ecma_3/FunExpr/
script fe-001-n.js
script fe-001.js
script fe-002.js
script regress-518103.js

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

@ -0,0 +1,27 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var BUGNUMBER = 518103;
var summary = 'lambda constructor "method" vs. instanceof';
var actual;
var expect;
printBugNumber(BUGNUMBER);
printStatus(summary);
var Y = {widget: {}};
Y.widget.DataSource = function () {};
Y.widget.DS_JSArray = function (A) { this.data = A; };
Y.widget.DS_JSArray.prototype = new Y.widget.DataSource();
var J = new Y.widget.DS_JSArray( [ ] );
actual = J instanceof Y.widget.DataSource;
expect = true;
reportCompare(actual, expect, summary);
printStatus("All tests passed!");

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

@ -0,0 +1,3 @@
(new Function("for (var j=0; j<9; ++j) { (function sum_indexing(array,start){return array.length==start ? 0 : array[start]+ sum_indexing(array,start+1)})([true,true,undefined],0)}"))()
/* Should not have crashed. */

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

@ -0,0 +1,18 @@
for each(let a in [new Boolean(false)]) {}
for (var b = 0; b < 13; ++b) {
if (b % 3 == 1) {
(function f(c) {
if (c <= 1) {
return 1;
}
return f(c - 1) + f(c - 2);
})(3)
} else {
(function g(d, e) {;
return d.length == e ? 0 : d[e] + g(d, e + 1);
})([false, new Boolean(true), false], 0)
}
}
/* Should not have crashed. */

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

@ -0,0 +1,6 @@
(Function("for (var a = 0; a < 6; a++) {\
(function sum_indexing(b, c) {\
return b.length == c ? 0 : b[c] + sum_indexing(b, c + 1)\
})([(void 0), Infinity, Infinity], 0)\
}"))()