Bug 1212794 - Remove decompile-body functionality. r=till

This commit is contained in:
Tom Schuster 2015-10-13 23:43:14 +02:00
parent f6dde272fb
commit 7de30b64ba
12 changed files with 37 additions and 84 deletions

View File

@ -1,4 +0,0 @@
// Binary: cache/js-dbg-64-462106f027af-linux
// Flags:
//
decompileBody(function () { });

View File

@ -2,12 +2,10 @@ var f = Function("a", "b", "return a + b;");
assertEq(f.toString(), "function anonymous(a, b) {\nreturn a + b;\n}");
assertEq(f.toSource(), "(function anonymous(a, b) {\nreturn a + b;\n})");
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) {\nreturn rest[42] + b;\n}");
assertEq(f.toSource(), "(function anonymous(a, ...rest) {\nreturn rest[42] + b;\n})")
assertEq(decompileFunction(f), f.toString());
assertEq(decompileBody(f), "return rest[42] + b;");
f = Function("");
assertEq(f.toString(), "function anonymous() {\n\n}");
f = Function("", "(abc)");

View File

@ -2,7 +2,6 @@ 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");

View File

@ -4,4 +4,4 @@ function getgen() {
var gen;
(getgen() for (x of [1])).next();
assertEq(gen.toSource(), "function genexp() {\n [generator expression]\n}");
assertEq(decompileBody(gen), "\n [generator expression]\n");
assertEq(gen.toString(), gen.toSource());

View File

@ -2,14 +2,11 @@ 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; ");

View File

@ -7,7 +7,5 @@ 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), "");
function f3() { }
assertEq(f3.toString(), "function f3() { }");
assertEq(decompileBody(f3), " ");

View File

@ -4583,17 +4583,7 @@ JS_DecompileFunction(JSContext* cx, HandleFunction fun, unsigned indent)
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, fun);
return FunctionToString(cx, fun, false, !(indent & JS_DONT_PRETTY_PRINT));
}
JS_PUBLIC_API(JSString*)
JS_DecompileFunctionBody(JSContext* cx, HandleFunction fun, unsigned indent)
{
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, fun);
return FunctionToString(cx, fun, true, !(indent & JS_DONT_PRETTY_PRINT));
return FunctionToString(cx, fun, !(indent & JS_DONT_PRETTY_PRINT));
}
MOZ_NEVER_INLINE static bool

View File

@ -4047,15 +4047,13 @@ JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script, const char* name
/*
* API extension: OR this into indent to avoid pretty-printing the decompiled
* source resulting from JS_DecompileFunction{,Body}.
* source resulting from JS_DecompileFunction.
*/
#define JS_DONT_PRETTY_PRINT ((unsigned)0x8000)
extern JS_PUBLIC_API(JSString*)
JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun, unsigned indent);
extern JS_PUBLIC_API(JSString*)
JS_DecompileFunctionBody(JSContext* cx, JS::Handle<JSFunction*> fun, unsigned indent);
/*
* NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either

View File

@ -909,7 +909,7 @@ js::FindBody(JSContext* cx, HandleFunction fun, HandleLinearString src, size_t*
}
JSString*
js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lambdaParen)
js::FunctionToString(JSContext* cx, HandleFunction fun, bool lambdaParen)
{
if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
return nullptr;
@ -925,9 +925,9 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
if (fun->hasScript()) {
script = fun->nonLazyScript();
if (script->isGeneratorExp()) {
if ((!bodyOnly && !out.append("function genexp() {")) ||
if (!out.append("function genexp() {") ||
!out.append("\n [generator expression]\n") ||
(!bodyOnly && !out.append("}")))
!out.append("}"))
{
return nullptr;
}
@ -937,21 +937,21 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
bool funIsMethodOrNonArrowLambda = (fun->isLambda() && !fun->isArrow()) || fun->isMethod() ||
fun->isGetter() || fun->isSetter();
if (!bodyOnly) {
// If we're not in pretty mode, put parentheses around lambda functions and methods.
if (fun->isInterpreted() && !lambdaParen && funIsMethodOrNonArrowLambda) {
if (!out.append("("))
return nullptr;
}
if (!fun->isArrow()) {
if (!(fun->isStarGenerator() ? out.append("function* ") : out.append("function ")))
return nullptr;
}
if (fun->atom()) {
if (!out.append(fun->atom()))
return nullptr;
}
// If we're not in pretty mode, put parentheses around lambda functions and methods.
if (fun->isInterpreted() && !lambdaParen && funIsMethodOrNonArrowLambda) {
if (!out.append("("))
return nullptr;
}
if (!fun->isArrow()) {
if (!(fun->isStarGenerator() ? out.append("function* ") : out.append("function ")))
return nullptr;
}
if (fun->atom()) {
if (!out.append(fun->atom()))
return nullptr;
}
bool haveSource = fun->isInterpreted() && !fun->isSelfHostedBuiltin();
if (haveSource && !script->scriptSource()->hasSourceData() &&
!JSScript::loadSource(cx, script->scriptSource(), &haveSource))
@ -987,7 +987,7 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
// resulting function will have the same semantics.
bool addUseStrict = script->strict() && !script->explicitUseStrict() && !fun->isArrow();
bool buildBody = funCon && !bodyOnly;
bool buildBody = funCon;
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
@ -1012,7 +1012,7 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
if (!out.append(") {\n"))
return nullptr;
}
if ((bodyOnly && !funCon) || addUseStrict) {
if (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.
size_t bodyStart = 0, bodyEnd;
@ -1043,10 +1043,8 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
}
}
// Output just the body (for bodyOnly) or the body and possibly
// closing braces (for addUseStrict).
size_t dependentEnd = bodyOnly ? bodyEnd : src->length();
if (!out.appendSubstring(src, bodyStart, dependentEnd - bodyStart))
// Output the body and possibly closing braces (for addUseStrict).
if (!out.appendSubstring(src, bodyStart, src->length() - bodyStart))
return nullptr;
} else {
if (!out.append(src))
@ -1056,32 +1054,30 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
if (!out.append("\n}"))
return nullptr;
}
if (bodyOnly) {
// Slap a semicolon on the end of functions with an expression body.
if (exprBody && !out.append(";"))
return nullptr;
} else if (!lambdaParen && funIsMethodOrNonArrowLambda) {
if (!lambdaParen && funIsMethodOrNonArrowLambda) {
if (!out.append(")"))
return nullptr;
}
} else if (fun->isInterpreted() && !fun->isSelfHostedBuiltin()) {
if ((!bodyOnly && !out.append("() {\n ")) ||
if (!out.append("() {\n ") ||
!out.append("[sourceless code]") ||
(!bodyOnly && !out.append("\n}")))
!out.append("\n}"))
{
return nullptr;
}
if (!lambdaParen && fun->isLambda() && !fun->isArrow() && !out.append(")"))
return nullptr;
} else {
MOZ_ASSERT(!fun->isExprBody());
if (fun->isNative() && fun->native() == js::DefaultDerivedClassConstructor) {
if ((!bodyOnly && !out.append("(...args) {\n ")) ||
if (!out.append("(...args) {\n ") ||
!out.append("super(...args);\n}"))
{
return nullptr;
}
} else {
if (!bodyOnly && !out.append("() {\n "))
if (!out.append("() {\n "))
return nullptr;
if (!fun->isNative() || fun->native() != js::DefaultClassConstructor) {
@ -1089,7 +1085,7 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lamb
return nullptr;
}
if (!bodyOnly && !out.append("\n}"))
if (!out.append("\n}"))
return nullptr;
}
}
@ -1110,7 +1106,7 @@ fun_toStringHelper(JSContext* cx, HandleObject obj, unsigned indent)
}
RootedFunction fun(cx, &obj->as<JSFunction>());
return FunctionToString(cx, fun, false, indent != JS_DONT_PRETTY_PRINT);
return FunctionToString(cx, fun, indent != JS_DONT_PRETTY_PRINT);
}
bool

View File

@ -761,7 +761,7 @@ JSFunction::getExtendedSlot(size_t which) const
namespace js {
JSString* FunctionToString(JSContext* cx, HandleFunction fun, bool bodyOnly, bool lambdaParen);
JSString* FunctionToString(JSContext* cx, HandleFunction fun, bool lambdaParen);
template<XDRMode mode>
bool

View File

@ -3698,8 +3698,7 @@ NestedShell(JSContext* cx, unsigned argc, Value* vp)
}
static bool
DecompileFunctionSomehow(JSContext* cx, unsigned argc, Value* vp,
JSString* (*decompiler)(JSContext*, HandleFunction, unsigned))
DecompileFunction(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 1 || !args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
@ -3707,25 +3706,13 @@ DecompileFunctionSomehow(JSContext* cx, unsigned argc, Value* vp,
return true;
}
RootedFunction fun(cx, &args[0].toObject().as<JSFunction>());
JSString* result = decompiler(cx, fun, 0);
JSString* result = JS_DecompileFunction(cx, fun, 0);
if (!result)
return false;
args.rval().setString(result);
return true;
}
static bool
DecompileBody(JSContext* cx, unsigned argc, Value* vp)
{
return DecompileFunctionSomehow(cx, argc, vp, JS_DecompileFunctionBody);
}
static bool
DecompileFunction(JSContext* cx, unsigned argc, Value* vp)
{
return DecompileFunctionSomehow(cx, argc, vp, JS_DecompileFunction);
}
static bool
DecompileThisScript(JSContext* cx, unsigned argc, Value* vp)
{
@ -4866,10 +4853,6 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
"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."),

View File

@ -10,8 +10,6 @@ function testRunOptionStrictMode(str, arg, result) {
}
assertEq(eval(uneval(testRunOptionStrictMode()))(), true);
if (typeof decompileBody !== "undefined") {
assertEq(decompileBody(new Function('x', 'return x*2;')).includes('\n"use strict"'), true);
}
assertEq((new Function('x', 'return x*2;')).toSource().includes('\n"use strict"'), true);
reportCompare(true, true);