From af300f36f11293c12f2ee01580fc749a7e114376 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Fri, 16 Mar 2018 11:35:57 +0100 Subject: Bug 755821: Function() should use the parser's argument parsing code --- js/src/jsapi.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 14 deletions(-) (limited to 'js/src/jsapi.cpp') diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index ee9c610594..e6fc1f98bd 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -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 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, ¶meterListEnd)) + 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) -- cgit v1.2.3