summaryrefslogtreecommitdiff
path: root/js/src/jsapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jsapi.cpp')
-rw-r--r--js/src/jsapi.cpp70
1 files changed, 56 insertions, 14 deletions
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<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)