diff options
Diffstat (limited to 'js/src/jsapi.cpp')
-rw-r--r-- | js/src/jsapi.cpp | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index ee9c61059..85a38bba4 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; @@ -2093,7 +2095,7 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val getter != JS_PropertyStub && setter != JS_StrictPropertyStub) { if (getter && !(attrs & JSPROP_GETTER)) { - RootedAtom atom(cx, IdToFunctionName(cx, id, "get")); + RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Get)); if (!atom) return false; JSFunction* getobj = NewNativeFunction(cx, (Native) getter, 0, atom); @@ -2109,7 +2111,7 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val if (setter && !(attrs & JSPROP_SETTER)) { // Root just the getter, since the setter is not yet a JSObject. AutoRooterGetterSetter getRoot(cx, JSPROP_GETTER, &getter, nullptr); - RootedAtom atom(cx, IdToFunctionName(cx, id, "set")); + RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Set)); if (!atom) return false; JSFunction* setobj = NewNativeFunction(cx, (Native) setter, 1, atom); @@ -3433,10 +3435,7 @@ JS::NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id) { return nullptr; } - JSFunction* fun = &funVal.toObject().as<JSFunction>(); - if (fs->flags & JSFUN_HAS_REST) - fun->setHasRest(); - return fun; + return &funVal.toObject().as<JSFunction>(); } RootedAtom atom(cx, IdToFunctionName(cx, id)); @@ -3616,7 +3615,7 @@ JS_GetFunctionObject(JSFunction* fun) JS_PUBLIC_API(JSString*) JS_GetFunctionId(JSFunction* fun) { - return fun->name(); + return fun->explicitName(); } JS_PUBLIC_API(JSString*) @@ -4232,15 +4231,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 +4255,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 +4267,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 +4321,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) |