From 53e46b1e12ef01ccaabb3256738ea1eac74b7941 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 13 Jul 2019 21:33:52 -0400 Subject: 1216630 - Print class source when calling toString on the constructor. This is accomplished in the following ways. LazyScripts and JSScripts now have 4 offsets: - Source begin and end for the actual source. This is used for lazy parsing. - toString begin and end for toString. Some kinds of functions, like async, only have a different begin offset. Class constructors have different offsets for both begin and end. For syntactically present (i.e. non-default) constructors, the class source span is remembered directly on the LazyScript or JSScript. The toString implementation then splices out the substring directly. For default constructors, a new SRC_CLASS SrcNote type is added. It's binary and has as its arguments the begin and end offsets of the class expression or statement. MakeDefaultConstructor reads the note and overrides the cloned self-hosted function's source object. This is probably the least intrusive way to accomplish this. --- js/src/jsfun.cpp | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'js/src/jsfun.cpp') diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 470746d50..4f15e78c2 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -821,7 +821,7 @@ CreateFunctionPrototype(JSContext* cx, JSProtoKey key) sourceObject, begin, ss->length(), - 0)); + 0, 0)); if (!script || !JSScript::initFunctionPrototype(cx, script, functionProto)) return nullptr; @@ -954,7 +954,13 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool prettyPrint) } bool funIsNonArrowLambda = fun->isLambda() && !fun->isArrow(); - bool haveSource = fun->isInterpreted() && !fun->isSelfHostedBuiltin(); + + // Default class constructors are self-hosted, but have their source + // objects overridden to refer to the span of the class statement or + // expression. Non-default class constructors are never self-hosted. So, + // all class constructors always have source. + bool haveSource = fun->isInterpreted() && (fun->isClassConstructor() || + !fun->isSelfHostedBuiltin()); // If we're not in pretty mode, put parentheses around lambda functions // so that eval returns lambda, not function statement. @@ -995,7 +1001,7 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool prettyPrint) }; if (haveSource) { - Rooted src(cx, JSScript::sourceDataWithPrelude(cx, script)); + Rooted src(cx, JSScript::sourceDataForToString(cx, script)); if (!src) return nullptr; @@ -1015,27 +1021,18 @@ js::FunctionToString(JSContext* cx, HandleFunction fun, bool prettyPrint) return nullptr; } } else { - bool derived = fun->infallibleIsDefaultClassConstructor(cx); - if (derived && fun->isDerivedClassConstructor()) { - if (!AppendPrelude() || - !out.append("(...args) {\n ") || - !out.append("super(...args);\n}")) - { - return nullptr; - } - } else { - if (!AppendPrelude() || - !out.append("() {\n ")) - return nullptr; + // Default class constructors should always haveSource. + MOZ_ASSERT(!fun->infallibleIsDefaultClassConstructor(cx)); - if (!derived) { - if (!out.append("[native code]")) - return nullptr; - } + if (!AppendPrelude() || + !out.append("() {\n ")) + return nullptr; - if (!out.append("\n}")) - return nullptr; - } + if (!out.append("[native code]")) + return nullptr; + + if (!out.append("\n}")) + return nullptr; } return out.finishString(); } -- cgit v1.2.3