Part 1: Implement ES6 function name property semantics

Issue #78
This commit is contained in:
janekptacijarabaci 2018-03-19 15:47:10 +01:00 • committed by Roy Tam
commit 748c69d7fd
30 changed files with 750 additions and 81 deletions

View file

@ -116,7 +116,7 @@ js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleOb
// Create a new function with AsyncFunctionPrototype, reusing the name and
// the length of `unwrapped`.
RootedAtom funName(cx, unwrapped->name());
RootedAtom funName(cx, unwrapped->explicitName());
uint16_t length;
if (!unwrapped->getLength(cx, &length))
return nullptr;
@ -130,6 +130,9 @@ js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleOb
if (!wrapped)
return nullptr;
if (unwrapped->hasCompileTimeName())
wrapped->setCompileTimeName(unwrapped->compileTimeName());
// Link them to each other to make GetWrappedAsyncFunction and
// GetUnwrappedAsyncFunction work.
unwrapped->setExtendedSlot(UNWRAPPED_ASYNC_WRAPPED_SLOT, ObjectValue(*wrapped));

View file

@ -9509,7 +9509,7 @@ DebuggerObject::name() const
{
MOZ_ASSERT(isFunction());
return referent()->as<JSFunction>().name();
return referent()->as<JSFunction>().explicitName();
}
JSAtom*

View file

@ -802,10 +802,10 @@ GlobalObject::getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global,
return false;
if (exists) {
RootedFunction fun(cx, &funVal.toObject().as<JSFunction>());
if (fun->name() == name)
if (fun->explicitName() == name)
return true;
if (fun->name() == selfHostedName) {
if (fun->explicitName() == selfHostedName) {
// This function was initially cloned because it was called by
// other self-hosted code, so the clone kept its self-hosted name,
// instead of getting the name it's intended to have in content

View file

@ -1860,7 +1860,6 @@ CASE(EnableInterruptsPseudoOpcode)
/* Various 1-byte no-ops. */
CASE(JSOP_NOP)
CASE(JSOP_NOP_DESTRUCTURING)
CASE(JSOP_UNUSED182)
CASE(JSOP_UNUSED183)
CASE(JSOP_UNUSED187)
CASE(JSOP_UNUSED192)
@ -3482,6 +3481,19 @@ CASE(JSOP_TOASYNC)
}
END_CASE(JSOP_TOASYNC)
CASE(JSOP_SETFUNNAME)
{
MOZ_ASSERT(REGS.stackDepth() >= 2);
FunctionPrefixKind prefixKind = FunctionPrefixKind(GET_UINT8(REGS.pc));
ReservedRooted<Value> name(&rootValue0, REGS.sp[-1]);
ReservedRooted<JSFunction*> fun(&rootFunction0, &REGS.sp[-2].toObject().as<JSFunction>());
if (!SetFunctionNameIfNoOwnName(cx, fun, name, prefixKind))
goto error;
REGS.sp--;
}
END_CASE(JSOP_SETFUNNAME)
CASE(JSOP_CALLEE)
MOZ_ASSERT(REGS.fp()->isFunctionFrame());
PUSH_COPY(REGS.fp()->calleev());
@ -4343,7 +4355,7 @@ js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
parent = parent->enclosingEnvironment();
/* ES5 10.5 (NB: with subsequent errata). */
RootedPropertyName name(cx, fun->name()->asPropertyName());
RootedPropertyName name(cx, fun->explicitName()->asPropertyName());
RootedShape shape(cx);
RootedObject pobj(cx);
@ -4991,7 +5003,7 @@ js::ReportRuntimeLexicalError(JSContext* cx, unsigned errorNumber,
RootedPropertyName name(cx);
if (op == JSOP_THROWSETCALLEE) {
name = script->functionNonDelazifying()->name()->asPropertyName();
name = script->functionNonDelazifying()->explicitName()->asPropertyName();
} else if (IsLocalOp(op)) {
name = FrameSlotName(script, pc)->asPropertyName();
} else if (IsAtomOp(op)) {
@ -5059,8 +5071,8 @@ js::ThrowUninitializedThis(JSContext* cx, AbstractFramePtr frame)
if (fun->isDerivedClassConstructor()) {
const char* name = "anonymous";
JSAutoByteString str;
if (fun->name()) {
if (!AtomToPrintableString(cx, fun->name(), &str))
if (fun->explicitName()) {
if (!AtomToPrintableString(cx, fun->explicitName(), &str))
return false;
name = str.ptr();
}

View file

@ -1870,7 +1870,16 @@
* Stack: =>
*/ \
macro(JSOP_POPVARENV, 181, "popvarenv", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED182, 182,"unused182", NULL, 1, 0, 0, JOF_BYTE) \
/*
* Pops the top two values on the stack as 'name' and 'fun', defines the
* name of 'fun' to 'name' with prefix if any, and pushes 'fun' back onto
* the stack.
* Category: Statements
* Type: Function
* Operands: uint8_t prefixKind
* Stack: fun, name => fun
*/ \
macro(JSOP_SETFUNNAME, 182,"setfunname", NULL, 2, 2, 1, JOF_UINT8) \
macro(JSOP_UNUSED183, 183,"unused183", NULL, 1, 0, 0, JOF_BYTE) \
\
/*

View file

@ -2878,7 +2878,7 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
RootedObject clone(cx);
if (selfHostedObject->is<JSFunction>()) {
RootedFunction selfHostedFunction(cx, &selfHostedObject->as<JSFunction>());
bool hasName = selfHostedFunction->name() != nullptr;
bool hasName = selfHostedFunction->explicitName() != nullptr;
// Arrow functions use the first extended slot for their lexical |this| value.
MOZ_ASSERT(!selfHostedFunction->isArrow());
@ -2894,7 +2894,7 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
// self-hosting compartment has to be stored on the clone.
if (clone && hasName) {
clone->as<JSFunction>().setExtendedSlot(LAZY_FUNCTION_NAME_SLOT,
StringValue(selfHostedFunction->name()));
StringValue(selfHostedFunction->explicitName()));
}
} else if (selfHostedObject->is<RegExpObject>()) {
RegExpObject& reobj = selfHostedObject->as<RegExpObject>();
@ -2977,10 +2977,10 @@ JSRuntime::createLazySelfHostedFunctionClone(JSContext* cx, HandlePropertyName s
return false;
if (!selfHostedFun->isClassConstructor() && !selfHostedFun->hasGuessedAtom() &&
selfHostedFun->name() != selfHostedName)
selfHostedFun->explicitName() != selfHostedName)
{
MOZ_ASSERT(selfHostedFun->getExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT).toBoolean());
funName = selfHostedFun->name();
funName = selfHostedFun->explicitName();
}
fun.set(NewScriptedFunction(cx, nargs, JSFunction::INTERPRETED_LAZY,

View file

@ -4541,7 +4541,7 @@ TypeScript::printTypes(JSContext* cx, HandleScript script) const
uintptr_t(script.get()), script->filename(), script->lineno());
if (script->functionNonDelazifying()) {
if (JSAtom* name = script->functionNonDelazifying()->name())
if (JSAtom* name = script->functionNonDelazifying()->explicitName())
name->dumpCharsNoNewline();
}

View file

@ -2870,7 +2870,7 @@ bool
DataViewObject::defineGetter(JSContext* cx, PropertyName* name, HandleNativeObject proto)
{
RootedId id(cx, NameToId(name));
RootedAtom atom(cx, IdToFunctionName(cx, id, "get"));
RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Get));
if (!atom)
return false;
unsigned attrs = JSPROP_SHARED | JSPROP_GETTER;