зеркало из https://github.com/mozilla/gecko-dev.git
Bug 761723 - Save script sources to implement Function.prototype.toString. r=jorendorff,njn,jimb,jst,Ms2ger
--HG-- extra : rebase_source : de1b55647780a30f98fe84d29ee3cb4a437a3ece
This commit is contained in:
Родитель
2f82b105e6
Коммит
78a5439268
|
@ -57,15 +57,15 @@ let inputValues = [
|
|||
[false, "true", "true"],
|
||||
|
||||
// 11
|
||||
[false, "document.getElementById", "function getElementById() {[native code]}",
|
||||
[false, "document.getElementById", "function getElementById() {\n [native code]\n}",
|
||||
"function getElementById() {\n [native code]\n}",
|
||||
"function getElementById() {\n [native code]\n}",
|
||||
"function getElementById() {[native code]}",
|
||||
"document.wrappedJSObject.getElementById"],
|
||||
|
||||
// 12
|
||||
[false, "(function() { return 42; })", "function () {return 42;}",
|
||||
"function () {\n return 42;\n}",
|
||||
"(function () {return 42;})"],
|
||||
[false, "(function() { return 42; })", "function () { return 42; }",
|
||||
"function () { return 42; }",
|
||||
"(function () { return 42; })"],
|
||||
|
||||
// 13
|
||||
[false, "new Date(" + dateNow + ")", (new Date(dateNow)).toString()],
|
||||
|
|
|
@ -40,7 +40,7 @@ function runTests() {
|
|||
root.setAttribute("onclick", listenerSource);
|
||||
infos = els.getListenerInfoFor(root, {});
|
||||
is(infos.length, 1, "Element should have listeners (1)");
|
||||
is(infos[0].toSource(), 'function onclick(event) {' + listenerSource + '}',
|
||||
is(infos[0].toSource(), 'function onclick(event) { ' + listenerSource + ' }',
|
||||
"Unexpected serialization (1)");
|
||||
is(infos[0].type, "click", "Wrong type (1)");
|
||||
is(infos[0].capturing, false, "Wrong phase (1)");
|
||||
|
@ -67,7 +67,7 @@ function runTests() {
|
|||
root.addEventListener("foo", l, false, false);
|
||||
infos = els.getListenerInfoFor(root, {});
|
||||
is(infos.length, 2, "Element should have listeners (2)");
|
||||
is(infos[0].toSource(), "(function (e) {alert(e);})",
|
||||
is(infos[0].toSource(), "(function (e) { alert(e); })",
|
||||
"Unexpected serialization (2)");
|
||||
is(infos[0].type, "foo", "Wrong type (2)");
|
||||
is(infos[0].capturing, true, "Wrong phase (2)");
|
||||
|
@ -78,7 +78,7 @@ function runTests() {
|
|||
is(jsdvalue.getWrappedValue(), l, "Wrong JS value! (1)");
|
||||
*/
|
||||
|
||||
is(infos[1].toSource(), "(function (e) {alert(e);})",
|
||||
is(infos[1].toSource(), "(function (e) { alert(e); })",
|
||||
"Unexpected serialization (3)");
|
||||
is(infos[1].type, "foo", "Wrong type (3)");
|
||||
is(infos[1].capturing, false, "Wrong phase (3)");
|
||||
|
@ -97,7 +97,7 @@ function runTests() {
|
|||
root.onclick = l;
|
||||
infos = els.getListenerInfoFor(root, {});
|
||||
is(infos.length, 1, "Element should have listeners (3)");
|
||||
is(infos[0].toSource(), '(function (e) {alert(e);})',
|
||||
is(infos[0].toSource(), '(function (e) { alert(e); })',
|
||||
"Unexpected serialization (4)");
|
||||
is(infos[0].type, "click", "Wrong type (4)");
|
||||
is(infos[0].capturing, false, "Wrong phase (4)");
|
||||
|
|
|
@ -45,10 +45,10 @@ div.onload = f;
|
|||
is(div.onload, f, "Should have 'f' as div's onload");
|
||||
div.setAttribute("onload", "");
|
||||
isnot(div.onload, f, "Should not longer have 'f' as div's onload");
|
||||
is(div.onload.toString(), "function onload(event) {\n}",
|
||||
is(div.onload.toString(), "function onload(event) { }",
|
||||
"Should have wrapped empty string in a function");
|
||||
div.setAttribute("onload", "foopy();");
|
||||
is(div.onload.toString(), "function onload(event) {\n foopy();\n}",
|
||||
is(div.onload.toString(), "function onload(event) { foopy(); }",
|
||||
"Should have wrapped call in a function");
|
||||
div.removeAttribute("onload");
|
||||
is(div.onload, null, "Should have null onload now");
|
||||
|
@ -69,11 +69,11 @@ function testPropagationToWindow(eventName) {
|
|||
|
||||
document.body.setAttribute("on"+eventName, eventName);
|
||||
is(window["on"+eventName].toString(),
|
||||
"function on"+eventName+"(event) {\n "+eventName+";\n}",
|
||||
"function on"+eventName+"(event) { "+eventName+" }",
|
||||
"Setting on"+eventName+"attribute on body should propagate to window");
|
||||
document.createElement("body").setAttribute("on"+eventName, eventName+"2");
|
||||
is(window["on"+eventName].toString(),
|
||||
"function on"+eventName+"(event) {\n "+eventName+"2;\n}",
|
||||
"function on"+eventName+"(event) { "+eventName+"2 }",
|
||||
"Setting on"+eventName+"attribute on body outside the document should propagate to window");
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689564
|
|||
var div = document.createElement("div");
|
||||
div.setAttribute("onclick", "div");
|
||||
is(window.onclick, null, "div should not forward onclick");
|
||||
is(div.onclick.toString(), "function onclick(event) {\n div;\n}",
|
||||
is(div.onclick.toString(), "function onclick(event) { div }",
|
||||
"div should have an onclick handler");
|
||||
|
||||
div.setAttribute("onscroll", "div");
|
||||
is(window.onscroll, null, "div should not forward onscroll");
|
||||
is(div.onscroll.toString(), "function onscroll(event) {\n div;\n}",
|
||||
is(div.onscroll.toString(), "function onscroll(event) { div }",
|
||||
"div should have an onscroll handler");
|
||||
|
||||
div.setAttribute("onpopstate", "div");
|
||||
|
@ -36,25 +36,25 @@ is(div.onpopstate, null, "div should not have onpopstate handler");
|
|||
var body = document.createElement("body");
|
||||
body.setAttribute("onclick", "body");
|
||||
is(window.onclick, null, "body should not forward onclick");
|
||||
is(body.onclick.toString(), "function onclick(event) {\n body;\n}",
|
||||
is(body.onclick.toString(), "function onclick(event) { body }",
|
||||
"body should have an onclick handler");
|
||||
body.setAttribute("onscroll", "body");
|
||||
is(window.onscroll.toString(), "function onscroll(event) {\n body;\n}",
|
||||
is(window.onscroll.toString(), "function onscroll(event) { body }",
|
||||
"body should forward onscroll");
|
||||
body.setAttribute("onpopstate", "body");
|
||||
is(window.onpopstate.toString(), "function onpopstate(event) {\n body;\n}",
|
||||
is(window.onpopstate.toString(), "function onpopstate(event) { body }",
|
||||
"body should forward onpopstate");
|
||||
|
||||
var frameset = document.createElement("frameset");
|
||||
frameset.setAttribute("onclick", "frameset");
|
||||
is(window.onclick, null, "frameset should not forward onclick");
|
||||
is(frameset.onclick.toString(), "function onclick(event) {\n frameset;\n}",
|
||||
is(frameset.onclick.toString(), "function onclick(event) { frameset }",
|
||||
"frameset should have an onclick handler");
|
||||
frameset.setAttribute("onscroll", "frameset");
|
||||
is(window.onscroll.toString(), "function onscroll(event) {\n frameset;\n}",
|
||||
is(window.onscroll.toString(), "function onscroll(event) { frameset }",
|
||||
"frameset should forward onscroll");
|
||||
frameset.setAttribute("onpopstate", "frameset");
|
||||
is(window.onpopstate.toString(), "function onpopstate(event) {\n frameset;\n}",
|
||||
is(window.onpopstate.toString(), "function onpopstate(event) { frameset }",
|
||||
"frameset should forward onpopstate");
|
||||
|
||||
|
||||
|
|
|
@ -122,26 +122,13 @@ InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
JS::Value* argv = JS_ARGV(cx, vp);
|
||||
uint32_t indent = 0;
|
||||
if (argc != 0 && !JS_ValueToECMAUint32(cx, argv[0], &indent))
|
||||
return false;
|
||||
|
||||
nsAutoString spaces;
|
||||
while (indent-- > 0) {
|
||||
spaces.Append(PRUnichar(' '));
|
||||
}
|
||||
|
||||
nsString str;
|
||||
str.Append(spaces);
|
||||
str.AppendLiteral("function ");
|
||||
str.Append(name, length);
|
||||
str.AppendLiteral("() {");
|
||||
str.Append('\n');
|
||||
str.Append(spaces);
|
||||
str.AppendLiteral(" [native code]");
|
||||
str.Append('\n');
|
||||
str.Append(spaces);
|
||||
str.AppendLiteral("}");
|
||||
|
||||
return xpc::NonVoidStringToJsval(cx, str, vp);
|
||||
|
|
|
@ -8,15 +8,15 @@ var iframeScript = function() {
|
|||
var ev = content.document.createEvent('HTMLEvents');
|
||||
ev.initEvent('contextmenu', true, false);
|
||||
element.dispatchEvent(ev);
|
||||
}
|
||||
};
|
||||
|
||||
XPCNativeWrapper.unwrap(content).ctxCallbackFired = function(data) {
|
||||
sendAsyncMessage('test:callbackfired', {data: data});
|
||||
}
|
||||
};
|
||||
|
||||
XPCNativeWrapper.unwrap(content).onerror = function(e) {
|
||||
sendAsyncMessage('test:errorTriggered', {data: e});
|
||||
}
|
||||
};
|
||||
|
||||
content.fireContextMenu(content.document.body);
|
||||
content.fireContextMenu(content.document.getElementById('menu1-trigger'));
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"Should throw TypeError for function \"function () {\n localStorage.key();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n localStorage.getItem();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n localStorage.setItem();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n localStorage.setItem(\"a\");\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n localStorage.removeItem();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n sessionStorage.key();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n sessionStorage.getItem();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n sessionStorage.setItem();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n sessionStorage.setItem(\"a\");\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n sessionStorage.removeItem();\n}\".": true,
|
||||
"Should throw TypeError for function \"function () {\n new StorageEvent;\n}\".": true
|
||||
"Should throw TypeError for function \"function () { localStorage.key(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.getItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.setItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.setItem(\"a\"); }\".": true,
|
||||
"Should throw TypeError for function \"function () { localStorage.removeItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.key(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.getItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.setItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.setItem(\"a\"); }\".": true,
|
||||
"Should throw TypeError for function \"function () { sessionStorage.removeItem(); }\".": true,
|
||||
"Should throw TypeError for function \"function () { new StorageEvent(); }\".": true
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
// killed.
|
||||
SimpleTest.requestLongerTimeout(100);
|
||||
|
||||
// Disable crash observers as it breaks later tests.
|
||||
function iframeScriptFirst() {
|
||||
// Disable this functionality, it breaks later tests.
|
||||
SpecialPowers.prototype.registerProcessCrashObservers = function() { };
|
||||
SpecialPowers.prototype.unregisterProcessCrashObservers = function() { };
|
||||
|
||||
|
|
|
@ -21,6 +21,33 @@
|
|||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
|
||||
class AutoAttachToRuntime {
|
||||
JSRuntime *rt;
|
||||
public:
|
||||
ScriptSource *ss;
|
||||
AutoAttachToRuntime(JSRuntime *rt)
|
||||
: rt(rt), ss(NULL) {}
|
||||
~AutoAttachToRuntime() {
|
||||
// This makes the source visible to the GC. If compilation fails, and no
|
||||
// script refers to it, it will be collected.
|
||||
if (ss)
|
||||
ss->attachToRuntime(rt);
|
||||
}
|
||||
};
|
||||
|
||||
static bool
|
||||
CheckLength(JSContext *cx, size_t length)
|
||||
{
|
||||
// Note this limit is simply so we can store sourceStart and sourceEnd in
|
||||
// JSScript as 32-bits. It could be lifted fairly easily, since the compiler
|
||||
// is using size_t internally already.
|
||||
if (length > UINT32_MAX) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_SOURCE_TOO_LONG);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JSScript *
|
||||
frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *callerFrame,
|
||||
JSPrincipals *principals, JSPrincipals *originPrincipals,
|
||||
|
@ -52,6 +79,15 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
|
|||
JS_ASSERT_IF(callerFrame, compileAndGo);
|
||||
JS_ASSERT_IF(staticLevel != 0, callerFrame);
|
||||
|
||||
if (!CheckLength(cx, length))
|
||||
return NULL;
|
||||
AutoAttachToRuntime attacher(cx->runtime);
|
||||
SourceCompressionToken sct(cx->runtime);
|
||||
ScriptSource *ss = ScriptSource::createFromSource(cx, chars, length, false, &sct);
|
||||
if (!ss)
|
||||
return NULL;
|
||||
attacher.ss = ss;
|
||||
|
||||
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
|
||||
/* foldConstants = */ true, compileAndGo);
|
||||
if (!parser.init())
|
||||
|
@ -72,7 +108,10 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
|
|||
compileAndGo,
|
||||
noScriptRval,
|
||||
version,
|
||||
staticLevel));
|
||||
staticLevel,
|
||||
ss,
|
||||
0,
|
||||
length));
|
||||
if (!script)
|
||||
return NULL;
|
||||
|
||||
|
@ -215,6 +254,15 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun,
|
|||
Bindings *bindings, const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno, JSVersion version)
|
||||
{
|
||||
if (!CheckLength(cx, length))
|
||||
return false;
|
||||
AutoAttachToRuntime attacher(cx->runtime);
|
||||
SourceCompressionToken sct(cx->runtime);
|
||||
ScriptSource *ss = ScriptSource::createFromSource(cx, chars, length, true, &sct);
|
||||
if (!ss)
|
||||
return NULL;
|
||||
attacher.ss = ss;
|
||||
|
||||
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
|
||||
/* foldConstants = */ true, /* compileAndGo = */ false);
|
||||
if (!parser.init())
|
||||
|
@ -239,7 +287,10 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun,
|
|||
/* compileAndGo = */ false,
|
||||
/* noScriptRval = */ false,
|
||||
version,
|
||||
staticLevel));
|
||||
staticLevel,
|
||||
ss,
|
||||
0,
|
||||
length));
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -4872,7 +4872,10 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
parent->compileAndGo,
|
||||
/* noScriptRval = */ false,
|
||||
parent->getVersion(),
|
||||
parent->staticLevel + 1));
|
||||
parent->staticLevel + 1,
|
||||
bce->script->source,
|
||||
funbox->bufStart,
|
||||
funbox->bufEnd));
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1475,6 +1475,8 @@ struct FunctionBox : public ObjectBox
|
|||
FunctionBox *kids;
|
||||
FunctionBox *parent;
|
||||
Bindings bindings; /* bindings for this function */
|
||||
size_t bufStart;
|
||||
size_t bufEnd;
|
||||
uint16_t level;
|
||||
uint16_t ndefaults;
|
||||
StrictMode::StrictModeState strictModeState;
|
||||
|
|
|
@ -177,6 +177,8 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn,
|
|||
kids(NULL),
|
||||
parent(tc->sc->inFunction() ? tc->sc->funbox() : NULL),
|
||||
bindings(),
|
||||
bufStart(0),
|
||||
bufEnd(0),
|
||||
level(tc->staticLevel),
|
||||
ndefaults(0),
|
||||
strictModeState(sms),
|
||||
|
@ -1245,6 +1247,8 @@ Parser::functionArguments(ParseNode **listp, bool &hasRest)
|
|||
return false;
|
||||
}
|
||||
|
||||
tc->sc->funbox()->bufStart = tokenStream.offsetOfToken(tokenStream.currentToken());
|
||||
|
||||
hasRest = false;
|
||||
|
||||
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, this);
|
||||
|
@ -1625,12 +1629,16 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
|
|||
return NULL;
|
||||
|
||||
#if JS_HAS_EXPR_CLOSURES
|
||||
if (bodyType == StatementListBody)
|
||||
if (bodyType == StatementListBody) {
|
||||
#endif
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
|
||||
else if (kind == Statement && !MatchOrInsertSemicolon(context, &tokenStream))
|
||||
return NULL;
|
||||
#else
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
|
||||
funbox->bufEnd = tokenStream.offsetOfToken(tokenStream.currentToken()) + 1;
|
||||
#if JS_HAS_EXPR_CLOSURES
|
||||
} else {
|
||||
funbox->bufEnd = tokenStream.endOffset(tokenStream.currentToken());
|
||||
if (kind == Statement && !MatchOrInsertSemicolon(context, &tokenStream))
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
pn->pn_pos.end = tokenStream.currentToken().pos.end;
|
||||
|
||||
|
@ -1743,6 +1751,7 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
|
|||
ParseNode *
|
||||
Parser::functionStmt()
|
||||
{
|
||||
JS_ASSERT(tokenStream.currentToken().type == TOK_FUNCTION);
|
||||
RootedPropertyName name(context);
|
||||
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) {
|
||||
name = tokenStream.currentToken().name();
|
||||
|
@ -1764,6 +1773,7 @@ ParseNode *
|
|||
Parser::functionExpr()
|
||||
{
|
||||
RootedPropertyName name(context);
|
||||
JS_ASSERT(tokenStream.currentToken().type == TOK_FUNCTION);
|
||||
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME)
|
||||
name = tokenStream.currentToken().name();
|
||||
else
|
||||
|
@ -1889,6 +1899,7 @@ Parser::processDirectives(ParseNode *stmts)
|
|||
if (isDirective) {
|
||||
// It's a directive. Is it one we know?
|
||||
if (atom == context->runtime->atomState.useStrictAtom && !gotStrictMode) {
|
||||
tc->sc->setExplicitUseStrict();
|
||||
if (!setStrictMode(true))
|
||||
return false;
|
||||
gotStrictMode = true;
|
||||
|
|
|
@ -378,11 +378,11 @@ TokenStream::peekChars(int n, jschar *cp)
|
|||
const jschar *
|
||||
TokenStream::TokenBuf::findEOLMax(const jschar *p, size_t max)
|
||||
{
|
||||
JS_ASSERT(base <= p && p <= limit);
|
||||
JS_ASSERT(base_ <= p && p <= limit_);
|
||||
|
||||
size_t n = 0;
|
||||
while (true) {
|
||||
if (p >= limit)
|
||||
if (p >= limit_)
|
||||
break;
|
||||
if (n >= max)
|
||||
break;
|
||||
|
@ -1125,6 +1125,31 @@ TokenStream::matchUnicodeEscapeIdent(int32_t *cp)
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
TokenStream::endOffset(const Token &tok)
|
||||
{
|
||||
uint32_t lineno = tok.pos.begin.lineno;
|
||||
JS_ASSERT(lineno <= tok.pos.end.lineno);
|
||||
const jschar *end;
|
||||
if (lineno < tok.pos.end.lineno) {
|
||||
TokenBuf buf(tok.ptr, userbuf.addressOfNextRawChar() - userbuf.base());
|
||||
for (; lineno < tok.pos.end.lineno; lineno++) {
|
||||
jschar c;
|
||||
do {
|
||||
JS_ASSERT(buf.hasRawChars());
|
||||
c = buf.getRawChar();
|
||||
} while (!TokenBuf::isRawEOLChar(c));
|
||||
if (c == '\r' && buf.hasRawChars())
|
||||
buf.matchRawChar('\n');
|
||||
}
|
||||
end = buf.addressOfNextRawChar() + tok.pos.end.index;
|
||||
} else {
|
||||
end = tok.ptr + (tok.pos.end.index - tok.pos.begin.index);
|
||||
}
|
||||
JS_ASSERT(end <= userbuf.addressOfNextRawChar());
|
||||
return end - userbuf.base();
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function which returns true if the first length(q) characters in p are
|
||||
* the same as the characters in q.
|
||||
|
|
|
@ -495,6 +495,9 @@ class TokenStream
|
|||
TokenKind type = currentToken().type;
|
||||
return type == type1 || type == type2;
|
||||
}
|
||||
size_t offsetOfToken(const Token &tok) const {
|
||||
return tok.ptr - userbuf.base();
|
||||
}
|
||||
const CharBuffer &getTokenbuf() const { return tokenbuf; }
|
||||
const char *getFilename() const { return filename; }
|
||||
unsigned getLineno() const { return lineno; }
|
||||
|
@ -668,6 +671,12 @@ class TokenStream
|
|||
JS_ALWAYS_TRUE(matchToken(tt));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the offset into the source buffer of the end of the token.
|
||||
*/
|
||||
size_t endOffset(const Token &tok);
|
||||
|
||||
/*
|
||||
* Give up responsibility for managing the sourceMap filename's memory.
|
||||
*/
|
||||
|
@ -704,14 +713,22 @@ class TokenStream
|
|||
class TokenBuf {
|
||||
public:
|
||||
TokenBuf(const jschar *buf, size_t length)
|
||||
: base(buf), limit(buf + length), ptr(buf) { }
|
||||
: base_(buf), limit_(buf + length), ptr(buf) { }
|
||||
|
||||
bool hasRawChars() const {
|
||||
return ptr < limit;
|
||||
return ptr < limit_;
|
||||
}
|
||||
|
||||
bool atStart() const {
|
||||
return ptr == base;
|
||||
return ptr == base_;
|
||||
}
|
||||
|
||||
const jschar *base() const {
|
||||
return base_;
|
||||
}
|
||||
|
||||
const jschar *limit() const {
|
||||
return limit_;
|
||||
}
|
||||
|
||||
jschar getRawChar() {
|
||||
|
@ -771,8 +788,8 @@ class TokenStream
|
|||
const jschar *findEOLMax(const jschar *p, size_t max);
|
||||
|
||||
private:
|
||||
const jschar *base; /* base of buffer */
|
||||
const jschar *limit; /* limit for quick bounds check */
|
||||
const jschar *base_; /* base of buffer */
|
||||
const jschar *limit_; /* limit for quick bounds check */
|
||||
const jschar *ptr; /* next char to get */
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ class ContextFlags {
|
|||
friend struct SharedContext;
|
||||
friend struct FunctionBox;
|
||||
|
||||
// True if "use strict"; appears in the body instead of being inherited.
|
||||
bool hasExplicitUseStrict:1;
|
||||
|
||||
// The (static) bindings of this script need to support dynamic name
|
||||
// read/write access. Here, 'dynamic' means dynamic dictionary lookup on
|
||||
// the scope chain for a dynamic set of keys. The primary examples are:
|
||||
|
@ -106,7 +109,8 @@ class ContextFlags {
|
|||
|
||||
public:
|
||||
ContextFlags(JSContext *cx)
|
||||
: bindingsAccessedDynamically(false),
|
||||
: hasExplicitUseStrict(false),
|
||||
bindingsAccessedDynamically(false),
|
||||
funIsHeavyweight(false),
|
||||
funIsGenerator(false),
|
||||
funMightAliasLocals(false),
|
||||
|
@ -173,6 +177,7 @@ struct SharedContext {
|
|||
// functions below.
|
||||
#define INFUNC JS_ASSERT(inFunction())
|
||||
|
||||
bool hasExplicitUseStrict() const { return cxFlags.hasExplicitUseStrict; }
|
||||
bool bindingsAccessedDynamically() const { return cxFlags.bindingsAccessedDynamically; }
|
||||
bool funIsHeavyweight() const { INFUNC; return cxFlags.funIsHeavyweight; }
|
||||
bool funIsGenerator() const { INFUNC; return cxFlags.funIsGenerator; }
|
||||
|
@ -181,6 +186,7 @@ struct SharedContext {
|
|||
bool funArgumentsHasLocalBinding() const { INFUNC; return cxFlags.funArgumentsHasLocalBinding; }
|
||||
bool funDefinitelyNeedsArgsObj() const { INFUNC; return cxFlags.funDefinitelyNeedsArgsObj; }
|
||||
|
||||
void setExplicitUseStrict() { cxFlags.hasExplicitUseStrict = true; }
|
||||
void setBindingsAccessedDynamically() { cxFlags.bindingsAccessedDynamically = true; }
|
||||
void setFunIsHeavyweight() { cxFlags.funIsHeavyweight = true; }
|
||||
void setFunIsGenerator() { INFUNC; cxFlags.funIsGenerator = true; }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
actual = '';
|
||||
expected = 'function h(x, y) {\n return arguments;\n},2,4,8,';
|
||||
expected = 'function h(x, y) { return arguments; },2,4,8,';
|
||||
|
||||
function h(x, y) { return arguments; }
|
||||
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,46 +0,0 @@
|
|||
function f1(a=1) {}
|
||||
assertEq(f1.toString(), "function f1(a = 1) {\n}");
|
||||
function f2(a=1, b=2, c=3) {}
|
||||
assertEq(f2.toString(), "function f2(a = 1, b = 2, c = 3) {\n}");
|
||||
function f3(a, b, c=1, d=2) {}
|
||||
assertEq(f3.toString(), "function f3(a, b, c = 1, d = 2) {\n}");
|
||||
function f4(a, [b], c=1) {}
|
||||
assertEq(f4.toString(), "function f4(a, [b], c = 1) {\n}");
|
||||
function f5(a, b, c=1, ...rest) {}
|
||||
assertEq(f5.toString(), "function f5(a, b, c = 1, ...rest) {\n}");
|
||||
function f6(a, [b], c=1, ...rest) {}
|
||||
assertEq(f6.toString(), "function f6(a, [b], c = 1, ...rest) {\n}");
|
||||
function f7(a, c=d = 190) {}
|
||||
assertEq(f7.toString(), "function f7(a, c = d = 190) {\n}");
|
||||
function f8(a=(b = 8)) {
|
||||
function nested() {
|
||||
return a + b;
|
||||
}
|
||||
return nested;
|
||||
}
|
||||
assertEq(f8.toString(), "function f8(a = b = 8) {\n\n\
|
||||
function nested() {\n\
|
||||
return a + b;\n\
|
||||
}\n\n\
|
||||
return nested;\n\
|
||||
}");
|
||||
function f9(a, b, c={complexity : .5, is : 40 + great.prop}, d=[42], ...rest) {}
|
||||
assertEq(f9.toString(), "function f9(a, b, c = {complexity: 0.5, is: 40 + great.prop}, d = [42], ...rest) {\n}");
|
||||
function f10(a=12) { return arguments; }
|
||||
assertEq(f10.toString(), "function f10(a = 12) {\n return arguments;\n}");
|
||||
function f11(a=(0, c=1)) {}
|
||||
assertEq(f11.length, 1);
|
||||
var g = eval("(" + f11 + ")");
|
||||
assertEq(g.length, 1);
|
||||
function f12(a, b=4) {
|
||||
return b;
|
||||
function b() { }
|
||||
}
|
||||
assertEq(f12.toString(), "function f12(a, b = 4) {\n return b;\n\n function b() {\n }\n\n}");
|
||||
function f13(a, b=4, ...rest) {
|
||||
return b;
|
||||
function b() { }
|
||||
}
|
||||
assertEq(f13.toString(), "function f13(a, b = 4, ...rest) {\n return b;\n\n function b() {\n }\n\n}");
|
||||
function f14(x = let (y) 42, ...rest) {}
|
||||
assertEq(f14.toString(), "function f14(x = let (y) 42, ...rest) {\n}");
|
|
@ -3,10 +3,8 @@ function no_defaults(a, ...rest) {
|
|||
function rest() { return a; }
|
||||
}
|
||||
assertEq(typeof no_defaults(), "function");
|
||||
assertEq(no_defaults.toString(), "function no_defaults(a, ...rest) {\n return rest;\n\n function rest() {\n return a;\n }\n\n}");
|
||||
function with_defaults(a=42, ...rest) {
|
||||
return rest;
|
||||
function rest() { return a; }
|
||||
}
|
||||
assertEq(typeof with_defaults(), "function");
|
||||
assertEq(with_defaults.toString(), "function with_defaults(a = 42, ...rest) {\n return rest;\n\n function rest() {\n return a;\n }\n\n}");
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
g = (function (...rest) { return rest; });
|
||||
assertEq(g.toString(), "function (...rest) {\n return rest;\n}");
|
|
@ -1,9 +0,0 @@
|
|||
function test() {
|
||||
3 && x++;
|
||||
}
|
||||
assertEq(test.toString(), "function test() {\n 3 && x++;\n}");
|
||||
|
||||
function f() {
|
||||
a[1, 2]++;
|
||||
}
|
||||
assertEq(f.toString(), "function f() {\n a[1, 2]++;\n}");
|
|
@ -0,0 +1,6 @@
|
|||
function example(a, b, c) {
|
||||
var complicated = 3;
|
||||
perform_some_operations();
|
||||
}
|
||||
var myfun = function (a, b) a + b;
|
||||
assertEq(decompileThis(), snarf(thisFilename()));
|
|
@ -0,0 +1,18 @@
|
|||
var f = Function("a", "b", "return a + b;");
|
||||
assertEq(f.toString(), "function anonymous(a, b) { return a + b; }");
|
||||
assertEq(f.toSource(), "(function anonymous(a, b) { return a + b; })");
|
||||
assertEq(decompileFunction(f), f.toString());
|
||||
assertEq(decompileBody(f), "return a + b;");
|
||||
f = Function("a", "...rest", "return rest[42] + b;");
|
||||
assertEq(f.toString(), "function anonymous(a, ...rest) { return rest[42] + b; }");
|
||||
assertEq(f.toSource(), "(function anonymous(a, ...rest) { return rest[42] + b; })")
|
||||
assertEq(decompileFunction(f), f.toString());
|
||||
assertEq(decompileBody(f), "return rest[42] + b;");
|
||||
f = Function("x", "return let (y) x;");
|
||||
assertEq(f.toSource(), "(function anonymous(x) { return let (y) x; })");
|
||||
f = Function("");
|
||||
assertEq(f.toString(), "function anonymous() { }");
|
||||
f = Function("", "(abc)");
|
||||
assertEq(f.toString(), "function anonymous() { (abc) }");
|
||||
f = Function("", "return function (a, b) a + b;")();
|
||||
assertEq(f.toString(), "function (a, b) a + b");
|
|
@ -0,0 +1,32 @@
|
|||
function f1(foo, bar) foo + bar;
|
||||
assertEq(f1.toString(), "function f1(foo, bar) foo + bar");
|
||||
assertEq(f1.toString(), f1.toSource());
|
||||
assertEq(decompileFunction(f1), f1.toString());
|
||||
assertEq(decompileBody(f1), "foo + bar;");
|
||||
// No semicolon on purpose
|
||||
function f2(foo, bar) foo + bar
|
||||
assertEq(f2.toString(), "function f2(foo, bar) foo + bar");
|
||||
assertEq(f2.toString(), f2.toSource());
|
||||
var f3 = function (foo, bar) foo + bar;
|
||||
assertEq(f3.toSource(), "(function (foo, bar) foo + bar)");
|
||||
assertEq(f3.toString(), "function (foo, bar) foo + bar");
|
||||
// No semicolon on purpose
|
||||
var f4 = function (foo, bar) foo + bar
|
||||
assertEq(f4.toSource(), "(function (foo, bar) foo + bar)");
|
||||
assertEq(f4.toString(), "function (foo, bar) foo + bar");
|
||||
var f5 = function (foo, bar) foo + bar ;
|
||||
assertEq(f5.toSource(), "(function (foo, bar) foo + bar)");
|
||||
assertEq(f5.toString(), "function (foo, bar) foo + bar");
|
||||
var f6 = function (foo, bar) foo + bar; var a = 42
|
||||
assertEq(f6.toSource(), "(function (foo, bar) foo + bar)");
|
||||
assertEq(f6.toString(), "function (foo, bar) foo + bar");
|
||||
var f7 = function (foo, bar) foo + bar + '\
|
||||
long\
|
||||
string\
|
||||
test\
|
||||
'
|
||||
// a comment followed by some space
|
||||
|
||||
|
||||
assertEq(f7.toString(), "function (foo, bar) foo + bar + '\\\nlong\\\nstring\\\ntest\\\n'");
|
||||
assertEq(f7.toSource(), "(" + f7.toString() + ")");
|
|
@ -0,0 +1,2 @@
|
|||
assertEq(Function.prototype.toString(), "function () {\n}");
|
||||
assertEq(Function.prototype.toSource(), "function () {\n}");
|
|
@ -0,0 +1,7 @@
|
|||
var o = {get prop() a + b, set prop(x) a + b};
|
||||
var prop = Object.getOwnPropertyDescriptor(o, "prop");
|
||||
assertEq(prop.get.toString(), "function () a + b");
|
||||
assertEq(prop.get.toSource(), "(function () a + b)");
|
||||
assertEq(prop.set.toString(), "function (x) a + b");
|
||||
assertEq(prop.set.toSource(), "(function (x) a + b)");
|
||||
assertEq(o.toSource(), "({get prop () a + b, set prop (x) a + b})");
|
|
@ -0,0 +1,15 @@
|
|||
var f1 = function f0(a, b) { return a + b; }
|
||||
assertEq(f1.toSource(), "(function f0(a, b) { return a + b; })");
|
||||
assertEq(f1.toString(), "function f0(a, b) { return a + b; }");
|
||||
assertEq(decompileFunction(f1), f1.toString());
|
||||
assertEq(decompileBody(f1), "return a + b;");
|
||||
var f2 = function (a, b) { return a + b; };
|
||||
assertEq(f2.toSource(), "(function (a, b) { return a + b; })");
|
||||
assertEq(f2.toString(), "function (a, b) { return a + b; }");
|
||||
assertEq(decompileFunction(f2), f2.toString());
|
||||
assertEq(decompileBody(f2), "return a + b;");
|
||||
var f3 = (function (a, b) { return a + b; });
|
||||
assertEq(f3.toSource(), "(function (a, b) { return a + b; })");
|
||||
assertEq(f3.toString(), "function (a, b) { return a + b; }");
|
||||
assertEq(decompileFunction(f3), f3.toString());
|
||||
assertEq(decompileBody(f3), "return a + b;");
|
|
@ -0,0 +1,10 @@
|
|||
function f1(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
assertEq(f1.toString(), "function f1(a, b) {\n return a + b;\n}");
|
||||
assertEq(f1.toSource(), f1.toString());
|
||||
function f2(a, /* ))))pernicious comment */ b,
|
||||
c, // another comment((
|
||||
d) {}
|
||||
assertEq(f2.toString(), "function f2(a, /* ))))pernicious comment */ b,\n c, // another comment((\n d) {}");
|
||||
assertEq(decompileBody(f2), "");
|
|
@ -0,0 +1,12 @@
|
|||
function outer() {
|
||||
"use strict";
|
||||
function inner() {}
|
||||
return inner;
|
||||
}
|
||||
assertEq(outer().toString().indexOf("use strict") != -1, true);
|
||||
function outer2() {
|
||||
"use strict";
|
||||
function inner() blah;
|
||||
return inner;
|
||||
}
|
||||
assertEq(outer2().toString().indexOf("/* use strict */") != -1, true);
|
|
@ -8,7 +8,7 @@ function test(str, arg, result)
|
|||
var fun = new Function('x', str);
|
||||
|
||||
var got = fun.toSource().replace(/\n/g,'');
|
||||
var expect = '(function anonymous(x) {' + str + '})';
|
||||
var expect = '(function anonymous(x) { ' + str + ' })';
|
||||
if (got !== expect) {
|
||||
print("GOT: " + got);
|
||||
print("EXPECT: " + expect);
|
||||
|
@ -341,20 +341,3 @@ test('switch (x) {case 3:let y;return 3;case 4:let z;return 4;default:return x;}
|
|||
test('switch (x) {case 3:let x;break;default:if (x === undefined) {return "ponies";}}');
|
||||
test('switch (x) {case 3:default:let y;let (y = x) {return y;}}');
|
||||
isError('switch (x) {case 3:let y;return 3;case 4:let y;return 4;default:;}');
|
||||
|
||||
// test weird cases where the decompiler changes tokens
|
||||
function testWeird(str, printedAs, arg, result)
|
||||
{
|
||||
var fun = new Function('x', str);
|
||||
|
||||
// this is lame and doesn't normalize whitespace so if an assert fails
|
||||
// here, see if its just whitespace and fix the caller
|
||||
assertEq(fun.toSource(), '(function anonymous(x) {' + printedAs + '})');
|
||||
|
||||
test(printedAs, arg, result);
|
||||
}
|
||||
|
||||
testWeird('let y = x;return x;', 'var y = x;return x;');
|
||||
testWeird('let y = 1, y = x;return y;', 'var y = 1, y = x;return y;');
|
||||
testWeird('return let ({x:x, y:y} = x) x + y', 'return let ({x, y} = x) x + y;', {x:'pon', y:'ies'});
|
||||
testWeird('let ({x:x, y:y} = x) {return x + y;}', 'let ({x, y} = x) {return x + y;}', {x:'pon', y:'ies'});
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
var g = newGlobal('new-compartment');
|
||||
var dbg = Debugger(g);
|
||||
dbg.onNewScript = function (s) {
|
||||
eval(longScript);
|
||||
}
|
||||
const longScript = "var x = 1;\n" + new Array(5000).join("x + ") + "x";
|
||||
g.eval(longScript);
|
|
@ -116,7 +116,7 @@ MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 62, 0, JSEXN_SYNTAXERR, "unmatched ) in r
|
|||
MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 63, 0, JSEXN_INTERNALERR, "data are to big to encode")
|
||||
MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE, 64, 1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range")
|
||||
MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 65, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)")
|
||||
MSG_DEF(JSMSG_UNUSED66, 66, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_SOURCE_TOO_LONG, 66, 0, JSEXN_RANGEERR, "source is too long")
|
||||
MSG_DEF(JSMSG_UNUSED67, 67, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC, 68, 0, JSEXN_INTERNALERR, "bad script XDR magic number")
|
||||
MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
|
||||
|
|
|
@ -230,3 +230,26 @@ BEGIN_TEST(testXDR_bug516827)
|
|||
return true;
|
||||
}
|
||||
END_TEST(testXDR_bug516827)
|
||||
|
||||
BEGIN_TEST(testXDR_source)
|
||||
{
|
||||
const char *samples[] = {
|
||||
// This can't possibly fail to compress well, can it?
|
||||
"function f(x) { return x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x }",
|
||||
"short",
|
||||
NULL
|
||||
};
|
||||
for (const char **s = samples; *s; s++) {
|
||||
JSScript *script = JS_CompileScript(cx, global, *s, strlen(*s), __FILE__, __LINE__);
|
||||
CHECK(script);
|
||||
script = FreezeThaw(cx, script);
|
||||
CHECK(script);
|
||||
JSString *out = JS_DecompileScript(cx, script, "testing", 0);
|
||||
CHECK(out);
|
||||
JSBool equal;
|
||||
CHECK(JS_StringEqualsAscii(cx, out, *s, &equal));
|
||||
CHECK(equal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
END_TEST(testXDR_source)
|
||||
|
|
|
@ -810,6 +810,9 @@ JSRuntime::JSRuntime()
|
|||
data(NULL),
|
||||
gcLock(NULL),
|
||||
gcHelperThread(thisFromCtor()),
|
||||
#ifdef JS_THREADSAFE
|
||||
sourceCompressorThread(thisFromCtor()),
|
||||
#endif
|
||||
defaultFreeOp_(thisFromCtor(), false, false),
|
||||
debuggerMutations(0),
|
||||
securityCallbacks(const_cast<JSSecurityCallbacks *>(&NullSecurityCallbacks)),
|
||||
|
@ -829,6 +832,7 @@ JSRuntime::JSRuntime()
|
|||
sameCompartmentWrapObjectCallback(NULL),
|
||||
preWrapObjectCallback(NULL),
|
||||
preserveWrapperCallback(NULL),
|
||||
scriptSources(NULL),
|
||||
#ifdef DEBUG
|
||||
noGCOrAllocationCheck(0),
|
||||
#endif
|
||||
|
@ -894,6 +898,11 @@ JSRuntime::init(uint32_t maxbytes)
|
|||
if (!scriptFilenameTable.init())
|
||||
return false;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (!sourceCompressorThread.init())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!evalCache.init())
|
||||
return false;
|
||||
|
||||
|
@ -919,6 +928,10 @@ JSRuntime::~JSRuntime()
|
|||
*/
|
||||
FreeScriptFilenames(this);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
sourceCompressorThread.finish();
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
|
||||
if (!JS_CLIST_IS_EMPTY(&contextList)) {
|
||||
|
@ -5324,27 +5337,12 @@ JS_PUBLIC_API(JSString *)
|
|||
JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, unsigned indent)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
JSPrinter *jp;
|
||||
JSString *str;
|
||||
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
#ifdef DEBUG
|
||||
if (cx->compartment != script->compartment())
|
||||
CompartmentChecker::fail(cx->compartment, script->compartment());
|
||||
#endif
|
||||
jp = js_NewPrinter(cx, name, NULL,
|
||||
indent & ~JS_DONT_PRETTY_PRINT,
|
||||
!(indent & JS_DONT_PRETTY_PRINT),
|
||||
false, false);
|
||||
if (!jp)
|
||||
return NULL;
|
||||
if (js_DecompileScript(jp, script))
|
||||
str = js_GetPrinterOutput(jp);
|
||||
else
|
||||
str = NULL;
|
||||
js_DestroyPrinter(jp);
|
||||
return str;
|
||||
if (script->function())
|
||||
return JS_DecompileFunction(cx, script->function(), indent);
|
||||
return script->sourceData(cx);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
|
@ -5354,10 +5352,7 @@ JS_DecompileFunction(JSContext *cx, JSFunction *fun, unsigned indent)
|
|||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, fun);
|
||||
return js_DecompileToString(cx, "JS_DecompileFunction", fun,
|
||||
indent & ~JS_DONT_PRETTY_PRINT,
|
||||
!(indent & JS_DONT_PRETTY_PRINT),
|
||||
false, false, js_DecompileFunction);
|
||||
return fun->toString(cx, false, !(indent & JS_DONT_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
|
@ -5367,10 +5362,7 @@ JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, unsigned indent)
|
|||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, fun);
|
||||
return js_DecompileToString(cx, "JS_DecompileFunctionBody", fun,
|
||||
indent & ~JS_DONT_PRETTY_PRINT,
|
||||
!(indent & JS_DONT_PRETTY_PRINT),
|
||||
false, false, js_DecompileFunctionBody);
|
||||
return fun->toString(cx, true, !(indent & JS_DONT_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
JS_NEVER_INLINE JS_PUBLIC_API(JSBool)
|
||||
|
|
|
@ -159,18 +159,18 @@ struct ConservativeGCData
|
|||
}
|
||||
};
|
||||
|
||||
class ToSourceCache
|
||||
class SourceDataCache
|
||||
{
|
||||
typedef HashMap<JSFunction *,
|
||||
JSString *,
|
||||
DefaultHasher<JSFunction *>,
|
||||
typedef HashMap<ScriptSource *,
|
||||
JSFixedString *,
|
||||
DefaultHasher<ScriptSource *>,
|
||||
SystemAllocPolicy> Map;
|
||||
Map *map_;
|
||||
public:
|
||||
ToSourceCache() : map_(NULL) {}
|
||||
JSString *lookup(JSFunction *fun);
|
||||
void put(JSFunction *fun, JSString *);
|
||||
void purge();
|
||||
Map *map_;
|
||||
public:
|
||||
SourceDataCache() : map_(NULL) {}
|
||||
JSFixedString *lookup(ScriptSource *ss);
|
||||
void put(ScriptSource *ss, JSFixedString *);
|
||||
void purge();
|
||||
};
|
||||
|
||||
struct EvalCacheLookup
|
||||
|
@ -751,6 +751,10 @@ struct JSRuntime : js::RuntimeFriendFields
|
|||
|
||||
js::GCHelperThread gcHelperThread;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
js::SourceCompressorThread sourceCompressorThread;
|
||||
#endif
|
||||
|
||||
private:
|
||||
js::FreeOp defaultFreeOp_;
|
||||
|
||||
|
@ -800,7 +804,7 @@ struct JSRuntime : js::RuntimeFriendFields
|
|||
js::PropertyCache propertyCache;
|
||||
js::NewObjectCache newObjectCache;
|
||||
js::NativeIterCache nativeIterCache;
|
||||
js::ToSourceCache toSourceCache;
|
||||
js::SourceDataCache sourceDataCache;
|
||||
js::EvalCache evalCache;
|
||||
|
||||
/* State used by jsdtoa.cpp. */
|
||||
|
@ -830,6 +834,8 @@ struct JSRuntime : js::RuntimeFriendFields
|
|||
|
||||
js::ScriptFilenameTable scriptFilenameTable;
|
||||
|
||||
js::ScriptSource *scriptSources;
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t noGCOrAllocationCheck;
|
||||
#endif
|
||||
|
|
203
js/src/jsfun.cpp
203
js/src/jsfun.cpp
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "mozilla/RangedPtr.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include "gc/Marking.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/ScopeObject.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
#include "vm/Xdr.h"
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
|
@ -521,34 +523,177 @@ JS_FRIEND_DATA(Class) js::FunctionClass = {
|
|||
fun_trace
|
||||
};
|
||||
|
||||
JSString *
|
||||
ToSourceCache::lookup(JSFunction *fun)
|
||||
{
|
||||
if (!map_)
|
||||
return NULL;
|
||||
if (Map::Ptr p = map_->lookup(fun))
|
||||
return p->value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ToSourceCache::put(JSFunction *fun, JSString *str)
|
||||
/* Find the body of a function (not including braces). */
|
||||
static bool
|
||||
FindBody(JSContext *cx, JSFunction *fun, const jschar *chars, size_t length,
|
||||
size_t *bodyStart, size_t *bodyEnd)
|
||||
{
|
||||
if (!map_) {
|
||||
map_ = OffTheBooks::new_<Map>();
|
||||
if (!map_)
|
||||
return;
|
||||
map_->init();
|
||||
// We don't need principals, since those are only used for error reporting.
|
||||
TokenStream ts(cx, NULL, NULL, chars, length, "internal-FindBody", 0,
|
||||
fun->script()->getVersion(), NULL);
|
||||
JS_ASSERT(chars[0] == '(');
|
||||
int nest = 0;
|
||||
bool onward = true;
|
||||
// Skip arguments list.
|
||||
do {
|
||||
switch (ts.getToken()) {
|
||||
case TOK_LP:
|
||||
nest++;
|
||||
break;
|
||||
case TOK_RP:
|
||||
if (--nest == 0)
|
||||
onward = false;
|
||||
break;
|
||||
case TOK_ERROR:
|
||||
// Must be memory.
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (onward);
|
||||
DebugOnly<bool> braced = ts.matchToken(TOK_LC);
|
||||
if (ts.getToken() == TOK_ERROR)
|
||||
return false;
|
||||
JS_ASSERT(!!(fun->flags & JSFUN_EXPR_CLOSURE) ^ braced);
|
||||
*bodyStart = ts.offsetOfToken(ts.currentToken());
|
||||
RangedPtr<const jschar> p(chars, length);
|
||||
p = chars + length;
|
||||
for (; unicode::IsSpaceOrBOM2(p[-1]); p--)
|
||||
;
|
||||
if (p[-1] == '}') {
|
||||
p--;
|
||||
for (; unicode::IsSpaceOrBOM2(p[-1]); p--)
|
||||
;
|
||||
} else {
|
||||
JS_ASSERT(!braced);
|
||||
}
|
||||
|
||||
(void) map_->put(fun, str);
|
||||
*bodyEnd = p.get() - chars;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ToSourceCache::purge()
|
||||
JSString *
|
||||
JSFunction::toString(JSContext *cx, bool bodyOnly, bool lambdaParen)
|
||||
{
|
||||
Foreground::delete_(map_);
|
||||
map_ = NULL;
|
||||
StringBuffer out(cx);
|
||||
|
||||
if (!bodyOnly) {
|
||||
// If we're not in pretty mode, put parentheses around lambda functions.
|
||||
if (isInterpreted() && !lambdaParen && (flags & JSFUN_LAMBDA)) {
|
||||
if (!out.append("("))
|
||||
return NULL;
|
||||
}
|
||||
if (!out.append("function "))
|
||||
return NULL;
|
||||
if (atom) {
|
||||
if (!out.append(atom))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (isInterpreted()) {
|
||||
RootedString src(cx, script()->sourceData(cx));
|
||||
if (!src)
|
||||
return NULL;
|
||||
const jschar *chars = src->getChars(cx);
|
||||
if (!chars)
|
||||
return NULL;
|
||||
bool exprBody = flags & JSFUN_EXPR_CLOSURE;
|
||||
|
||||
// The source data for functions created by calling the Function
|
||||
// constructor is only the function's body.
|
||||
bool funCon = script()->sourceStart == 0 && script()->source->argumentsNotIncluded();
|
||||
|
||||
// Functions created with the constructor should not be using the
|
||||
// expression body extension.
|
||||
JS_ASSERT_IF(funCon, !exprBody);
|
||||
JS_ASSERT_IF(!funCon, src->length() > 0 && chars[0] == '(');
|
||||
|
||||
// If a function inherits strict mode by having scopes above it that
|
||||
// have "use strict", we insert "use strict" into the body of the
|
||||
// function. This ensures that if the result of toString is evaled, the
|
||||
// resulting function will have the same semantics.
|
||||
bool addUseStrict = script()->strictModeCode && !script()->explicitUseStrict;
|
||||
|
||||
// Functions created with the constructor can't have inherited strict
|
||||
// mode.
|
||||
JS_ASSERT(!funCon || !addUseStrict);
|
||||
bool buildBody = funCon && !bodyOnly;
|
||||
if (buildBody) {
|
||||
// This function was created with the Function constructor. We don't
|
||||
// have source for the arguments, so we have to generate that. Part
|
||||
// of bug 755821 should be cobbling the arguments passed into the
|
||||
// Function constructor into the source string.
|
||||
if (!out.append("("))
|
||||
return NULL;
|
||||
|
||||
// Fish out the argument names.
|
||||
BindingVector *localNames = cx->new_<BindingVector>(cx);
|
||||
js::ScopedDeletePtr<BindingVector> freeNames(localNames);
|
||||
if (!GetOrderedBindings(cx, script()->bindings, localNames))
|
||||
return NULL;
|
||||
for (unsigned i = 0; i < nargs; i++) {
|
||||
if ((i && !out.append(", ")) ||
|
||||
(i == unsigned(nargs - 1) && hasRest() && !out.append("...")) ||
|
||||
!out.append((*localNames)[i].maybeName)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!out.append(") { "))
|
||||
return NULL;
|
||||
}
|
||||
if ((bodyOnly && !funCon) || addUseStrict) {
|
||||
// We need to get at the body either because we're only supposed to
|
||||
// return the body or we need to insert "use strict" into the body.
|
||||
JS_ASSERT(!buildBody);
|
||||
size_t bodyStart = 0, bodyEnd = 0;
|
||||
if (!FindBody(cx, this, chars, src->length(), &bodyStart, &bodyEnd))
|
||||
return NULL;
|
||||
|
||||
if (addUseStrict) {
|
||||
// Output source up to beginning of body.
|
||||
if (!out.append(chars, bodyStart))
|
||||
return NULL;
|
||||
if (exprBody) {
|
||||
// We can't insert a statement into a function with an
|
||||
// expression body. Do what the decompiler did, and insert a
|
||||
// comment.
|
||||
if (!out.append("/* use strict */ "))
|
||||
return NULL;
|
||||
} else {
|
||||
if (!out.append("\"use strict\";\n"))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Output just the body (for bodyOnly) or the body and possibly
|
||||
// closing braces (for addUseStrict).
|
||||
size_t dependentEnd = (bodyOnly) ? bodyEnd : src->length();
|
||||
if (!out.append(chars + bodyStart, dependentEnd - bodyStart))
|
||||
return NULL;
|
||||
} else {
|
||||
if (!out.append(src))
|
||||
return NULL;
|
||||
}
|
||||
if (buildBody) {
|
||||
if (!out.append(" }"))
|
||||
return NULL;
|
||||
}
|
||||
if (bodyOnly) {
|
||||
// Slap a semicolon on the end of functions with an expression body.
|
||||
if (exprBody && !out.append(";"))
|
||||
return NULL;
|
||||
} else if (!lambdaParen && (flags & JSFUN_LAMBDA)) {
|
||||
if (!out.append(")"))
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(!(flags & JSFUN_EXPR_CLOSURE));
|
||||
if ((!bodyOnly && !out.append("() {\n ")) ||
|
||||
!out.append("[native code]") ||
|
||||
(!bodyOnly && !out.append("\n}")))
|
||||
return NULL;
|
||||
}
|
||||
return out.finishString();
|
||||
}
|
||||
|
||||
JSString *
|
||||
|
@ -568,19 +713,7 @@ fun_toStringHelper(JSContext *cx, JSObject *obj, unsigned indent)
|
|||
if (!fun)
|
||||
return NULL;
|
||||
|
||||
if (!indent) {
|
||||
if (JSString *str = cx->runtime->toSourceCache.lookup(fun))
|
||||
return str;
|
||||
}
|
||||
|
||||
JSString *str = JS_DecompileFunction(cx, fun, indent);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
if (!indent)
|
||||
cx->runtime->toSourceCache.put(fun, str);
|
||||
|
||||
return str;
|
||||
return fun->toString(cx, false, indent != JS_DONT_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
|
|
@ -153,6 +153,8 @@ struct JSFunction : public JSObject
|
|||
inline const js::Value &getBoundFunctionArgument(unsigned which) const;
|
||||
inline size_t getBoundFunctionArgumentCount() const;
|
||||
|
||||
JSString *toString(JSContext *cx, bool bodyOnly, bool pretty);
|
||||
|
||||
private:
|
||||
inline js::FunctionExtended *toExtended();
|
||||
inline const js::FunctionExtended *toExtended() const;
|
||||
|
|
|
@ -3082,7 +3082,7 @@ PurgeRuntime(JSTracer *trc)
|
|||
rt->propertyCache.purge(rt);
|
||||
rt->newObjectCache.purge();
|
||||
rt->nativeIterCache.purge();
|
||||
rt->toSourceCache.purge();
|
||||
rt->sourceDataCache.purge();
|
||||
rt->evalCache.clear();
|
||||
|
||||
for (ContextIter acx(rt); !acx.done(); acx.next())
|
||||
|
@ -3487,8 +3487,10 @@ SweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool *startBackgroundSweep)
|
|||
* script and calls rt->destroyScriptHook, the hook can still access the
|
||||
* script's filename. See bug 323267.
|
||||
*/
|
||||
if (rt->gcIsFull)
|
||||
if (rt->gcIsFull) {
|
||||
SweepScriptFilenames(rt);
|
||||
ScriptSource::sweep(rt);
|
||||
}
|
||||
|
||||
/*
|
||||
* This removes compartments from rt->compartment, so we do it last to make
|
||||
|
|
|
@ -356,7 +356,10 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
|||
NeedsArgsObj,
|
||||
OwnFilename,
|
||||
ParentFilename,
|
||||
IsGenerator
|
||||
IsGenerator,
|
||||
OwnSource,
|
||||
ParentSource,
|
||||
ExplicitUseStrict
|
||||
};
|
||||
|
||||
uint32_t length, lineno, nslots;
|
||||
|
@ -500,6 +503,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
|||
scriptBits |= (1 << SavedCallerFun);
|
||||
if (script->strictModeCode)
|
||||
scriptBits |= (1 << StrictModeCode);
|
||||
if (script->explicitUseStrict)
|
||||
scriptBits |= (1 << ExplicitUseStrict);
|
||||
if (script->bindingsAccessedDynamically)
|
||||
scriptBits |= (1 << ContainsDynamicNameAccess);
|
||||
if (script->funHasExtensibleScope)
|
||||
|
@ -513,6 +518,9 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
|||
? (1 << ParentFilename)
|
||||
: (1 << OwnFilename);
|
||||
}
|
||||
scriptBits |= (enclosingScript && enclosingScript->source == script->source)
|
||||
? (1 << ParentSource)
|
||||
: (1 << OwnSource);
|
||||
if (script->isGenerator)
|
||||
scriptBits |= (1 << IsGenerator);
|
||||
|
||||
|
@ -565,7 +573,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
|||
/* compileAndGo = */ false,
|
||||
!!(scriptBits & (1 << NoScriptRval)),
|
||||
version_,
|
||||
/* staticLevel = */ 0);
|
||||
/* staticLevel = */ 0,
|
||||
NULL, 0, 0);
|
||||
if (!script || !JSScript::partiallyInit(cx, script,
|
||||
length, nsrcnotes, natoms, nobjects,
|
||||
nregexps, ntrynotes, nconsts, nClosedArgs,
|
||||
|
@ -583,6 +592,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
|||
|
||||
if (scriptBits & (1 << StrictModeCode))
|
||||
script->strictModeCode = true;
|
||||
if (scriptBits & (1 << ExplicitUseStrict))
|
||||
script->explicitUseStrict = true;
|
||||
if (scriptBits & (1 << ContainsDynamicNameAccess))
|
||||
script->bindingsAccessedDynamically = true;
|
||||
if (scriptBits & (1 << FunHasExtensibleScope))
|
||||
|
@ -621,6 +632,19 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
|||
script->filename = enclosingScript->filename;
|
||||
}
|
||||
|
||||
if (scriptBits & (1 << OwnSource)) {
|
||||
if (!ScriptSource::performXDR<mode>(xdr, &script->source))
|
||||
return false;
|
||||
} else if (scriptBits & (1 << ParentSource)) {
|
||||
JS_ASSERT(enclosingScript);
|
||||
if (mode == XDR_DECODE)
|
||||
script->source = enclosingScript->source;
|
||||
}
|
||||
if (!xdr->codeUint32(&script->sourceStart))
|
||||
return false;
|
||||
if (!xdr->codeUint32(&script->sourceEnd))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
script->lineno = lineno;
|
||||
script->nslots = uint16_t(nslots);
|
||||
|
@ -932,6 +956,373 @@ JSScript::destroySourceMap(FreeOp *fop)
|
|||
fop->free_(releaseSourceMap());
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
void
|
||||
SourceCompressorThread::compressorThread(void *arg)
|
||||
{
|
||||
PR_SetCurrentThreadName("JS Source Compressing Thread");
|
||||
static_cast<SourceCompressorThread *>(arg)->threadLoop();
|
||||
}
|
||||
|
||||
bool
|
||||
SourceCompressorThread::init()
|
||||
{
|
||||
JS_ASSERT(!thread);
|
||||
lock = PR_NewLock();
|
||||
if (!lock)
|
||||
return false;
|
||||
wakeup = PR_NewCondVar(lock);
|
||||
if (!wakeup)
|
||||
return false;
|
||||
done = PR_NewCondVar(lock);
|
||||
if (!done)
|
||||
return false;
|
||||
thread = PR_CreateThread(PR_USER_THREAD, compressorThread, this, PR_PRIORITY_NORMAL,
|
||||
PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
if (!thread)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SourceCompressorThread::finish()
|
||||
{
|
||||
if (thread) {
|
||||
PR_Lock(lock);
|
||||
// We should only be compressing things when in the compiler.
|
||||
JS_ASSERT(state == IDLE);
|
||||
PR_NotifyCondVar(wakeup);
|
||||
state = SHUTDOWN;
|
||||
PR_Unlock(lock);
|
||||
PR_JoinThread(thread);
|
||||
}
|
||||
if (wakeup)
|
||||
PR_DestroyCondVar(wakeup);
|
||||
if (done)
|
||||
PR_DestroyCondVar(done);
|
||||
if (lock)
|
||||
PR_DestroyLock(lock);
|
||||
}
|
||||
|
||||
void
|
||||
SourceCompressorThread::threadLoop()
|
||||
{
|
||||
PR_Lock(lock);
|
||||
while (true) {
|
||||
switch (state) {
|
||||
case SHUTDOWN:
|
||||
PR_Unlock(lock);
|
||||
return;
|
||||
case IDLE:
|
||||
PR_WaitCondVar(wakeup, PR_INTERVAL_NO_TIMEOUT);
|
||||
break;
|
||||
case COMPRESSING:
|
||||
JS_ASSERT(tok);
|
||||
JS_ASSERT(!tok->ss->ready());
|
||||
tok->ss->considerCompressing(rt, tok->chars);
|
||||
// We hold the lock, so no one should have changed this.
|
||||
JS_ASSERT(state == COMPRESSING);
|
||||
state = IDLE;
|
||||
PR_NotifyCondVar(done);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceCompressorThread::compress(SourceCompressionToken *sct)
|
||||
{
|
||||
if (tok)
|
||||
// We have reentered the compiler. (This can happen through the
|
||||
// debugger.) Complete the current compression before starting the next
|
||||
// one.
|
||||
waitOnCompression(tok);
|
||||
JS_ASSERT(state == IDLE);
|
||||
JS_ASSERT(!tok);
|
||||
PR_Lock(lock);
|
||||
tok = sct;
|
||||
state = COMPRESSING;
|
||||
PR_NotifyCondVar(wakeup);
|
||||
PR_Unlock(lock);
|
||||
}
|
||||
|
||||
void
|
||||
SourceCompressorThread::waitOnCompression(SourceCompressionToken *userTok)
|
||||
{
|
||||
JS_ASSERT(userTok == tok);
|
||||
JS_ASSERT(!tok->ss->onRuntime());
|
||||
PR_Lock(lock);
|
||||
if (state == COMPRESSING)
|
||||
PR_WaitCondVar(done, PR_INTERVAL_NO_TIMEOUT);
|
||||
JS_ASSERT(state == IDLE);
|
||||
JS_ASSERT(tok->ss->ready());
|
||||
tok->ss = NULL;
|
||||
tok->chars = NULL;
|
||||
tok = NULL;
|
||||
PR_Unlock(lock);
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
JSFixedString *
|
||||
JSScript::sourceData(JSContext *cx)
|
||||
{
|
||||
return source->substring(cx, sourceStart, sourceEnd);
|
||||
}
|
||||
|
||||
JSFixedString *
|
||||
SourceDataCache::lookup(ScriptSource *ss)
|
||||
{
|
||||
if (!map_)
|
||||
return NULL;
|
||||
if (Map::Ptr p = map_->lookup(ss))
|
||||
return p->value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SourceDataCache::put(ScriptSource *ss, JSFixedString *str)
|
||||
{
|
||||
if (!map_) {
|
||||
map_ = OffTheBooks::new_<Map>();
|
||||
if (!map_)
|
||||
return;
|
||||
if (!map_->init()) {
|
||||
purge();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
(void) map_->put(ss, str);
|
||||
}
|
||||
|
||||
void
|
||||
SourceDataCache::purge()
|
||||
{
|
||||
Foreground::delete_(map_);
|
||||
map_ = NULL;
|
||||
}
|
||||
|
||||
JSFixedString *
|
||||
ScriptSource::substring(JSContext *cx, uint32_t start, uint32_t stop)
|
||||
{
|
||||
JS_ASSERT(ready());
|
||||
const jschar *chars;
|
||||
Rooted<JSFixedString *> cached(cx, NULL);
|
||||
if (compressed()) {
|
||||
cached = cx->runtime->sourceDataCache.lookup(this);
|
||||
if (!cached) {
|
||||
const size_t memlen = sizeof(jschar) * (length_ + 1);
|
||||
jschar *decompressed = static_cast<jschar *>(cx->malloc_(memlen));
|
||||
if (!decompressed)
|
||||
return NULL;
|
||||
if (!DecompressString(data.compressed, compressedLength,
|
||||
reinterpret_cast<unsigned char *>(decompressed), memlen)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
cx->free_(decompressed);
|
||||
return NULL;
|
||||
}
|
||||
decompressed[length_] = 0;
|
||||
cached = js_NewString(cx, decompressed, length_);
|
||||
if (!cached) {
|
||||
cx->free_(decompressed);
|
||||
return NULL;
|
||||
}
|
||||
cx->runtime->sourceDataCache.put(this, cached);
|
||||
}
|
||||
chars = cached->getChars(cx);
|
||||
JS_ASSERT(chars);
|
||||
} else {
|
||||
chars = data.source;
|
||||
}
|
||||
return js_NewStringCopyN(cx, chars + start, stop - start);
|
||||
}
|
||||
|
||||
ScriptSource *
|
||||
ScriptSource::createFromSource(JSContext *cx, const jschar *src, uint32_t length,
|
||||
bool argumentsNotIncluded, SourceCompressionToken *tok)
|
||||
{
|
||||
ScriptSource *ss = static_cast<ScriptSource *>(cx->malloc_(sizeof(*ss)));
|
||||
if (!ss)
|
||||
return NULL;
|
||||
const size_t memlen = length * sizeof(jschar);
|
||||
ss->data.compressed = static_cast<unsigned char *>(cx->malloc_(memlen));
|
||||
if (!ss->data.compressed) {
|
||||
cx->free_(ss);
|
||||
return NULL;
|
||||
}
|
||||
ss->next = NULL;
|
||||
ss->length_ = length;
|
||||
ss->marked = ss->onRuntime_ = false;
|
||||
ss->argumentsNotIncluded_ = argumentsNotIncluded;
|
||||
#ifdef DEBUG
|
||||
ss->ready_ = false;
|
||||
#endif
|
||||
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
/*
|
||||
* During the IGC we need to ensure that source is marked whenever it is
|
||||
* accessed even if the name was already in the table. At this point old
|
||||
* scripts pointing to the source may no longer be reachable.
|
||||
*/
|
||||
if (cx->runtime->gcIncrementalState == MARK && cx->runtime->gcIsFull)
|
||||
ss->marked = true;
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
if (tok) {
|
||||
tok->ss = ss;
|
||||
tok->chars = src;
|
||||
cx->runtime->sourceCompressorThread.compress(tok);
|
||||
} else
|
||||
#endif
|
||||
ss->considerCompressing(cx->runtime, src);
|
||||
|
||||
|
||||
return ss;
|
||||
}
|
||||
|
||||
void
|
||||
ScriptSource::considerCompressing(JSRuntime *rt, const jschar *src)
|
||||
{
|
||||
JS_ASSERT(!ready());
|
||||
const size_t memlen = length_ * sizeof(jschar);
|
||||
const size_t COMPRESS_THRESHOLD = 512;
|
||||
|
||||
size_t compressedLen;
|
||||
if (memlen >= COMPRESS_THRESHOLD &&
|
||||
TryCompressString(reinterpret_cast<const unsigned char *>(src), memlen,
|
||||
data.compressed, &compressedLen))
|
||||
{
|
||||
JS_ASSERT(compressedLen < memlen);
|
||||
compressedLength = compressedLen;
|
||||
void *mem = rt->realloc_(data.compressed, compressedLength);
|
||||
data.compressed = static_cast<unsigned char *>(mem);
|
||||
JS_ASSERT(data.compressed);
|
||||
} else {
|
||||
compressedLength = 0;
|
||||
PodCopy(data.source, src, length_);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
ready_ = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SourceCompressionToken::ensureReady()
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
rt->sourceCompressorThread.waitOnCompression(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ScriptSource::attachToRuntime(JSRuntime *rt)
|
||||
{
|
||||
JS_ASSERT(!onRuntime());
|
||||
next = rt->scriptSources;
|
||||
rt->scriptSources = this;
|
||||
onRuntime_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
ScriptSource::destroy(JSRuntime *rt)
|
||||
{
|
||||
JS_ASSERT(ready());
|
||||
JS_ASSERT(onRuntime());
|
||||
rt->free_(data.compressed);
|
||||
onRuntime_ = marked = false;
|
||||
#ifdef DEBUG
|
||||
ready_ = false;
|
||||
#endif
|
||||
rt->free_(this);
|
||||
}
|
||||
|
||||
void
|
||||
ScriptSource::sweep(JSRuntime *rt)
|
||||
{
|
||||
ScriptSource *next = rt->scriptSources, **prev = &rt->scriptSources;
|
||||
while (next) {
|
||||
ScriptSource *cur = next;
|
||||
next = cur->next;
|
||||
JS_ASSERT(cur->ready());
|
||||
JS_ASSERT(cur->onRuntime());
|
||||
if (cur->marked) {
|
||||
cur->marked = false;
|
||||
prev = &cur->next;
|
||||
} else {
|
||||
*prev = next;
|
||||
cur->destroy(rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
ScriptSource::performXDR(XDRState<mode> *xdr, ScriptSource **ssp)
|
||||
{
|
||||
class Cleanup {
|
||||
JSContext *cx;
|
||||
ScriptSource *ss;
|
||||
public:
|
||||
explicit Cleanup(JSContext *cx)
|
||||
: cx(cx), ss(NULL) {}
|
||||
~Cleanup()
|
||||
{
|
||||
if (ss) {
|
||||
if (ss->data.compressed)
|
||||
cx->free_(ss->data.compressed);
|
||||
cx->free_(ss);
|
||||
}
|
||||
}
|
||||
void protect(ScriptSource *source) { ss = source; }
|
||||
void release() { ss = NULL; }
|
||||
} cleanup(xdr->cx());
|
||||
ScriptSource *ss = *ssp;
|
||||
if (mode == XDR_DECODE) {
|
||||
*ssp = static_cast<ScriptSource *>(xdr->cx()->malloc_(sizeof(ScriptSource)));
|
||||
ss = *ssp;
|
||||
if (!ss)
|
||||
return false;
|
||||
ss->marked = ss->onRuntime_ = ss->argumentsNotIncluded_ = false;
|
||||
#ifdef DEBUG
|
||||
ss->ready_ = false;
|
||||
#endif
|
||||
ss->data.compressed = NULL;
|
||||
cleanup.protect(ss);
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
// See comment in ScriptSource::createFromSource.
|
||||
if (xdr->cx()->runtime->gcIncrementalState == MARK &&
|
||||
xdr->cx()->runtime->gcIsFull)
|
||||
ss->marked = true;
|
||||
#endif
|
||||
}
|
||||
if (!xdr->codeUint32(&ss->length_))
|
||||
return false;
|
||||
if (!xdr->codeUint32(&ss->compressedLength))
|
||||
return false;
|
||||
uint8_t argumentsNotIncluded = ss->argumentsNotIncluded_;
|
||||
if (!xdr->codeUint8(&argumentsNotIncluded))
|
||||
return false;
|
||||
ss->argumentsNotIncluded_ = argumentsNotIncluded;
|
||||
size_t byteLen = ss->compressed() ? ss->compressedLength :
|
||||
(ss->length_ * sizeof(jschar));
|
||||
if (mode == XDR_DECODE) {
|
||||
ss->data.compressed = static_cast<unsigned char *>(xdr->cx()->malloc_(byteLen));
|
||||
if (!ss->data.compressed)
|
||||
return false;
|
||||
}
|
||||
if (!xdr->codeBytes(ss->data.compressed, byteLen))
|
||||
return false;
|
||||
if (mode == XDR_DECODE) {
|
||||
#ifdef DEBUG
|
||||
ss->ready_ = true;
|
||||
#endif
|
||||
ss->attachToRuntime(xdr->cx()->runtime);
|
||||
cleanup.release();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shared script filename management.
|
||||
*/
|
||||
|
@ -1112,7 +1503,8 @@ ScriptDataSize(uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
|
|||
JSScript *
|
||||
JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun,
|
||||
JSPrincipals *principals, JSPrincipals *originPrincipals,
|
||||
bool compileAndGo, bool noScriptRval, JSVersion version, unsigned staticLevel)
|
||||
bool compileAndGo, bool noScriptRval, JSVersion version, unsigned staticLevel,
|
||||
ScriptSource *ss, uint32_t bufStart, uint32_t bufEnd)
|
||||
{
|
||||
JSScript *script = js_NewGCScript(cx);
|
||||
if (!script)
|
||||
|
@ -1150,6 +1542,10 @@ JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun
|
|||
}
|
||||
script->staticLevel = uint16_t(staticLevel);
|
||||
|
||||
script->source = ss;
|
||||
script->sourceStart = bufStart;
|
||||
script->sourceEnd = bufEnd;
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
|
@ -1340,6 +1736,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
|||
if (bce->constList.length() != 0)
|
||||
bce->constList.finish(script->consts());
|
||||
script->strictModeCode = bce->sc->inStrictMode();
|
||||
script->explicitUseStrict = bce->sc->hasExplicitUseStrict();
|
||||
script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
|
||||
script->funHasExtensibleScope = bce->sc->funHasExtensibleScope();
|
||||
script->hasSingletons = bce->hasSingletons;
|
||||
|
@ -1779,7 +2176,8 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
|||
JSScript *dst = JSScript::Create(cx, enclosingScope, src->savedCallerFun,
|
||||
cx->compartment->principals, src->originPrincipals,
|
||||
src->compileAndGo, src->noScriptRval,
|
||||
src->getVersion(), src->staticLevel);
|
||||
src->getVersion(), src->staticLevel,
|
||||
src->source, src->sourceStart, src->sourceEnd);
|
||||
if (!dst) {
|
||||
Foreground::free_(data);
|
||||
return NULL;
|
||||
|
@ -1815,6 +2213,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
|||
}
|
||||
dst->cloneHasArray(src);
|
||||
dst->strictModeCode = src->strictModeCode;
|
||||
dst->explicitUseStrict = src->explicitUseStrict;
|
||||
dst->bindingsAccessedDynamically = src->bindingsAccessedDynamically;
|
||||
dst->funHasExtensibleScope = src->funHasExtensibleScope;
|
||||
dst->hasSingletons = src->hasSingletons;
|
||||
|
@ -2106,8 +2505,13 @@ JSScript::markChildren(JSTracer *trc)
|
|||
if (enclosingScope_)
|
||||
MarkObject(trc, &enclosingScope_, "enclosing");
|
||||
|
||||
if (IS_GC_MARKING_TRACER(trc) && filename)
|
||||
MarkScriptFilename(trc->runtime, filename);
|
||||
if (IS_GC_MARKING_TRACER(trc)) {
|
||||
if (filename)
|
||||
MarkScriptFilename(trc->runtime, filename);
|
||||
|
||||
if (trc->runtime->gcIsFull && source && source->onRuntime())
|
||||
source->mark();
|
||||
}
|
||||
|
||||
bindings.trace(trc);
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
/*
|
||||
* JS script descriptor.
|
||||
*/
|
||||
#include "jsatom.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsclist.h"
|
||||
|
@ -336,6 +335,8 @@ typedef HashMap<JSScript *,
|
|||
DefaultHasher<JSScript *>,
|
||||
SystemAllocPolicy> DebugScriptMap;
|
||||
|
||||
struct ScriptSource;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSScript : public js::gc::Cell
|
||||
|
@ -436,6 +437,8 @@ struct JSScript : public js::gc::Cell
|
|||
/* Persistent type information retained across GCs. */
|
||||
js::types::TypeScript *types;
|
||||
|
||||
js::ScriptSource *source; /* source code */
|
||||
|
||||
private:
|
||||
#ifdef JS_METHODJIT
|
||||
JITScriptSet *jitInfo;
|
||||
|
@ -455,6 +458,10 @@ struct JSScript : public js::gc::Cell
|
|||
|
||||
uint32_t natoms; /* length of atoms array */
|
||||
|
||||
uint32_t sourceStart;
|
||||
uint32_t sourceEnd;
|
||||
|
||||
|
||||
private:
|
||||
uint32_t useCount; /* Number of times the script has been called
|
||||
* or has had backedges taken. Reset if the
|
||||
|
@ -468,6 +475,8 @@ struct JSScript : public js::gc::Cell
|
|||
uint32_t idpad;
|
||||
#endif
|
||||
|
||||
uint32_t PADDING;
|
||||
|
||||
// 16-bit fields.
|
||||
|
||||
private:
|
||||
|
@ -511,6 +520,7 @@ struct JSScript : public js::gc::Cell
|
|||
expression statement */
|
||||
bool savedCallerFun:1; /* can call getCallerFunction() */
|
||||
bool strictModeCode:1; /* code is in strict mode */
|
||||
bool explicitUseStrict:1; /* code has "use strict"; explicitly */
|
||||
bool compileAndGo:1; /* see Parser::compileAndGo */
|
||||
bool bindingsAccessedDynamically:1; /* see ContextFlags' field of the same name */
|
||||
bool funHasExtensibleScope:1; /* see ContextFlags' field of the same name */
|
||||
|
@ -551,7 +561,8 @@ struct JSScript : public js::gc::Cell
|
|||
static JSScript *Create(JSContext *cx, js::HandleObject enclosingScope, bool savedCallerFun,
|
||||
JSPrincipals *principals, JSPrincipals *originPrincipals,
|
||||
bool compileAndGo, bool noScriptRval,
|
||||
JSVersion version, unsigned staticLevel);
|
||||
JSVersion version, unsigned staticLevel,
|
||||
js::ScriptSource *ss, uint32_t sourceStart, uint32_t sourceEnd);
|
||||
|
||||
// Three ways ways to initialize a JSScript. Callers of partiallyInit()
|
||||
// and fullyInitTrivial() are responsible for notifying the debugger after
|
||||
|
@ -607,6 +618,8 @@ struct JSScript : public js::gc::Cell
|
|||
JSFunction *function() const { return function_; }
|
||||
void setFunction(JSFunction *fun);
|
||||
|
||||
JSFixedString *sourceData(JSContext *cx);
|
||||
|
||||
/* Return whether this script was compiled for 'eval' */
|
||||
bool isForEval() { return isCachedEval || isActiveEval; }
|
||||
|
||||
|
@ -937,6 +950,132 @@ js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
|
|||
|
||||
namespace js {
|
||||
|
||||
struct SourceCompressionToken;
|
||||
|
||||
struct ScriptSource
|
||||
{
|
||||
friend class SourceCompressorThread;
|
||||
ScriptSource *next;
|
||||
private:
|
||||
union {
|
||||
// When the script source is ready, compressedLength > 0 implies
|
||||
// compressed holds the compressed data; otherwise, source holds the
|
||||
// uncompressed source.
|
||||
jschar *source;
|
||||
unsigned char *compressed;
|
||||
} data;
|
||||
uint32_t length_;
|
||||
uint32_t compressedLength;
|
||||
bool marked:1;
|
||||
bool onRuntime_:1;
|
||||
bool argumentsNotIncluded_:1;
|
||||
#ifdef DEBUG
|
||||
bool ready_:1;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static ScriptSource *createFromSource(JSContext *cx,
|
||||
const jschar *src,
|
||||
uint32_t length,
|
||||
bool argumentsNotIncluded = false,
|
||||
SourceCompressionToken *tok = NULL);
|
||||
void attachToRuntime(JSRuntime *rt);
|
||||
void mark() { JS_ASSERT(ready_); JS_ASSERT(onRuntime_); marked = true; }
|
||||
void destroy(JSRuntime *rt);
|
||||
uint32_t length() const { return length_; }
|
||||
bool onRuntime() const { return onRuntime_; }
|
||||
bool argumentsNotIncluded() const { return argumentsNotIncluded_; }
|
||||
#ifdef DEBUG
|
||||
bool ready() const { return ready_; }
|
||||
#endif
|
||||
JSFixedString *substring(JSContext *cx, uint32_t start, uint32_t stop);
|
||||
|
||||
// For the GC.
|
||||
static void sweep(JSRuntime *rt);
|
||||
|
||||
// XDR handling
|
||||
template <XDRMode mode>
|
||||
static bool performXDR(XDRState<mode> *xdr, ScriptSource **ss);
|
||||
|
||||
private:
|
||||
bool compressed() { return !!compressedLength; }
|
||||
void considerCompressing(JSRuntime *rt, const jschar *src);
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
/*
|
||||
* Background thread to compress JS source code. This happens only while parsing
|
||||
* and bytecode generation is happening in the main thread. If needed, the
|
||||
* compiler waits for compression to complete before returning.
|
||||
*
|
||||
* To use it, you have to have a SourceCompressionToken, tok, with tok.ss and
|
||||
* tok.chars set to the proper values. When the SourceCompressionToken is
|
||||
* destroyed, it makes sure the compression is complete. At this point tok.ss is
|
||||
* ready to be attached to the runtime.
|
||||
*/
|
||||
class SourceCompressorThread
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
// The compression thread is in the process of compression some source.
|
||||
COMPRESSING,
|
||||
// The compression thread is not doing anything and available to
|
||||
// compress source.
|
||||
IDLE,
|
||||
// Set by finish() to tell the compression thread to exit.
|
||||
SHUTDOWN
|
||||
} state;
|
||||
JSRuntime *rt;
|
||||
SourceCompressionToken *tok;
|
||||
PRThread *thread;
|
||||
// Protects |state| and |tok| when it's non-NULL.
|
||||
PRLock *lock;
|
||||
// When it's idling, the compression thread blocks on this. The main thread
|
||||
// uses it to notify the compression thread when it has source to be
|
||||
// compressed.
|
||||
PRCondVar *wakeup;
|
||||
// The main thread can block on this to wait for compression to finish.
|
||||
PRCondVar *done;
|
||||
|
||||
void threadLoop();
|
||||
static void compressorThread(void *arg);
|
||||
|
||||
public:
|
||||
explicit SourceCompressorThread(JSRuntime *rt)
|
||||
: state(IDLE),
|
||||
rt(rt),
|
||||
tok(NULL),
|
||||
thread(NULL),
|
||||
lock(NULL),
|
||||
wakeup(NULL),
|
||||
done(NULL) {}
|
||||
void finish();
|
||||
bool init();
|
||||
void compress(SourceCompressionToken *tok);
|
||||
void waitOnCompression(SourceCompressionToken *userTok);
|
||||
};
|
||||
#endif
|
||||
|
||||
struct SourceCompressionToken
|
||||
{
|
||||
friend class ScriptSource;
|
||||
friend class SourceCompressorThread;
|
||||
private:
|
||||
JSRuntime *rt;
|
||||
ScriptSource *ss;
|
||||
const jschar *chars;
|
||||
public:
|
||||
SourceCompressionToken(JSRuntime *rt)
|
||||
: rt(rt), ss(NULL), chars(NULL) {}
|
||||
~SourceCompressionToken()
|
||||
{
|
||||
JS_ASSERT_IF(!ss, !chars);
|
||||
if (ss)
|
||||
ensureReady();
|
||||
}
|
||||
void ensureReady();
|
||||
};
|
||||
|
||||
extern void
|
||||
CallDestroyScriptHook(FreeOp *fop, JSScript *script);
|
||||
|
||||
|
|
|
@ -23,8 +23,76 @@
|
|||
#include "js/TemplateLib.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
static void *
|
||||
zlib_alloc(void *cx, uInt items, uInt size)
|
||||
{
|
||||
return OffTheBooks::malloc_(items * size);
|
||||
}
|
||||
|
||||
static void
|
||||
zlib_free(void *cx, void *addr)
|
||||
{
|
||||
Foreground::free_(addr);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
js::TryCompressString(const unsigned char *inp, size_t inplen, unsigned char *out, size_t *outlen)
|
||||
{
|
||||
JS_ASSERT(inplen);
|
||||
if (inplen >= UINT32_MAX)
|
||||
return false;
|
||||
z_stream zs;
|
||||
zs.opaque = NULL;
|
||||
zs.zalloc = zlib_alloc;
|
||||
zs.zfree = zlib_free;
|
||||
zs.next_in = (Bytef *)inp;
|
||||
zs.avail_in = inplen;
|
||||
zs.next_out = out;
|
||||
zs.avail_out = inplen;
|
||||
int ret = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
|
||||
if (ret != Z_OK) {
|
||||
JS_ASSERT(ret == Z_MEM_ERROR);
|
||||
return false;
|
||||
}
|
||||
ret = deflate(&zs, Z_FINISH);
|
||||
DebugOnly<int> ret2 = deflateEnd(&zs);
|
||||
JS_ASSERT(ret2 == Z_OK);
|
||||
if (ret != Z_STREAM_END)
|
||||
return false;
|
||||
*outlen = inplen - zs.avail_out;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::DecompressString(const unsigned char *inp, size_t inplen, unsigned char *out, size_t outlen)
|
||||
{
|
||||
JS_ASSERT(inplen <= UINT32_MAX);
|
||||
z_stream zs;
|
||||
zs.zalloc = zlib_alloc;
|
||||
zs.zfree = zlib_free;
|
||||
zs.opaque = NULL;
|
||||
zs.next_in = (Bytef *)inp;
|
||||
zs.avail_in = inplen;
|
||||
zs.next_out = out;
|
||||
JS_ASSERT(outlen);
|
||||
zs.avail_out = outlen;
|
||||
int ret = inflateInit(&zs);
|
||||
if (ret != Z_OK) {
|
||||
JS_ASSERT(ret == Z_MEM_ERROR);
|
||||
return false;
|
||||
}
|
||||
ret = inflate(&zs, Z_FINISH);
|
||||
JS_ASSERT(ret == Z_STREAM_END);
|
||||
ret = inflateEnd(&zs);
|
||||
JS_ASSERT(ret == Z_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* For JS_OOM_POSSIBLY_FAIL in jsutil.h. */
|
||||
JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations = UINT32_MAX;
|
||||
|
|
|
@ -335,6 +335,21 @@ ClearAllBitArrayElements(size_t *array, size_t length)
|
|||
array[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to compress some bytes. Return true if compression produced a
|
||||
* string smaller than the input. The caller is responsible for allocating
|
||||
* |out| to a string the same length as the input.
|
||||
*/
|
||||
bool TryCompressString(const unsigned char *inp, size_t inplen,
|
||||
unsigned char *out, size_t *outlen);
|
||||
|
||||
/*
|
||||
* Decompress a string. The caller must know the length of the output and
|
||||
* allocate |out| to a string of that length.
|
||||
*/
|
||||
bool DecompressString(const unsigned char *inp, size_t inplen,
|
||||
unsigned char *out, size_t outlen);
|
||||
|
||||
} /* namespace js */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
@ -3292,6 +3292,63 @@ Snarf(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
DecompileFunctionSomehow(JSContext *cx, unsigned argc, Value *vp,
|
||||
JSString *(*decompiler)(JSContext *, JSFunction *, unsigned))
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() < 1 || !args[0].isObject() || !args[0].toObject().isFunction()) {
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
JSString *result = decompiler(cx, args[0].toObject().toFunction(), 0);
|
||||
if (!result)
|
||||
return false;
|
||||
args.rval().setString(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
DecompileBody(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return DecompileFunctionSomehow(cx, argc, vp, JS_DecompileFunctionBody);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
DecompileFunction(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return DecompileFunctionSomehow(cx, argc, vp, JS_DecompileFunction);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
DecompileThisScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSScript *script = js_GetCurrentScript(cx);
|
||||
JS_ASSERT(script);
|
||||
JSString *result = JS_DecompileScript(cx, script, "test", 0);
|
||||
if (!result)
|
||||
return false;
|
||||
args.rval().setString(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ThisFilename(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JSScript *script = js_GetCurrentScript(cx);
|
||||
if (!script || !script->filename) {
|
||||
args.rval().setString(cx->runtime->emptyString);
|
||||
return true;
|
||||
}
|
||||
JSString *filename = JS_NewStringCopyZ(cx, script->filename);
|
||||
if (!filename)
|
||||
return false;
|
||||
args.rval().setString(filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Wrap(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
|
@ -3688,6 +3745,22 @@ static JSFunctionSpecWithHelp shell_functions[] = {
|
|||
"parent(obj)",
|
||||
" Returns the parent of obj."),
|
||||
|
||||
JS_FN_HELP("decompileFunction", DecompileFunction, 1, 0,
|
||||
"decompileFunction(func)",
|
||||
" Decompile a function."),
|
||||
|
||||
JS_FN_HELP("decompileBody", DecompileBody, 1, 0,
|
||||
"decompileBody(func)",
|
||||
" Decompile a function's body."),
|
||||
|
||||
JS_FN_HELP("decompileThis", DecompileThisScript, 0, 0,
|
||||
"decompileThis()",
|
||||
" Decompile the currently executing script."),
|
||||
|
||||
JS_FN_HELP("thisFilename", ThisFilename, 0, 0,
|
||||
"thisFilename()",
|
||||
" Return the filename of the current script"),
|
||||
|
||||
JS_FN_HELP("wrap", Wrap, 1, 0,
|
||||
"wrap(obj)",
|
||||
" Wrap an object into a noop wrapper."),
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var summary = "Function.prototype.toString should not quote XML literals";
|
||||
var BUGNUMBER = 301692;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
actual = ConvertToString((function () { return <xml/>; }));
|
||||
expect = 'function () { return <xml/>;}';
|
||||
TEST(1, expect, actual);
|
||||
|
||||
actual = ConvertToString((function () { return <xml></xml>; }));
|
||||
expect = 'function () { return <xml></xml>;}';
|
||||
TEST(2, expect, actual);
|
||||
|
||||
actual = ConvertToString((function () { return <xml><morexml/></xml>; }));
|
||||
expect = 'function () { return <xml><morexml/></xml>;}';
|
||||
TEST(3, expect, actual);
|
||||
|
||||
actual = ConvertToString((function (k) { return <xml>{k}</xml>; }));
|
||||
expect = 'function (k) { return <xml>{k}</xml>;}';
|
||||
TEST(4, expect, actual);
|
||||
|
||||
actual = ConvertToString((function (k) { return <{k}/>; }));
|
||||
expect = 'function (k) { return <{k}/>;}';
|
||||
TEST(5, expect, actual);
|
||||
|
||||
actual = ConvertToString((function (k) { return <{k}>{k}</{k}>; }));
|
||||
expect = 'function (k) { return <{k}>{k}</{k}>;}';
|
||||
TEST(6, expect, actual);
|
||||
|
||||
actual = ConvertToString((function (k) { return <{k}
|
||||
{k}={k} {"k"}={k + "world"}><{k + "k"}/></{k}>; }));
|
||||
expect = 'function (k) ' +
|
||||
'{ return <{k} {k}={k} {"k"}={k + "world"}><{k + "k"}/></{k}>;}';
|
||||
TEST(7, expect, actual);
|
||||
|
||||
END();
|
||||
|
||||
function ConvertToString(f)
|
||||
{
|
||||
return f.toString().replace(/\n/g, '').replace(/[ ]+/g, ' ');
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var summary = "Operator .. should not implicitly quote its right operand";
|
||||
var BUGNUMBER = 321547;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
function a(){
|
||||
var x=<a><b><c>value c</c></b></a>;
|
||||
return x..c;
|
||||
}
|
||||
|
||||
actual = a.toString();
|
||||
expect = 'function a() {\n' +
|
||||
' var x = <a><b><c>value c</c></b></a>;\n' +
|
||||
' return x..c;\n' +
|
||||
'}';
|
||||
actual = actual.replace(/[\n ]+/mg, ' ');
|
||||
expect = expect.replace(/[\n ]+/mg, ' ');
|
||||
|
||||
TEST(1, expect, actual);
|
||||
|
||||
actual = String(a.valueOf());
|
||||
expect = 'function a() {\n' +
|
||||
' var x = <a><b><c>value c</c></b></a>;\n' +
|
||||
' return x..c;\n' +
|
||||
'}';
|
||||
actual = actual.replace(/[\n ]+/mg, ' ');
|
||||
expect = expect.replace(/[\n ]+/mg, ' ');
|
||||
|
||||
TEST(3, expect, actual);
|
||||
|
||||
actual = String(a);
|
||||
expect = 'function a() {\n' +
|
||||
' var x = <a><b><c>value c</c></b></a>;\n' +
|
||||
' return x..c;\n' +
|
||||
'}';
|
||||
actual = actual.replace(/[\n ]+/mg, ' ');
|
||||
expect = expect.replace(/[\n ]+/mg, ' ');
|
||||
|
||||
TEST(4, expect, actual);
|
||||
|
||||
actual = a();
|
||||
expect = <c>value c</c>;
|
||||
actual = actual.replace(/[\n ]+/mg, ' ');
|
||||
expect = expect.replace(/[\n ]+/mg, ' ');
|
||||
|
||||
TEST(5, expect, actual);
|
||||
|
||||
END();
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 331558;
|
||||
var summary = 'Decompiler: Missing = in default xml namespace statement';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
actual = (function () { default xml namespace = 'abc' }).toString();
|
||||
expect = 'function () {\n default xml namespace = "abc";\n}';
|
||||
|
||||
TEST(1, expect, actual);
|
||||
|
||||
END();
|
|
@ -1,58 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = "352097";
|
||||
var summary = "Avoid adding unnecessary spaces to PIs";
|
||||
var actual, expect;
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var failed = false;
|
||||
|
||||
function assertContains(func, str)
|
||||
{
|
||||
if (func.toString().indexOf(str) < 0)
|
||||
throw func.toString() + " does not contain " + str + "!";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var f = new Function("return <?f?>;");
|
||||
assertContains(f, "<?f?>");
|
||||
|
||||
var g = new Function("return <?f ?>;");
|
||||
assertContains(g, "<?f?>");
|
||||
|
||||
var h = new Function("return <?f ?>;");
|
||||
assertContains(h, "<?f?>");
|
||||
|
||||
var i = new Function("return <?f i?>;");
|
||||
assertContains(i, "<?f i?>");
|
||||
|
||||
var j = new Function("return <?f i ?>;");
|
||||
assertContains(j, "<?f i ?>");
|
||||
|
||||
var k = new Function("return <?f i ?>;");
|
||||
assertContains(k, "<?f i ?>");
|
||||
|
||||
var m = new Function("return <?f i ?>;");
|
||||
assertContains(m, "<?f i ?>");
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
failed = ex;
|
||||
}
|
||||
|
||||
expect = false;
|
||||
actual = failed;
|
||||
|
||||
TEST(1, expect, actual);
|
|
@ -1,27 +0,0 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributors: Blake Kaplan, Bob Clary
|
||||
*/
|
||||
|
||||
|
||||
var summary = 'E4X - Function.prototype.toString should not quote {} ' +
|
||||
'attribute values';
|
||||
var BUGNUMBER = 302097;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
function f(k) {
|
||||
return <xml k={k}/>;
|
||||
}
|
||||
|
||||
actual = f.toString().replace(/</g, '<');
|
||||
expect = 'function f(k) {\n return <xml k={k}/>;\n}';
|
||||
|
||||
TEST(1, expect, actual);
|
||||
|
||||
END();
|
|
@ -1,46 +0,0 @@
|
|||
// |reftest| fails
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = "352285";
|
||||
var summary = "Decompiler escapes line breaks/backslashes in E4X literals";
|
||||
var actual, expect;
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var failed = false;
|
||||
|
||||
function assertCorrectDecompilation(xmlInitializer)
|
||||
{
|
||||
var func = new Function("return " + xmlInitializer);
|
||||
var funcStr = func.toString();
|
||||
if (funcStr.indexOf(xmlInitializer) < 0)
|
||||
throw "'" + funcStr + "' does not contain '" + xmlInitializer + "'!";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
assertCorrectDecompilation("<![CDATA[\\\\]]>");
|
||||
assertCorrectDecompilation("<![CDATA[\n]]>");
|
||||
assertCorrectDecompilation("<![CDATA[foo\nbar\nbaz]]>");
|
||||
assertCorrectDecompilation("<!--f b\nc\n-->");
|
||||
assertCorrectDecompilation("<?f b\n\nc\nc?>");
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
failed = ex;
|
||||
}
|
||||
|
||||
expect = false;
|
||||
actual = failed;
|
||||
|
||||
TEST(1, expect, actual);
|
|
@ -1,29 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 349814;
|
||||
var summary = 'decompilation of e4x literals';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var z = function ()
|
||||
{
|
||||
a =
|
||||
<x>
|
||||
<y/>
|
||||
</x>;
|
||||
};
|
||||
|
||||
expect = z + '';
|
||||
actual = (eval("(" + z + ")")) + '';
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,23 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 349815;
|
||||
var summary = 'decompilation of parameterized e4x xmllist literal';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = function (tag) { return <><{tag}></{tag}></>; }
|
||||
|
||||
expect = 'function (tag) {\n return <><{tag}></{tag}></>;\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,30 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 349822;
|
||||
var summary = 'decompilation of x.@[2]';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
expect = 'function () {\n return x.@[2];\n}';
|
||||
|
||||
try
|
||||
{
|
||||
var f = eval('(function () { return x.@[2]; })');
|
||||
actual = f + '';
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,27 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 349956;
|
||||
var summary = 'decompilation of <x/>.@*';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f;
|
||||
var g;
|
||||
|
||||
f = function () { <x/>.@* };
|
||||
g = eval('(' + f + ')');
|
||||
|
||||
expect = f + '';
|
||||
actual = g + '';
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,22 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 350226;
|
||||
var summary = 'decompilation of <x/>.@[*]';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = function () { <x/>[@[*]]; }
|
||||
expect = 'function () {\n <x/>[@[*]];\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 350531;
|
||||
var summary = "decompilation of function (){ return (@['a'])=='b'}";
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function (){ return (@['a'])=='b'}
|
||||
expect = 'function () {\n return @["a"] == "b";\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
f = function (){ return (@['a']).toXMLString() }
|
||||
expect = 'function () {\n return @["a"].toXMLString();\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(2) + summary);
|
||||
|
||||
END();
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 351706;
|
||||
var summary = 'decompilation of E4X literals with parens';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function() { return <{m}/>.(y) }
|
||||
expect = 'function() { return (<{m}/>).(y); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
f = function() { return (<{m}/>).(y) }
|
||||
expect = 'function() { return (<{m}/>).(y); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(2) + summary);
|
||||
|
||||
END();
|
|
@ -1,24 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor: Robert Sayre
|
||||
*/
|
||||
|
||||
|
||||
var summary = 'decompilation of XMLPI object initializer';
|
||||
var BUGNUMBER = 351988;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f;
|
||||
f = function() { var y = <?foo bar?>; }
|
||||
actual = f + '';
|
||||
expect = 'function () {\n var y = <?foo bar?>;\n}';
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,104 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 352013;
|
||||
var summary = 'Decompilation with new operator redeaux';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var l, m, r;
|
||||
var nTests = 0;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
l = function () { (new x(y))[z]; };
|
||||
expect = 'function () { (new x(y))[z]; }';
|
||||
actual = l + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
m = function () { new (x(y))[z]; };
|
||||
expect = 'function () { new (x(y)[z]); }';
|
||||
actual = m + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
r = function () { new (x(y)[z]); };
|
||||
expect = 'function () { new (x(y)[z]); }';
|
||||
actual = r + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
l = function () { (new x(y)).@a; };
|
||||
expect = 'function () { (new x(y)).@a; }';
|
||||
actual = l + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
m = function () { new (x(y)).@a; };
|
||||
expect = 'function () { new (x(y).@a); }';
|
||||
actual = m + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
r = function () { new (x(y).@a); };
|
||||
expect = 'function () { new (x(y).@a); }';
|
||||
actual = r + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
l = function () { (new x(y)).@n::a; };
|
||||
expect = 'function () { (new x(y)).@[n::a]; }';
|
||||
actual = l + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
m = function () { new (x(y)).@n::a; };
|
||||
expect = 'function () { new (x(y).@[n::a]); }';
|
||||
actual = m + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
r = function () { new (x(y).@n::a); };
|
||||
expect = 'function () { new (x(y).@[n::a]); }';
|
||||
actual = r + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
l = function () { (new x(y)).n::z; };
|
||||
expect = 'function () { (new x(y)).n::z; }';
|
||||
actual = l + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
m = function () { new (x(y)).n::z; };
|
||||
expect = 'function () { new (x(y).n::z); }';
|
||||
actual = m + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
r = function () { new (x(y).n::z); };
|
||||
expect = 'function () { new (x(y).n::z); }';
|
||||
actual = r + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
l = function () { (new x(y)).n::[z]; };
|
||||
expect = 'function () { (new x(y)).n::[z]; }';
|
||||
actual = l + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
m = function () { new (x(y)).n::[z]; };
|
||||
expect = 'function () { new (x(y).n::[z]); }';
|
||||
actual = m + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
r = function () { new (x(y).n::[z]); };
|
||||
expect = 'function () { new (x(y).n::[z]); }';
|
||||
actual = r + '';
|
||||
compareSource(expect, actual, inSection(++nTests) + summary);
|
||||
|
||||
END();
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 352459;
|
||||
var summary = 'decompilation for 4..@x++';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = (function() { return 4..@x++; } );
|
||||
expect = 'function() { return (4).@x++; }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 352649;
|
||||
var summary = 'decompilation of e4x literal after |if| block';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = function() { if(g) p; (<x/>.i) }
|
||||
expect = 'function() { if(g) {p;} <x/>.i; }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,33 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 352789;
|
||||
var summary = 'Decompilation of new and .@';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function() { return new (a()).@z; };
|
||||
expect = 'function() { return new (a().@z); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
f = function () { return new a().@z; };
|
||||
expect = 'function () { return (new a).@z; }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(2) + summary);
|
||||
|
||||
f = function () { return (new a).@z; };
|
||||
expect = 'function () { return (new a).@z; }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(3) + summary);
|
||||
|
||||
END();
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 355101;
|
||||
var summary = 'XML Filtering predicate operator';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = function () { return i.(true); }
|
||||
expect = 'function () { return i.(true); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 355474;
|
||||
var summary = 'Iterating over XML with WAY_TOO_MUCH_GC';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = function () { for each (var z in <y/>) { print(z); } };
|
||||
|
||||
expect = 'function () { for each (var z in <y/>) { print(z); } }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
expect = actual = 'No Hang';
|
||||
f();
|
||||
f();
|
||||
|
||||
TEST(2, expect, actual);
|
||||
|
||||
END();
|
|
@ -1,23 +0,0 @@
|
|||
// |reftest| skip -- obsolete test
|
||||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var BUGNUMBER = 373678;
|
||||
var summary = 'Missing quotes around string in decompilation, ' +
|
||||
'with for..in and do..while';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = function() { do {for(a.b in []) { } } while("c\\d"); };
|
||||
expect = 'function() { do {for(a.b in []) { } } while("c\\\\d"); }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,33 +0,0 @@
|
|||
// |reftest| require-or(debugMode,skip)
|
||||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var summary = 'trap should not change decompilation <x/>';
|
||||
var BUGNUMBER = 429249
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
function g() {
|
||||
return <x/>;
|
||||
}
|
||||
|
||||
expect = 'function g() { return <x/>; }';
|
||||
actual = g + '';
|
||||
compareSource(expect, actual, summary + ' : before trap');
|
||||
|
||||
if (typeof trap == 'function' && typeof setDebug == 'function')
|
||||
{
|
||||
setDebug(true);
|
||||
trap(g, 0, "");
|
||||
actual = g + '';
|
||||
compareSource(expect, actual, summary + ' : after trap');
|
||||
}
|
||||
|
||||
END();
|
|
@ -1,23 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var summary = 'Decompilation of ({0: (4, <></>)})';
|
||||
var BUGNUMBER = 461233;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
var f = (function() { return ({0: (4, <></>) }); });
|
||||
|
||||
expect = 'function() { return {0: (4, <></>) }; }';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, expect)
|
||||
|
||||
END();
|
|
@ -1,23 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor:
|
||||
* Rasmus Jensen <rje(a)dbc.dk>
|
||||
*/
|
||||
|
||||
|
||||
var summary = 'Uneval+eval of XML containing string with {';
|
||||
var BUGNUMBER = 463360;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
actual = eval(uneval(XML("<a>{</a>")));
|
||||
expect = XML("<a>{</a>");
|
||||
|
||||
compareSource(expect, actual, inSection(1) + summary);
|
||||
|
||||
END();
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
var summary = "Operator .. should not implicitly quote its right operand";
|
||||
var BUGNUMBER = 321547;
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
START(summary);
|
||||
|
||||
function a(){
|
||||
var x=<a><b><c>value c</c></b></a>;
|
||||
return x..c;
|
||||
}
|
||||
|
||||
actual = a.toSource();
|
||||
expect = 'function a() {var x = <a><b><c>value c</c></b></a>;return x..c;}';
|
||||
actual = actual.replace(/[\n ]+/mg, ' ');
|
||||
expect = expect.replace(/[\n ]+/mg, ' ');
|
||||
|
||||
TEST(2, expect, actual);
|
||||
|
||||
END();
|
|
@ -23,19 +23,16 @@ function test()
|
|||
var code;
|
||||
|
||||
code = '(function() { label1: for (;;) { continue \n label1; }})';
|
||||
expect = '(function() { label1: for (;;) { continue ; label1; }})';
|
||||
actual = uneval(eval(code));
|
||||
compareSource(expect, actual, summary + ': ' + code);
|
||||
compareSource(code, actual, summary + ': ' + code);
|
||||
|
||||
code = '(function() { label2: for (;;) { break \n label2; }})';
|
||||
expect = '(function() { label2: for (;;) { break ; label2; }})';
|
||||
actual = uneval(eval(code));
|
||||
compareSource(expect, actual, summary + ': ' + code);
|
||||
compareSource(code, actual, summary + ': ' + code);
|
||||
|
||||
code = '(function() { return \n x++; })';
|
||||
expect = '(function() { return ; x++; })';
|
||||
actual = uneval(eval(code));
|
||||
compareSource(expect, actual, summary + ': ' + code);
|
||||
compareSource(code, actual, summary + ': ' + code);
|
||||
|
||||
print('see bug 256617');
|
||||
code = '(function() { throw \n x++; })';
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
var a = function (t) {
|
||||
return t % 0;
|
||||
}
|
||||
|
||||
var b = function (t) {
|
||||
return t % "";
|
||||
}
|
||||
|
||||
var c = function (t) {
|
||||
return t % ("" + "");
|
||||
}
|
||||
|
||||
assertEq(a.toString(), b.toString());
|
||||
assertEq(a.toString(), c.toString());
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -22,54 +22,6 @@ function f2novar(o){with(this)for(x in o)printStatus(o[x]); return x}
|
|||
function f3(i,o){for(var x=i in o)printStatus(o[x]); return x}
|
||||
function f4(i,o){with(this)for(var x=i in o)printStatus(o[x]); return x}
|
||||
|
||||
const f1src =
|
||||
"function f1(o) {\n" +
|
||||
" for (var x in o) {\n" +
|
||||
" printStatus(o[x]);\n" +
|
||||
" }\n" +
|
||||
" return x;\n" +
|
||||
"}";
|
||||
|
||||
const f2src =
|
||||
"function f2(o) {\n" +
|
||||
" with (this) {\n" +
|
||||
" for (var x in o) {\n" +
|
||||
" printStatus(o[x]);\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" return x;\n" +
|
||||
"}";
|
||||
|
||||
const f2novarsrc =
|
||||
"function f2novar(o) {\n" +
|
||||
" with (this) {\n" +
|
||||
" for (x in o) {\n" +
|
||||
" printStatus(o[x]);\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" return x;\n" +
|
||||
"}";
|
||||
|
||||
const f3src =
|
||||
"function f3(i, o) {\n" +
|
||||
" var x = i;\n" +
|
||||
" for (x in o) {\n" +
|
||||
" printStatus(o[x]);\n" +
|
||||
" }\n" +
|
||||
" return x;\n" +
|
||||
"}";
|
||||
|
||||
const f4src =
|
||||
"function f4(i, o) {\n" +
|
||||
" with (this) {\n" +
|
||||
" var x = i;\n" +
|
||||
" for (x in o) {\n" +
|
||||
" printStatus(o[x]);\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" return x;\n" +
|
||||
"}";
|
||||
|
||||
var t=0;
|
||||
function assert(c)
|
||||
{
|
||||
|
@ -86,21 +38,6 @@ function assert(c)
|
|||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
if (dodis && this.dis) dis(f1);
|
||||
assert(f1 == f1src);
|
||||
|
||||
if (dodis && this.dis) dis(f2);
|
||||
assert(f2 == f2src);
|
||||
|
||||
if (dodis && this.dis) dis(f2novar);
|
||||
assert(f2novar == f2novarsrc);
|
||||
|
||||
if (dodis && this.dis) dis(f3);
|
||||
assert(f3 == f3src);
|
||||
|
||||
if (dodis && this.dis) dis(f4);
|
||||
assert(f4 == f4src);
|
||||
|
||||
assert(f1([]) == undefined);
|
||||
|
||||
assert(f1(['first']) == 0);
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349648;
|
||||
var summary = 'Extra "[" in decomilation of nested array comprehensions';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function(){ [[0 for (x in [])] for (y in []) ]; };
|
||||
expect = 'function () {\n [[0 for (x in [])] for (y in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':1');
|
||||
|
||||
f = function(){ [[0 for (x in [])] for (y in []) ]; };
|
||||
expect = 'function () {\n [[0 for (x in [])] for (y in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':2');
|
||||
|
||||
f = function(){ [[0 for (x in [])] for (yyyyyyyyyyy in []) ]; }
|
||||
expect = 'function () {\n [[0 for (x in [])] for (yyyyyyyyyyy in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':3');
|
||||
|
||||
f = function(){ [0 for (x in [])]; }
|
||||
expect = 'function () {\n [0 for (x in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':4');
|
||||
|
||||
f = function(){ [[[0 for (x in [])] for (yyyyyyyyyyy in []) ]
|
||||
for (zzz in [])]; }
|
||||
expect = 'function () {\n [[[0 for (x in [])] for (yyyyyyyyyyy in [])]' +
|
||||
' for (zzz in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':5');
|
||||
|
||||
f = function(){ [[0 for (x in [])] for (y in []) ]; }
|
||||
expect = 'function () {\n [[0 for (x in [])] for (y in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':6');
|
||||
|
||||
f = function(){ [[11 for (x in [])] for (y in []) ]; }
|
||||
expect = 'function () {\n [[11 for (x in [])] for (y in [])];\n}';
|
||||
actual = f + '';
|
||||
reportCompare(expect, actual, summary + ':7');
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 344120;
|
||||
var summary = 'function to source with numeric labels';
|
||||
var actual = '';
|
||||
var expect;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 'function () { x = {1:1};}';
|
||||
actual = ''+function (){x={1:1}}
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 346892;
|
||||
var summary = 'decompilation of new Function("3")';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 'function anonymous() {\n}';
|
||||
actual = (new Function("3")) + '';
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 346902;
|
||||
var summary = 'uneval expressions with object literals';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
expect =
|
||||
'function () {\n' +
|
||||
' ({}[alert(5)]);\n' +
|
||||
'}';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { 1 ? {}[alert(5)] : 0; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
expect =
|
||||
'function () {\n' +
|
||||
' [alert(5)];\n' +
|
||||
'}';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { {}[alert(5)]; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 346904;
|
||||
var summary = 'uneval expressions with double negation, negation decrement';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
// - --
|
||||
expect =
|
||||
'function () {\n' +
|
||||
' return - --x;\n' +
|
||||
'}';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { return - --x; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
// - -
|
||||
expect =
|
||||
'function () {\n' +
|
||||
' return - - x;\n' +
|
||||
'}';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { return - - x; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
// ---
|
||||
expect = 'SyntaxError';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { return ---x; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex.name;
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
// + ++
|
||||
expect =
|
||||
'function () {\n' +
|
||||
' return + ++x;\n' +
|
||||
'}';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { return + ++x; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
// + +
|
||||
expect =
|
||||
'function () {\n' +
|
||||
' return + + x;\n' +
|
||||
'}';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { return + + x; })');
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
reportCompare(expect, actual, summary);
|
||||
}
|
||||
|
||||
// +++
|
||||
|
||||
expect = 'SyntaxError';
|
||||
try
|
||||
{
|
||||
f = eval('(function () { return +++x; })');
|
||||
actual = f + '';
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex.name;
|
||||
}
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 346915;
|
||||
var summary = 'Optimize decompilation of delete expressions';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function() { delete 3; };
|
||||
expect = 'function () {\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// |reftest| skip -- obsolete test
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349484;
|
||||
var summary = 'Incorrect decompilation of import/export statements';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 'function () {\n export x;\n alert(5);\n}';
|
||||
var f = function() { export x; alert(5); };
|
||||
actual = f.toString();
|
||||
print(f.toString());
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
expect = 'function () {\n import o.x;\n alert(5);\n}';
|
||||
f = function () { import o.x; alert(5); }
|
||||
actual = f.toString();
|
||||
print(f.toString());
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349489;
|
||||
var summary = 'Incorrect decompilation of labeled useless statements';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 'function () {\nL:\n 3;\n}';
|
||||
var f = function() { L: 3; };
|
||||
actual = f.toString();
|
||||
print(f.toString());
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
expect = 'function () {\nL:\n 3;\n alert(5);\n}';
|
||||
f = function() { L: 3; alert(5); }
|
||||
actual = f.toString();
|
||||
print(f.toString());
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349491;
|
||||
var summary = 'Incorrect decompilation due to assign to const';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var a;
|
||||
|
||||
a = function () { const z = 3; g = 7; g = z += 1; return g };
|
||||
expect = a();
|
||||
actual = (eval('(' + a + ')'))();
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
a = function () { const z = 3; return z += 2 };
|
||||
expect = a();
|
||||
actual = (eval('(' + a + ')'))();
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
expect = 'function () {\n const z = 3;\n}';
|
||||
a = function () { const z = 3; z = 4; }
|
||||
actual = a.toString();
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
expect = 'function () {\n const z = 3;\n}';
|
||||
a = function () { const z = 3; 4; }
|
||||
actual = a.toString();
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349596;
|
||||
var summary = 'decompilation of labeled if(0)...';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f = function() { L: if (0) return 5 }
|
||||
|
||||
expect = 'function () {\n L: {\n }\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349650;
|
||||
var summary = 'Number getting parens replaces last character of identifier in decompilation of array comprehension';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function() { [5[7] for (y in window)]; }
|
||||
expect = 'function () {\n [(5)[7] for (y in window)];\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 349663;
|
||||
var summary = 'decompilation of Function with const *=';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f, g;
|
||||
|
||||
f = function() { const h; for(null; h *= ""; null) ; }
|
||||
g = eval('(' + f + ')');
|
||||
|
||||
expect = f + '';
|
||||
actual = g + '';
|
||||
|
||||
print(f);
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 350242;
|
||||
var summary = 'decompilation of delete 0x11.x';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function () { delete 0x11.x }
|
||||
expect = 'function () {\n delete (17).x;\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
f = function () { delete (17).x }
|
||||
expect = 'function () {\n delete (17).x;\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 350263;
|
||||
var summary = 'decompilation of labeled if(1);';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function () { L: if(1); }
|
||||
expect = 'function () {\n L: {\n }\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 350271;
|
||||
var summary = 'decompilation if (0x10.(a))';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function () { if(0x10.(a)) { h(); } }
|
||||
expect = 'function () {\n if ((16).(a)) {\n h();\n }\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 350666;
|
||||
var summary = 'decompilation for (;; delete expr)';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function () { for(;; delete y.(x)) { } }
|
||||
actual = f + '';
|
||||
expect = 'function () {\n for (;; y.(x), true) {\n }\n}';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
try
|
||||
{
|
||||
eval('(' + expect + ')');
|
||||
actual = 'No Error';
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
expect = 'No Error';
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
f = function () { for(;; delete (y+x)) { } }
|
||||
actual = f + '';
|
||||
expect = 'function () {\n for (;; y + x, true) {\n }\n}';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
try
|
||||
{
|
||||
eval('(' + expect + ')');
|
||||
actual = 'No Error';
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
expect = 'No Error';
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 350670;
|
||||
var summary = 'decompilation of (for(z() in x)';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function() { for(z() in x) { } }
|
||||
expect = 'function () {\n for (z() in x) {\n }\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
f = function() { for(z(12345678) in x) { } }
|
||||
expect = 'function () {\n for (z(12345678) in x) {\n }\n}';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 351104;
|
||||
var summary = 'decompilation of for with ternary as initializer';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function () { for((0 ? 2 : ({})); ; ) { } }
|
||||
expect = 'function () {\n for ({};;) {\n }\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 351219;
|
||||
var summary = 'Decompilation of immutable infinity, NaN';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f = function () { return 2e308 };
|
||||
expect = 'function () { return 1 / 0; }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary + ' decompile Infinity as 1/0');
|
||||
|
||||
f = function () { var NaN = 1 % 0; return NaN };
|
||||
expect = 'function () { var NaN = 0 / 0; return NaN; }';
|
||||
actual = f + '';
|
||||
compareSource(expect, actual, summary + ': decompile NaN as 0/0');
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// |reftest| skip -- obsolete test
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 351336;
|
||||
var summary = 'decompilation of for initialization containing for';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f = function () { for (("p" in a); 0;) { } }
|
||||
expect = 'function () {\n for (("p" in a); 0;) {\n }\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 351597;
|
||||
var summary = 'decompilation of new expression with extra parens';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
f = function() { new ((x=a))(y) }
|
||||
expect = 'function () {\n new (x = a)(y);\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 351625;
|
||||
var summary = 'decompilation of object literal';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
f = function() { ({a:b, c:3}); }
|
||||
expect = 'function () {\n ({a:b, c:3});\n}';
|
||||
actual = f + '';
|
||||
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// |reftest| skip -- obsolete test
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 351626;
|
||||
var summary = 'decompilation of if(lamda)';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var f;
|
||||
|
||||
f = function () { if (function () {}) { g(); } }
|
||||
actual = f + '';
|
||||
expect = 'function () {\n if (function () {}) {\n g();\n }\n}';
|
||||
compareSource(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче