зеркало из https://github.com/mozilla/pjs.git
Bug 620315 - "Assertion failure: unexpected constantly false guard detected" with "use strict", 4 > this. Fix a problem where we weren't marking functions created by |new Function| as accepting a primitive this value when their body was strict mode, by removing the duplicative bit that was being checked. r=dmandelin
This commit is contained in:
Родитель
33fe3323b9
Коммит
5910c2cb2f
|
@ -500,7 +500,7 @@ extern JS_PUBLIC_DATA(jsid) JSID_EMPTY;
|
|||
|
||||
#define JSFUN_HEAVYWEIGHT_TEST(f) ((f) & JSFUN_HEAVYWEIGHT)
|
||||
|
||||
#define JSFUN_PRIMITIVE_THIS 0x0100 /* |this| may be a primitive value */
|
||||
/* 0x0100 is unused */
|
||||
#define JSFUN_CONSTRUCTOR 0x0200 /* native that can be called as a ctor
|
||||
without creating a this object */
|
||||
|
||||
|
|
|
@ -120,11 +120,11 @@ bool_valueOf(JSContext *cx, uintN argc, Value *vp)
|
|||
|
||||
static JSFunctionSpec boolean_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, bool_toSource, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toSource_str, bool_toSource, 0, 0),
|
||||
#endif
|
||||
JS_FN(js_toString_str, bool_toString, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_valueOf_str, bool_valueOf, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toJSON_str, bool_valueOf, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toString_str, bool_toString, 0, 0),
|
||||
JS_FN(js_valueOf_str, bool_valueOf, 0, 0),
|
||||
JS_FN(js_toJSON_str, bool_valueOf, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
@ -182,8 +182,6 @@ struct JSFunction : public JSObject_Slots2
|
|||
|
||||
inline bool inStrictMode() const;
|
||||
|
||||
bool acceptsPrimitiveThis() const { return flags & JSFUN_PRIMITIVE_THIS; }
|
||||
|
||||
uintN countVars() const {
|
||||
JS_ASSERT(FUN_INTERPRETED(this));
|
||||
return u.i.nvars;
|
||||
|
|
|
@ -857,13 +857,6 @@ ComputeThisFromVpInPlace(JSContext *cx, js::Value *vp)
|
|||
return ComputeThisFromArgv(cx, vp + 2);
|
||||
}
|
||||
|
||||
/* Return true if |fun| would accept |v| as its |this|, without being wrapped. */
|
||||
JS_ALWAYS_INLINE bool
|
||||
PrimitiveThisTest(JSFunction *fun, const Value &v)
|
||||
{
|
||||
return !v.isPrimitive() || fun->acceptsPrimitiveThis();
|
||||
}
|
||||
|
||||
/*
|
||||
* Abstracts the layout of the stack passed to natives from the engine and from
|
||||
* natives to js::Invoke.
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
#include "jsstr.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
|
||||
#include "jsfuninlines.h"
|
||||
|
||||
inline void
|
||||
JSStackFrame::initPrev(JSContext *cx)
|
||||
{
|
||||
|
@ -356,7 +358,7 @@ JSStackFrame::computeThis(JSContext *cx)
|
|||
if (thisv.isObject())
|
||||
return true;
|
||||
if (isFunctionFrame()) {
|
||||
if (fun()->acceptsPrimitiveThis())
|
||||
if (fun()->inStrictMode())
|
||||
return true;
|
||||
/*
|
||||
* Eval function frames have their own |this| slot, which is a copy of the function's
|
||||
|
|
|
@ -929,15 +929,15 @@ JS_DEFINE_TRCINFO_2(num_toString,
|
|||
|
||||
static JSFunctionSpec number_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, num_toSource, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toSource_str, num_toSource, 0, 0),
|
||||
#endif
|
||||
JS_TN(js_toString_str, num_toString, 1, JSFUN_PRIMITIVE_THIS, &num_toString_trcinfo),
|
||||
JS_FN(js_toLocaleString_str, num_toLocaleString, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_valueOf_str, js_num_valueOf, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toJSON_str, js_num_valueOf, 0, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("toFixed", num_toFixed, 1, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("toExponential", num_toExponential, 1, JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("toPrecision", num_toPrecision, 1, JSFUN_PRIMITIVE_THIS),
|
||||
JS_TN(js_toString_str, num_toString, 1, 0, &num_toString_trcinfo),
|
||||
JS_FN(js_toLocaleString_str, num_toLocaleString, 0, 0),
|
||||
JS_FN(js_valueOf_str, js_num_valueOf, 0, 0),
|
||||
JS_FN(js_toJSON_str, js_num_valueOf, 0, 0),
|
||||
JS_FN("toFixed", num_toFixed, 1, 0),
|
||||
JS_FN("toExponential", num_toExponential, 1, 0),
|
||||
JS_FN("toPrecision", num_toPrecision, 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
@ -2757,7 +2757,7 @@ static JSFunctionSpec object_methods[] = {
|
|||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, obj_toSource, 0,0),
|
||||
#endif
|
||||
JS_FN(js_toString_str, obj_toString, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toString_str, obj_toString, 0,0),
|
||||
JS_FN(js_toLocaleString_str, obj_toLocaleString, 0,0),
|
||||
JS_FN(js_valueOf_str, obj_valueOf, 0,0),
|
||||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
|
|
|
@ -3163,9 +3163,6 @@ Parser::functionDef(JSAtom *funAtom, FunctionType type, uintN lambda)
|
|||
if (!LeaveFunction(pn, &funtc, funAtom, lambda))
|
||||
return NULL;
|
||||
|
||||
if (funtc.inStrictMode())
|
||||
fun->flags |= JSFUN_PRIMITIVE_THIS;
|
||||
|
||||
/* If the surrounding function is not strict code, reset the lexer. */
|
||||
if (!outertc->inStrictMode())
|
||||
tokenStream.setStrictMode(false);
|
||||
|
|
|
@ -3058,60 +3058,58 @@ JS_DEFINE_TRCINFO_1(str_concat,
|
|||
(3, (extern, STRING_RETRY, js_ConcatStrings, CONTEXT, THIS_STRING, STRING,
|
||||
1, nanojit::ACCSET_NONE)))
|
||||
|
||||
static const uint16 GENERIC_PRIMITIVE = JSFUN_GENERIC_NATIVE | JSFUN_PRIMITIVE_THIS;
|
||||
|
||||
static JSFunctionSpec string_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN("quote", str_quote, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN(js_toSource_str, str_toSource, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("quote", str_quote, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN(js_toSource_str, str_toSource, 0,0),
|
||||
#endif
|
||||
|
||||
/* Java-like methods. */
|
||||
JS_FN(js_toString_str, js_str_toString, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_valueOf_str, js_str_toString, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN(js_toJSON_str, js_str_toString, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("substring", str_substring, 2,GENERIC_PRIMITIVE),
|
||||
JS_FN("toLowerCase", str_toLowerCase, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("toUpperCase", str_toUpperCase, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("charAt", js_str_charAt, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN("charCodeAt", js_str_charCodeAt, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN("indexOf", str_indexOf, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN("lastIndexOf", str_lastIndexOf, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN("trim", str_trim, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("trimLeft", str_trimLeft, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("trimRight", str_trimRight, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,GENERIC_PRIMITIVE),
|
||||
JS_FN("localeCompare", str_localeCompare, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN(js_toString_str, js_str_toString, 0,0),
|
||||
JS_FN(js_valueOf_str, js_str_toString, 0,0),
|
||||
JS_FN(js_toJSON_str, js_str_toString, 0,0),
|
||||
JS_FN("substring", str_substring, 2,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("toLowerCase", str_toLowerCase, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("toUpperCase", str_toUpperCase, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("charAt", js_str_charAt, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("charCodeAt", js_str_charCodeAt, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("indexOf", str_indexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("lastIndexOf", str_lastIndexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("trim", str_trim, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("trimLeft", str_trimLeft, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("trimRight", str_trimRight, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("localeCompare", str_localeCompare, 1,JSFUN_GENERIC_NATIVE),
|
||||
|
||||
/* Perl-ish methods (search is actually Python-esque). */
|
||||
JS_FN("match", str_match, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN("search", str_search, 1,GENERIC_PRIMITIVE),
|
||||
JS_FN("replace", str_replace, 2,GENERIC_PRIMITIVE),
|
||||
JS_FN("split", str_split, 2,GENERIC_PRIMITIVE),
|
||||
JS_FN("match", str_match, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("search", str_search, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("replace", str_replace, 2,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("split", str_split, 2,JSFUN_GENERIC_NATIVE),
|
||||
#if JS_HAS_PERL_SUBSTR
|
||||
JS_FN("substr", str_substr, 2,GENERIC_PRIMITIVE),
|
||||
JS_FN("substr", str_substr, 2,JSFUN_GENERIC_NATIVE),
|
||||
#endif
|
||||
|
||||
/* Python-esque sequence methods. */
|
||||
JS_TN("concat", str_concat, 1,GENERIC_PRIMITIVE, &str_concat_trcinfo),
|
||||
JS_FN("slice", str_slice, 2,GENERIC_PRIMITIVE),
|
||||
JS_TN("concat", str_concat, 1,JSFUN_GENERIC_NATIVE, &str_concat_trcinfo),
|
||||
JS_FN("slice", str_slice, 2,JSFUN_GENERIC_NATIVE),
|
||||
|
||||
/* HTML string methods. */
|
||||
#if JS_HAS_STR_HTML_HELPERS
|
||||
JS_FN("bold", str_bold, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("italics", str_italics, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("fixed", str_fixed, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("fontsize", str_fontsize, 1,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("fontcolor", str_fontcolor, 1,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("link", str_link, 1,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("anchor", str_anchor, 1,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("strike", str_strike, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("small", str_small, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("big", str_big, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("blink", str_blink, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("sup", str_sup, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("sub", str_sub, 0,JSFUN_PRIMITIVE_THIS),
|
||||
JS_FN("bold", str_bold, 0,0),
|
||||
JS_FN("italics", str_italics, 0,0),
|
||||
JS_FN("fixed", str_fixed, 0,0),
|
||||
JS_FN("fontsize", str_fontsize, 1,0),
|
||||
JS_FN("fontcolor", str_fontcolor, 1,0),
|
||||
JS_FN("link", str_link, 1,0),
|
||||
JS_FN("anchor", str_anchor, 1,0),
|
||||
JS_FN("strike", str_strike, 0,0),
|
||||
JS_FN("small", str_small, 0,0),
|
||||
JS_FN("big", str_big, 0,0),
|
||||
JS_FN("blink", str_blink, 0,0),
|
||||
JS_FN("sup", str_sup, 0,0),
|
||||
JS_FN("sub", str_sub, 0,0),
|
||||
#endif
|
||||
|
||||
JS_FS_END
|
||||
|
|
|
@ -15720,7 +15720,7 @@ TraceRecorder::record_JSOP_CALLPROP()
|
|||
if (pcval.isFunObj()) {
|
||||
if (l.isPrimitive()) {
|
||||
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &pcval.toFunObj());
|
||||
if (!PrimitiveThisTest(fun, l))
|
||||
if (fun->isInterpreted() && !fun->inStrictMode())
|
||||
RETURN_STOP_A("callee does not accept primitive |this|");
|
||||
}
|
||||
set(&l, w.immpObjGC(&pcval.toFunObj()));
|
||||
|
|
|
@ -2022,7 +2022,6 @@ DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive)
|
|||
|
||||
SHOW_FLAG(LAMBDA);
|
||||
SHOW_FLAG(HEAVYWEIGHT);
|
||||
SHOW_FLAG(PRIMITIVE_THIS);
|
||||
SHOW_FLAG(EXPR_CLOSURE);
|
||||
SHOW_FLAG(TRCINFO);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче