diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-03-20 10:08:54 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-03-20 10:10:12 +0100 |
commit | 893a886ea38853a1a3e97bcf135ea3cb616cd69a (patch) | |
tree | 5188f8895ce513381917d37115b50f72fb4e64a9 /js/src/jsfun.h | |
parent | 7197b308fb97cd8ab7a972df6a3a17a7a265b594 (diff) | |
parent | 6085bfdcecc2529c1037f813e70583c2a776677d (diff) | |
download | UXP-893a886ea38853a1a3e97bcf135ea3cb616cd69a.tar UXP-893a886ea38853a1a3e97bcf135ea3cb616cd69a.tar.gz UXP-893a886ea38853a1a3e97bcf135ea3cb616cd69a.tar.lz UXP-893a886ea38853a1a3e97bcf135ea3cb616cd69a.tar.xz UXP-893a886ea38853a1a3e97bcf135ea3cb616cd69a.zip |
Add support for the function `name` property.
This resolves #78.
Merged remote-tracking branch 'janek/js_function_name_1'
Diffstat (limited to 'js/src/jsfun.h')
-rw-r--r-- | js/src/jsfun.h | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/js/src/jsfun.h b/js/src/jsfun.h index 88af5c22d..d45d112a5 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -31,6 +31,12 @@ static const uint32_t JSSLOT_BOUND_FUNCTION_ARGS = 4; static const char FunctionConstructorMedialSigils[] = ") {\n"; static const char FunctionConstructorFinalBrace[] = "\n}"; +enum class FunctionPrefixKind { + None, + Get, + Set +}; + class JSFunction : public js::NativeObject { public: @@ -61,7 +67,9 @@ class JSFunction : public js::NativeObject function-statement) */ SELF_HOSTED = 0x0080, /* function is self-hosted builtin and must not be decompilable nor constructible. */ - HAS_REST = 0x0100, /* function has a rest (...) parameter */ + HAS_COMPILE_TIME_NAME = 0x0100, /* function had no explicit name, but a + name was set by SetFunctionName + at compile time */ INTERPRETED_LAZY = 0x0200, /* function is interpreted but doesn't have a script yet */ RESOLVED_LENGTH = 0x0400, /* f.length has been resolved (see fun_resolve). */ RESOLVED_NAME = 0x0800, /* f.name has been resolved (see fun_resolve). */ @@ -95,7 +103,7 @@ class JSFunction : public js::NativeObject NO_XDR_FLAGS = RESOLVED_LENGTH | RESOLVED_NAME, STABLE_ACROSS_CLONES = CONSTRUCTOR | EXPR_BODY | HAS_GUESSED_ATOM | LAMBDA | - SELF_HOSTED | HAS_REST | FUNCTION_KIND_MASK + SELF_HOSTED | HAS_COMPILE_TIME_NAME | FUNCTION_KIND_MASK }; static_assert((INTERPRETED | INTERPRETED_LAZY) == js::JS_FUNCTION_INTERPRETED_BITS, @@ -180,10 +188,10 @@ class JSFunction : public js::NativeObject /* Possible attributes of an interpreted function: */ bool isExprBody() const { return flags() & EXPR_BODY; } + bool hasCompileTimeName() const { return flags() & HAS_COMPILE_TIME_NAME; } bool hasGuessedAtom() const { return flags() & HAS_GUESSED_ATOM; } bool isLambda() const { return flags() & LAMBDA; } bool isBoundFunction() const { return flags() & BOUND_FUN; } - bool hasRest() const { return flags() & HAS_REST; } bool isInterpretedLazy() const { return flags() & INTERPRETED_LAZY; } bool hasScript() const { return flags() & INTERPRETED; } @@ -222,7 +230,7 @@ class JSFunction : public js::NativeObject } bool isNamedLambda() const { - return isLambda() && displayAtom() && !hasGuessedAtom(); + return isLambda() && displayAtom() && !hasCompileTimeName() && !hasGuessedAtom(); } bool hasLexicalThis() const { @@ -264,11 +272,6 @@ class JSFunction : public js::NativeObject this->nargs_ = nargs; } - // Can be called multiple times by the parser. - void setHasRest() { - flags_ |= HAS_REST; - } - void setIsBoundFunction() { MOZ_ASSERT(!isBoundFunction()); flags_ |= BOUND_FUN; @@ -315,14 +318,12 @@ class JSFunction : public js::NativeObject JSAtom* getUnresolvedName(JSContext* cx); - JSAtom* name() const { return hasGuessedAtom() ? nullptr : atom_.get(); } - - // Because display names (see Debugger.Object.displayName) are already stored - // on functions and will always contain a valid es6 function name, as described - // in "ECMA-262 (2016-02-27) 9.2.11 SetFunctionName," we have opted to save - // memory by parsing the existing display name when a function's name property - // is accessed. - JSAtom* functionName(JSContext* cx) const; + JSAtom* explicitName() const { + return (hasCompileTimeName() || hasGuessedAtom()) ? nullptr : atom_.get(); + } + JSAtom* explicitOrCompileTimeName() const { + return hasGuessedAtom() ? nullptr : atom_.get(); + } void initAtom(JSAtom* atom) { atom_.init(atom); } @@ -332,9 +333,24 @@ class JSFunction : public js::NativeObject return atom_; } + void setCompileTimeName(JSAtom* atom) { + MOZ_ASSERT(!atom_); + MOZ_ASSERT(atom); + MOZ_ASSERT(!hasGuessedAtom()); + MOZ_ASSERT(!isClassConstructor()); + atom_ = atom; + flags_ |= HAS_COMPILE_TIME_NAME; + } + JSAtom* compileTimeName() const { + MOZ_ASSERT(hasCompileTimeName()); + MOZ_ASSERT(atom_); + return atom_; + } + void setGuessedAtom(JSAtom* atom) { MOZ_ASSERT(!atom_); MOZ_ASSERT(atom); + MOZ_ASSERT(!hasCompileTimeName()); MOZ_ASSERT(!hasGuessedAtom()); atom_ = atom; flags_ |= HAS_GUESSED_ATOM; @@ -679,7 +695,16 @@ NewFunctionWithProto(ExclusiveContext* cx, JSNative native, unsigned nargs, NewFunctionProtoHandling protoHandling = NewFunctionClassProto); extern JSAtom* -IdToFunctionName(JSContext* cx, HandleId id, const char* prefix = nullptr); +IdToFunctionName(JSContext* cx, HandleId id, + FunctionPrefixKind prefixKind = FunctionPrefixKind::None); + +extern JSAtom* +NameToFunctionName(ExclusiveContext* cx, HandleAtom name, + FunctionPrefixKind prefixKind = FunctionPrefixKind::None); + +extern bool +SetFunctionNameIfNoOwnName(JSContext* cx, HandleFunction fun, HandleValue name, + FunctionPrefixKind prefixKind); extern JSFunction* DefineFunction(JSContext* cx, HandleObject obj, HandleId id, JSNative native, |