Bug 1147144 - OdinMonkey: fix toString() on asm.js module when source discarding is enabled (r=bbouvier)

--HG--
extra : rebase_source : b8ec54fdbae503230efb4a1eb74638254c32b6c3
This commit is contained in:
Luke Wagner 2015-03-26 14:37:19 -05:00
parent 8b1839a458
commit 4c44332a0c
2 changed files with 85 additions and 50 deletions

View File

@ -1176,9 +1176,6 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
ScriptSource *source = module.scriptSource();
StringBuffer out(cx);
// Whether the function has been created with a Function ctor
bool funCtor = begin == 0 && end == source->length() && source->argumentsNotIncluded();
if (addParenToLambda && fun->isLambda() && !out.append("("))
return nullptr;
@ -1188,43 +1185,54 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
if (fun->atom() && !out.append(fun->atom()))
return nullptr;
if (funCtor) {
// Functions created with the function constructor don't have arguments in their source.
if (!out.append("("))
return nullptr;
if (PropertyName *argName = module.globalArgumentName()) {
if (!out.append(argName))
return nullptr;
}
if (PropertyName *argName = module.importArgumentName()) {
if (!out.append(", ") || !out.append(argName))
return nullptr;
}
if (PropertyName *argName = module.bufferArgumentName()) {
if (!out.append(", ") || !out.append(argName))
return nullptr;
}
if (!out.append(") {\n"))
return nullptr;
}
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
bool haveSource = source->hasSourceData();
if (!haveSource && !JSScript::loadSource(cx, source, &haveSource))
return nullptr;
if (module.strict()) {
if (!AppendUseStrictSource(cx, fun, src, out))
if (!haveSource) {
if (!out.append("() {\n [sourceless code]\n}"))
return nullptr;
} else {
if (!out.append(src))
// Whether the function has been created with a Function ctor
bool funCtor = begin == 0 && end == source->length() && source->argumentsNotIncluded();
if (funCtor) {
// Functions created with the function constructor don't have arguments in their source.
if (!out.append("("))
return nullptr;
if (PropertyName *argName = module.globalArgumentName()) {
if (!out.append(argName))
return nullptr;
}
if (PropertyName *argName = module.importArgumentName()) {
if (!out.append(", ") || !out.append(argName))
return nullptr;
}
if (PropertyName *argName = module.bufferArgumentName()) {
if (!out.append(", ") || !out.append(argName))
return nullptr;
}
if (!out.append(") {\n"))
return nullptr;
}
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (module.strict()) {
if (!AppendUseStrictSource(cx, fun, src, out))
return nullptr;
} else {
if (!out.append(src))
return nullptr;
}
if (funCtor && !out.append("\n}"))
return nullptr;
}
if (funCtor && !out.append("\n}"))
return nullptr;
if (addParenToLambda && fun->isLambda() && !out.append(")"))
return nullptr;
@ -1276,33 +1284,46 @@ js::AsmJSFunctionToString(JSContext *cx, HandleFunction fun)
ScriptSource *source = module.scriptSource();
StringBuffer out(cx);
// asm.js functions cannot have been created with a Function constructor
// as they belong within a module.
MOZ_ASSERT(!(begin == 0 && end == source->length() && source->argumentsNotIncluded()));
if (!out.append("function "))
return nullptr;
if (module.strict()) {
// AppendUseStrictSource expects its input to start right after the
// function name, so split the source chars from the src into two parts:
// the function name and the rest (arguments + body).
bool haveSource = source->hasSourceData();
if (!haveSource && !JSScript::loadSource(cx, source, &haveSource))
return nullptr;
if (!haveSource) {
// asm.js functions can't be anonymous
MOZ_ASSERT(fun->atom());
if (!out.append(fun->atom()))
return nullptr;
size_t nameEnd = begin + fun->atom()->length();
Rooted<JSFlatString*> src(cx, source->substring(cx, nameEnd, end));
if (!AppendUseStrictSource(cx, fun, src, out))
if (!out.append("() {\n [sourceless code]\n}"))
return nullptr;
} else {
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (!out.append(src))
return nullptr;
// asm.js functions cannot have been created with a Function constructor
// as they belong within a module.
MOZ_ASSERT(!(begin == 0 && end == source->length() && source->argumentsNotIncluded()));
if (module.strict()) {
// AppendUseStrictSource expects its input to start right after the
// function name, so split the source chars from the src into two parts:
// the function name and the rest (arguments + body).
// asm.js functions can't be anonymous
MOZ_ASSERT(fun->atom());
if (!out.append(fun->atom()))
return nullptr;
size_t nameEnd = begin + fun->atom()->length();
Rooted<JSFlatString*> src(cx, source->substring(cx, nameEnd, end));
if (!AppendUseStrictSource(cx, fun, src, out))
return nullptr;
} else {
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (!out.append(src))
return nullptr;
}
}
return out.finishString();

View File

@ -0,0 +1,14 @@
load(libdir + 'asm.js');
setLazyParsingEnabled(false)
assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`).toString(), "function asmModule() {\n [sourceless code]\n}");
assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`).toSource(), "(function asmModule() {\n [sourceless code]\n})");
assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`)().toString(), "function asmFun() {\n [sourceless code]\n}");
assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`)().toSource(), "function asmFun() {\n [sourceless code]\n}");
assertEq((evaluate(`function asmModule1() { "use asm"; function asmFun() {} return asmFun }`), asmModule1).toString(), "function asmModule1() {\n [sourceless code]\n}");
assertEq((evaluate(`function asmModule2() { "use asm"; function asmFun() {} return asmFun }`), asmModule2).toSource(), "function asmModule2() {\n [sourceless code]\n}");
assertEq((evaluate(`function asmModule3() { "use asm"; function asmFun() {} return asmFun }`), asmModule3)().toString(), "function asmFun() {\n [sourceless code]\n}");
assertEq((evaluate(`function asmModule4() { "use asm"; function asmFun() {} return asmFun }`), asmModule4)().toSource(), "function asmFun() {\n [sourceless code]\n}");
assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`).toString(), "function anonymous() {\n [sourceless code]\n}");
assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`).toSource(), "(function anonymous() {\n [sourceless code]\n})");
assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`)().toString(), "function asmFun() {\n [sourceless code]\n}");
assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`)().toSource(), "function asmFun() {\n [sourceless code]\n}");