Bug 755821: Function() should use the parser's argument parsing code

This commit is contained in:
janekptacijarabaci 2018-03-16 11:35:57 +01:00 committed by Roy Tam
commit 0e7a16c088
24 changed files with 321 additions and 469 deletions

View file

@ -11,6 +11,7 @@
#include "jsapi.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/Maybe.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Sprintf.h"
@ -107,6 +108,7 @@ using namespace js::gc;
using mozilla::Maybe;
using mozilla::PodCopy;
using mozilla::PodZero;
using mozilla::Some;
using JS::AutoGCRooter;
using JS::ToInt32;
@ -4232,15 +4234,15 @@ JS_GetFunctionScript(JSContext* cx, HandleFunction fun)
}
/*
* enclosingScope is a static enclosing scope, if any (e.g. a WithScope). If
* the enclosing scope is the global scope, this must be null.
* enclosingScope is a scope, if any (e.g. a WithScope). If the scope is the
* global scope, this must be null.
*
* enclosingDynamicScope is a dynamic scope to use, if it's not the global.
* enclosingEnv is an environment to use, if it's not the global.
*/
static bool
CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
const char* name, unsigned nargs, const char* const* argnames,
SourceBufferHolder& srcBuf,
const char* name,
SourceBufferHolder& srcBuf, uint32_t parameterListEnd,
HandleObject enclosingEnv, HandleScope enclosingScope,
MutableHandleFunction fun)
{
@ -4256,13 +4258,6 @@ CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
return false;
}
Rooted<PropertyNameVector> formals(cx, PropertyNameVector(cx));
for (unsigned i = 0; i < nargs; i++) {
RootedAtom argAtom(cx, Atomize(cx, argnames[i], strlen(argnames[i])));
if (!argAtom || !formals.append(argAtom->asPropertyName()))
return false;
}
fun.set(NewScriptedFunction(cx, 0, JSFunction::INTERPRETED_NORMAL, funAtom,
/* proto = */ nullptr,
gc::AllocKind::FUNCTION, TenuredObject,
@ -4275,7 +4270,45 @@ CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
MOZ_ASSERT_IF(!IsGlobalLexicalEnvironment(enclosingEnv),
enclosingScope->hasOnChain(ScopeKind::NonSyntactic));
if (!frontend::CompileFunctionBody(cx, fun, optionsArg, formals, srcBuf, enclosingScope))
if (!frontend::CompileStandaloneFunction(cx, fun, optionsArg, srcBuf,
Some(parameterListEnd), enclosingScope))
{
return false;
}
return true;
}
static MOZ_MUST_USE bool
BuildFunctionString(unsigned nargs, const char* const* argnames,
const SourceBufferHolder& srcBuf, StringBuffer* out,
uint32_t* parameterListEnd)
{
MOZ_ASSERT(out);
MOZ_ASSERT(parameterListEnd);
if (!out->ensureTwoByteChars())
return false;
if (!out->append("("))
return false;
for (unsigned i = 0; i < nargs; i++) {
if (i != 0) {
if (!out->append(", "))
return false;
}
if (!out->append(argnames[i], strlen(argnames[i])))
return false;
}
// Remember the position of ")".
*parameterListEnd = out->length();
MOZ_ASSERT(FunctionConstructorMedialSigils[0] == ')');
if (!out->append(FunctionConstructorMedialSigils))
return false;
if (!out->append(srcBuf.get(), srcBuf.length()))
return false;
if (!out->append(FunctionConstructorFinalBrace))
return false;
return true;
@ -4291,7 +4324,16 @@ JS::CompileFunction(JSContext* cx, AutoObjectVector& envChain,
RootedScope scope(cx);
if (!CreateNonSyntacticEnvironmentChain(cx, envChain, &env, &scope))
return false;
return CompileFunction(cx, options, name, nargs, argnames, srcBuf, env, scope, fun);
uint32_t parameterListEnd;
StringBuffer funStr(cx);
if (!BuildFunctionString(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);
}
JS_PUBLIC_API(bool)