summaryrefslogtreecommitdiffstats
path: root/js/src/jsfun.h
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-03-20 10:08:54 +0100
committerwolfbeast <mcwerewolf@gmail.com>2018-03-20 10:10:12 +0100
commit893a886ea38853a1a3e97bcf135ea3cb616cd69a (patch)
tree5188f8895ce513381917d37115b50f72fb4e64a9 /js/src/jsfun.h
parent7197b308fb97cd8ab7a972df6a3a17a7a265b594 (diff)
parent6085bfdcecc2529c1037f813e70583c2a776677d (diff)
downloadUXP-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.h61
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,