summaryrefslogtreecommitdiffstats
path: root/js/src/jsapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jsapi.cpp')
-rw-r--r--js/src/jsapi.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 6114b8157..f78f94dc1 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -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)