Stage 1-1: Implement Function.prototype.toString revision proposal.

Tag #960
This commit is contained in:
wolfbeast 2019-02-02 12:47:28 +01:00 • committed by Roy Tam
commit b68de773fd
13 changed files with 330 additions and 154 deletions

View file

@ -4250,7 +4250,7 @@ JS_GetFunctionScript(JSContext* cx, HandleFunction fun)
*/
static bool
CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
const char* name,
HandleAtom name, bool isInvalidName,
SourceBufferHolder& srcBuf, uint32_t parameterListEnd,
HandleObject enclosingEnv, HandleScope enclosingScope,
MutableHandleFunction fun)
@ -4261,13 +4261,8 @@ CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
assertSameCompartment(cx, enclosingEnv);
RootedAtom funAtom(cx);
if (name) {
funAtom = Atomize(cx, name, strlen(name));
if (!funAtom)
return false;
}
fun.set(NewScriptedFunction(cx, 0, JSFunction::INTERPRETED_NORMAL, funAtom,
fun.set(NewScriptedFunction(cx, 0, JSFunction::INTERPRETED_NORMAL,
isInvalidName ? nullptr : name,
/* proto = */ nullptr,
gc::AllocKind::FUNCTION, TenuredObject,
enclosingEnv));
@ -4285,11 +4280,17 @@ CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
return false;
}
// When function name is not a valid identifier, the generated function
// source in srcBuf doesn't have a function name. Set it here.
if (isInvalidName)
fun->setAtom(name);
return true;
}
static MOZ_MUST_USE bool
BuildFunctionString(unsigned nargs, const char* const* argnames,
BuildFunctionString(const char* name, size_t nameLen,
unsigned nargs, const char* const* argnames,
const SourceBufferHolder& srcBuf, StringBuffer* out,
uint32_t* parameterListEnd)
{
@ -4298,6 +4299,12 @@ BuildFunctionString(unsigned nargs, const char* const* argnames,
if (!out->ensureTwoByteChars())
return false;
if (!out->append("function "))
return false;
if (name) {
if (!out->append(name, nameLen))
return false;
}
if (!out->append("("))
return false;
for (unsigned i = 0; i < nargs; i++) {
@ -4334,15 +4341,32 @@ JS::CompileFunction(JSContext* cx, AutoObjectVector& envChain,
if (!CreateNonSyntacticEnvironmentChain(cx, envChain, &env, &scope))
return false;
size_t nameLen = 0;
bool isInvalidName = false;
RootedAtom nameAtom(cx);
if (name) {
nameLen = strlen(name);
nameAtom = Atomize(cx, name, nameLen);
if (!nameAtom)
return false;
// If name is not valid identifier
if (!js::frontend::IsIdentifier(name, nameLen))
isInvalidName = true;
}
uint32_t parameterListEnd;
StringBuffer funStr(cx);
if (!BuildFunctionString(nargs, argnames, srcBuf, &funStr, &parameterListEnd))
if (!BuildFunctionString(isInvalidName ? nullptr : name, nameLen, nargs, argnames, srcBuf,
&funStr, &parameterListEnd)) {
return false;
}
size_t newLen = funStr.length();
SourceBufferHolder newSrcBuf(funStr.stealChars(), newLen, SourceBufferHolder::GiveOwnership);
return CompileFunction(cx, options, name, newSrcBuf, parameterListEnd, env, scope, fun);
return CompileFunction(cx, options, nameAtom, isInvalidName, newSrcBuf, parameterListEnd, env,
scope, fun);
}
JS_PUBLIC_API(bool)