mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-09 04:54:33 +00:00
#521: async/await M1185106 parts 0, 1
This commit is contained in:
parent
7e7cdb504d
commit
d0348b2d1e
@ -6429,7 +6429,7 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line, unsigned* c
|
|||||||
AsmJSParseContext* outerpc = m.parser().pc;
|
AsmJSParseContext* outerpc = m.parser().pc;
|
||||||
|
|
||||||
Directives directives(outerpc);
|
Directives directives(outerpc);
|
||||||
FunctionBox* funbox = m.parser().newFunctionBox(fn, fun, outerpc, directives, NotGenerator);
|
FunctionBox* funbox = m.parser().newFunctionBox(fn, fun, outerpc, directives, NotGenerator, SyncFunction);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -312,6 +312,7 @@ BytecodeCompiler::saveCallerFun(HandleScript evalCaller)
|
|||||||
Directives directives(/* strict = */ options.strictOption);
|
Directives directives(/* strict = */ options.strictOption);
|
||||||
ObjectBox* funbox = parser->newFunctionBox(/* fn = */ nullptr, fun,
|
ObjectBox* funbox = parser->newFunctionBox(/* fn = */ nullptr, fun,
|
||||||
directives, fun->generatorKind(),
|
directives, fun->generatorKind(),
|
||||||
|
fun->asyncKind(),
|
||||||
enclosingStaticScope);
|
enclosingStaticScope);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
@ -6401,6 +6401,13 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||||||
MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
|
MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
|
||||||
pn->setOp(JSOP_FUNWITHPROTO);
|
pn->setOp(JSOP_FUNWITHPROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pn->getOp() == JSOP_DEFFUN) {
|
||||||
|
if (!emitIndex32(JSOP_LAMBDA, index))
|
||||||
|
return false;
|
||||||
|
return emit1(JSOP_DEFFUN);
|
||||||
|
}
|
||||||
|
|
||||||
return emitIndex32(pn->getOp(), index);
|
return emitIndex32(pn->getOp(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6441,7 +6448,9 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||||||
MOZ_ASSERT(pn->pn_scopecoord.isFree());
|
MOZ_ASSERT(pn->pn_scopecoord.isFree());
|
||||||
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
|
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
|
||||||
switchToPrologue();
|
switchToPrologue();
|
||||||
if (!emitIndex32(JSOP_DEFFUN, index))
|
if (!emitIndex32(JSOP_LAMBDA, index))
|
||||||
|
return false;
|
||||||
|
if (!emit1(JSOP_DEFFUN))
|
||||||
return false;
|
return false;
|
||||||
if (!updateSourceCoordNotes(pn->pn_pos.begin))
|
if (!updateSourceCoordNotes(pn->pn_pos.begin))
|
||||||
return false;
|
return false;
|
||||||
|
@ -689,7 +689,8 @@ Parser<FullParseHandler>::cloneParseTree(ParseNode* opn)
|
|||||||
RootedFunction fun(context, opn->pn_funbox->function());
|
RootedFunction fun(context, opn->pn_funbox->function());
|
||||||
NULLCHECK(pn->pn_funbox = newFunctionBox(pn, fun, pc,
|
NULLCHECK(pn->pn_funbox = newFunctionBox(pn, fun, pc,
|
||||||
Directives(/* strict = */ opn->pn_funbox->strict()),
|
Directives(/* strict = */ opn->pn_funbox->strict()),
|
||||||
opn->pn_funbox->generatorKind()));
|
opn->pn_funbox->generatorKind(),
|
||||||
|
opn->pn_funbox->asyncKind()));
|
||||||
NULLCHECK(pn->pn_body = cloneParseTree(opn->pn_body));
|
NULLCHECK(pn->pn_body = cloneParseTree(opn->pn_body));
|
||||||
pn->pn_scopecoord = opn->pn_scopecoord;
|
pn->pn_scopecoord = opn->pn_scopecoord;
|
||||||
pn->pn_dflags = opn->pn_dflags;
|
pn->pn_dflags = opn->pn_dflags;
|
||||||
|
@ -760,7 +760,8 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
|
|||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
||||||
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
|
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
|
||||||
Directives directives, bool extraWarnings, GeneratorKind generatorKind)
|
Directives directives, bool extraWarnings, GeneratorKind generatorKind,
|
||||||
|
FunctionAsyncKind asyncKind)
|
||||||
: ObjectBox(fun, traceListHead),
|
: ObjectBox(fun, traceListHead),
|
||||||
SharedContext(cx, directives, extraWarnings),
|
SharedContext(cx, directives, extraWarnings),
|
||||||
bindings(),
|
bindings(),
|
||||||
@ -771,6 +772,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
|
|||||||
startColumn(0),
|
startColumn(0),
|
||||||
length(0),
|
length(0),
|
||||||
generatorKindBits_(GeneratorKindAsBits(generatorKind)),
|
generatorKindBits_(GeneratorKindAsBits(generatorKind)),
|
||||||
|
asyncKindBits_(AsyncKindAsBits(asyncKind)),
|
||||||
inGenexpLambda(false),
|
inGenexpLambda(false),
|
||||||
hasDestructuringArgs(false),
|
hasDestructuringArgs(false),
|
||||||
useAsm(false),
|
useAsm(false),
|
||||||
@ -794,6 +796,7 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
|
|||||||
ParseContext<ParseHandler>* outerpc,
|
ParseContext<ParseHandler>* outerpc,
|
||||||
Directives inheritedDirectives,
|
Directives inheritedDirectives,
|
||||||
GeneratorKind generatorKind,
|
GeneratorKind generatorKind,
|
||||||
|
FunctionAsyncKind asyncKind,
|
||||||
JSObject* enclosingStaticScope)
|
JSObject* enclosingStaticScope)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
|
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
|
||||||
@ -809,7 +812,7 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
|
|||||||
FunctionBox* funbox =
|
FunctionBox* funbox =
|
||||||
alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
|
alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
|
||||||
inheritedDirectives, options().extraWarningsOption,
|
inheritedDirectives, options().extraWarningsOption,
|
||||||
generatorKind);
|
generatorKind, asyncKind);
|
||||||
if (!funbox) {
|
if (!funbox) {
|
||||||
ReportOutOfMemory(context);
|
ReportOutOfMemory(context);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1155,7 +1158,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
|
|||||||
return null();
|
return null();
|
||||||
fn->pn_body = argsbody;
|
fn->pn_body = argsbody;
|
||||||
|
|
||||||
FunctionBox* funbox = newFunctionBox(fn, fun, inheritedDirectives, generatorKind,
|
FunctionBox* funbox = newFunctionBox(fn, fun, inheritedDirectives, generatorKind, SyncFunction,
|
||||||
enclosingStaticScope);
|
enclosingStaticScope);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return null();
|
return null();
|
||||||
@ -2507,7 +2510,7 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
|||||||
RootedFunction fun(context, handler.nextLazyInnerFunction());
|
RootedFunction fun(context, handler.nextLazyInnerFunction());
|
||||||
MOZ_ASSERT(!fun->isLegacyGenerator());
|
MOZ_ASSERT(!fun->isLegacyGenerator());
|
||||||
FunctionBox* funbox = newFunctionBox(pn, fun, pc, Directives(/* strict = */ false),
|
FunctionBox* funbox = newFunctionBox(pn, fun, pc, Directives(/* strict = */ false),
|
||||||
fun->generatorKind());
|
fun->generatorKind(), fun->asyncKind());
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2836,6 +2839,7 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
|
|||||||
if (pc->sc->strict())
|
if (pc->sc->strict())
|
||||||
lazy->setStrict();
|
lazy->setStrict();
|
||||||
lazy->setGeneratorKind(funbox->generatorKind());
|
lazy->setGeneratorKind(funbox->generatorKind());
|
||||||
|
lazy->setAsyncKind(funbox->asyncKind());
|
||||||
if (funbox->isLikelyConstructorWrapper())
|
if (funbox->isLikelyConstructorWrapper())
|
||||||
lazy->setLikelyConstructorWrapper();
|
lazy->setLikelyConstructorWrapper();
|
||||||
if (funbox->isDerivedClassConstructor())
|
if (funbox->isDerivedClassConstructor())
|
||||||
@ -2859,7 +2863,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
|
|||||||
ParseContext<FullParseHandler>* outerpc = pc;
|
ParseContext<FullParseHandler>* outerpc = pc;
|
||||||
|
|
||||||
// Create box for fun->object early to protect against last-ditch GC.
|
// Create box for fun->object early to protect against last-ditch GC.
|
||||||
FunctionBox* funbox = newFunctionBox(pn, fun, pc, inheritedDirectives, generatorKind);
|
FunctionBox* funbox = newFunctionBox(pn, fun, pc, inheritedDirectives, generatorKind, SyncFunction);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2959,7 +2963,7 @@ Parser<SyntaxParseHandler>::functionArgsAndBody(InHandling inHandling, Node pn,
|
|||||||
ParseContext<SyntaxParseHandler>* outerpc = pc;
|
ParseContext<SyntaxParseHandler>* outerpc = pc;
|
||||||
|
|
||||||
// Create box for fun->object early to protect against last-ditch GC.
|
// Create box for fun->object early to protect against last-ditch GC.
|
||||||
FunctionBox* funbox = newFunctionBox(pn, fun, pc, inheritedDirectives, generatorKind);
|
FunctionBox* funbox = newFunctionBox(pn, fun, pc, inheritedDirectives, generatorKind, SyncFunction);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -3018,7 +3022,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
|
|||||||
|
|
||||||
RootedObject enclosing(context, fun->lazyScript()->enclosingScope());
|
RootedObject enclosing(context, fun->lazyScript()->enclosingScope());
|
||||||
Directives directives(/* strict = */ strict);
|
Directives directives(/* strict = */ strict);
|
||||||
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, enclosing);
|
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, SyncFunction, enclosing);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return null();
|
return null();
|
||||||
funbox->length = fun->nargs() - fun->hasRest();
|
funbox->length = fun->nargs() - fun->hasRest();
|
||||||
@ -8632,7 +8636,7 @@ Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKi
|
|||||||
|
|
||||||
// Create box for fun->object early to root it.
|
// Create box for fun->object early to root it.
|
||||||
Directives directives(/* strict = */ outerpc->sc->strict());
|
Directives directives(/* strict = */ outerpc->sc->strict());
|
||||||
FunctionBox* genFunbox = newFunctionBox(genfn, fun, outerpc, directives, comprehensionKind);
|
FunctionBox* genFunbox = newFunctionBox(genfn, fun, outerpc, directives, comprehensionKind, SyncFunction);
|
||||||
if (!genFunbox)
|
if (!genFunbox)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -126,6 +126,10 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
|
|||||||
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
|
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
|
||||||
bool isStarGenerator() const { return generatorKind() == StarGenerator; }
|
bool isStarGenerator() const { return generatorKind() == StarGenerator; }
|
||||||
|
|
||||||
|
bool isAsync() const {
|
||||||
|
return sc->isFunctionBox() && sc->asFunctionBox()->isAsync();
|
||||||
|
}
|
||||||
|
|
||||||
bool isArrowFunction() const {
|
bool isArrowFunction() const {
|
||||||
return sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow();
|
return sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow();
|
||||||
}
|
}
|
||||||
@ -579,22 +583,26 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||||||
ObjectBox* newObjectBox(JSObject* obj);
|
ObjectBox* newObjectBox(JSObject* obj);
|
||||||
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
|
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
|
||||||
Directives directives, GeneratorKind generatorKind,
|
Directives directives, GeneratorKind generatorKind,
|
||||||
|
FunctionAsyncKind asyncKind,
|
||||||
JSObject* enclosingStaticScope);
|
JSObject* enclosingStaticScope);
|
||||||
|
|
||||||
// Use when the funbox is the outermost.
|
// Use when the funbox is the outermost.
|
||||||
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, Directives directives,
|
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, Directives directives,
|
||||||
GeneratorKind generatorKind, HandleObject enclosingStaticScope)
|
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||||
|
HandleObject enclosingStaticScope)
|
||||||
{
|
{
|
||||||
return newFunctionBox(fn, fun, nullptr, directives, generatorKind,
|
return newFunctionBox(fn, fun, nullptr, directives, generatorKind,
|
||||||
|
asyncKind,
|
||||||
enclosingStaticScope);
|
enclosingStaticScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use when the funbox should be linked to the outerpc's innermost scope.
|
// Use when the funbox should be linked to the outerpc's innermost scope.
|
||||||
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
|
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
|
||||||
Directives directives, GeneratorKind generatorKind)
|
Directives directives, GeneratorKind generatorKind,
|
||||||
|
FunctionAsyncKind asyncKind)
|
||||||
{
|
{
|
||||||
RootedObject enclosing(context, outerpc->innermostStaticScope());
|
RootedObject enclosing(context, outerpc->innermostStaticScope());
|
||||||
return newFunctionBox(fn, fun, outerpc, directives, generatorKind, enclosing);
|
return newFunctionBox(fn, fun, outerpc, directives, generatorKind, asyncKind, enclosing);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleBox* newModuleBox(Node pn, HandleModuleObject module);
|
ModuleBox* newModuleBox(Node pn, HandleModuleObject module);
|
||||||
|
@ -333,6 +333,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||||||
uint16_t length;
|
uint16_t length;
|
||||||
|
|
||||||
uint8_t generatorKindBits_; /* The GeneratorKind of this function. */
|
uint8_t generatorKindBits_; /* The GeneratorKind of this function. */
|
||||||
|
uint8_t asyncKindBits_; /* The FunctionAsyncKing of this function. */
|
||||||
bool inGenexpLambda:1; /* lambda from generator expression */
|
bool inGenexpLambda:1; /* lambda from generator expression */
|
||||||
bool hasDestructuringArgs:1; /* arguments list contains destructuring expression */
|
bool hasDestructuringArgs:1; /* arguments list contains destructuring expression */
|
||||||
bool useAsm:1; /* see useAsmOrInsideUseAsm */
|
bool useAsm:1; /* see useAsmOrInsideUseAsm */
|
||||||
@ -350,7 +351,8 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
||||||
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
|
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
|
||||||
Directives directives, bool extraWarnings, GeneratorKind generatorKind);
|
Directives directives, bool extraWarnings, GeneratorKind generatorKind,
|
||||||
|
FunctionAsyncKind asyncKind);
|
||||||
|
|
||||||
ObjectBox* toObjectBox() override { return this; }
|
ObjectBox* toObjectBox() override { return this; }
|
||||||
JSFunction* function() const { return &object->as<JSFunction>(); }
|
JSFunction* function() const { return &object->as<JSFunction>(); }
|
||||||
@ -365,6 +367,8 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||||||
bool isGenerator() const { return generatorKind() != NotGenerator; }
|
bool isGenerator() const { return generatorKind() != NotGenerator; }
|
||||||
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
|
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
|
||||||
bool isStarGenerator() const { return generatorKind() == StarGenerator; }
|
bool isStarGenerator() const { return generatorKind() == StarGenerator; }
|
||||||
|
FunctionAsyncKind asyncKind() const { return AsyncKindFromBits(asyncKindBits_); }
|
||||||
|
bool isAsync() const { return asyncKind() == AsyncFunction; }
|
||||||
bool isArrow() const { return function()->isArrow(); }
|
bool isArrow() const { return function()->isArrow(); }
|
||||||
|
|
||||||
void setGeneratorKind(GeneratorKind kind) {
|
void setGeneratorKind(GeneratorKind kind) {
|
||||||
|
@ -2679,15 +2679,14 @@ static const VMFunction DefFunOperationInfo = FunctionInfo<DefFunOperationFn>(De
|
|||||||
bool
|
bool
|
||||||
BaselineCompiler::emit_JSOP_DEFFUN()
|
BaselineCompiler::emit_JSOP_DEFFUN()
|
||||||
{
|
{
|
||||||
RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
|
frame.popRegsAndSync(1);
|
||||||
|
masm.unboxObject(R0, R0.scratchReg());
|
||||||
frame.syncStack(0);
|
masm.loadPtr(frame.addressOfScopeChain(), R1.scratchReg());
|
||||||
masm.loadPtr(frame.addressOfScopeChain(), R0.scratchReg());
|
|
||||||
|
|
||||||
prepareVMCall();
|
prepareVMCall();
|
||||||
|
|
||||||
pushArg(ImmGCPtr(fun));
|
|
||||||
pushArg(R0.scratchReg());
|
pushArg(R0.scratchReg());
|
||||||
|
pushArg(R1.scratchReg());
|
||||||
pushArg(ImmGCPtr(script));
|
pushArg(ImmGCPtr(script));
|
||||||
|
|
||||||
return callVM(DefFunOperationInfo);
|
return callVM(DefFunOperationInfo);
|
||||||
|
@ -4368,7 +4368,8 @@ CodeGenerator::visitDefFun(LDefFun* lir)
|
|||||||
{
|
{
|
||||||
Register scopeChain = ToRegister(lir->scopeChain());
|
Register scopeChain = ToRegister(lir->scopeChain());
|
||||||
|
|
||||||
pushArg(ImmGCPtr(lir->mir()->fun()));
|
Register fun = ToRegister(lir->fun());
|
||||||
|
pushArg(fun);
|
||||||
pushArg(scopeChain);
|
pushArg(scopeChain);
|
||||||
pushArg(ImmGCPtr(current->mir()->info().script()));
|
pushArg(ImmGCPtr(current->mir()->info().script()));
|
||||||
|
|
||||||
|
@ -12927,13 +12927,9 @@ IonBuilder::jsop_deflexical(uint32_t index)
|
|||||||
bool
|
bool
|
||||||
IonBuilder::jsop_deffun(uint32_t index)
|
IonBuilder::jsop_deffun(uint32_t index)
|
||||||
{
|
{
|
||||||
JSFunction* fun = script()->getFunction(index);
|
|
||||||
if (fun->isNative() && IsAsmJSModuleNative(fun->native()))
|
|
||||||
return abort("asm.js module function");
|
|
||||||
|
|
||||||
MOZ_ASSERT(analysis().usesScopeChain());
|
MOZ_ASSERT(analysis().usesScopeChain());
|
||||||
|
|
||||||
MDefFun* deffun = MDefFun::New(alloc(), fun, current->scopeChain());
|
MDefFun* deffun = MDefFun::New(alloc(), current->pop(), current->scopeChain());
|
||||||
current->add(deffun);
|
current->add(deffun);
|
||||||
|
|
||||||
return resumeAfter(deffun);
|
return resumeAfter(deffun);
|
||||||
|
@ -164,7 +164,11 @@ LIRGenerator::visitDefLexical(MDefLexical* ins)
|
|||||||
void
|
void
|
||||||
LIRGenerator::visitDefFun(MDefFun* ins)
|
LIRGenerator::visitDefFun(MDefFun* ins)
|
||||||
{
|
{
|
||||||
LDefFun* lir = new(alloc()) LDefFun(useRegisterAtStart(ins->scopeChain()));
|
MDefinition* fun = ins->fun();
|
||||||
|
MOZ_ASSERT(fun->type() == MIRType_Object);
|
||||||
|
|
||||||
|
LDefFun* lir = new(alloc()) LDefFun(useRegisterAtStart(fun),
|
||||||
|
useRegisterAtStart(ins->scopeChain()));
|
||||||
add(lir, ins);
|
add(lir, ins);
|
||||||
assignSafepoint(lir, ins);
|
assignSafepoint(lir, ins);
|
||||||
}
|
}
|
||||||
|
@ -7423,30 +7423,28 @@ class MDefLexical
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MDefFun
|
class MDefFun
|
||||||
: public MUnaryInstruction,
|
: public MBinaryInstruction,
|
||||||
public NoTypePolicy::Data
|
public SingleObjectPolicy::Data
|
||||||
{
|
{
|
||||||
CompilerFunction fun_;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MDefFun(JSFunction* fun, MDefinition* scopeChain)
|
MDefFun(MDefinition* fun, MDefinition* scopeChain)
|
||||||
: MUnaryInstruction(scopeChain),
|
: MBinaryInstruction(fun, scopeChain)
|
||||||
fun_(fun)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
INSTRUCTION_HEADER(DefFun)
|
INSTRUCTION_HEADER(DefFun)
|
||||||
|
|
||||||
static MDefFun* New(TempAllocator& alloc, JSFunction* fun, MDefinition* scopeChain) {
|
static MDefFun* New(TempAllocator& alloc, MDefinition* fun, MDefinition* scopeChain) {
|
||||||
return new(alloc) MDefFun(fun, scopeChain);
|
return new(alloc) MDefFun(fun, scopeChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSFunction* fun() const {
|
MDefinition* fun() const {
|
||||||
return fun_;
|
|
||||||
}
|
|
||||||
MDefinition* scopeChain() const {
|
|
||||||
return getOperand(0);
|
return getOperand(0);
|
||||||
}
|
}
|
||||||
|
MDefinition* scopeChain() const {
|
||||||
|
return getOperand(1);
|
||||||
|
}
|
||||||
|
|
||||||
bool possiblyCalls() const override {
|
bool possiblyCalls() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1238,19 +1238,23 @@ class LDefLexical : public LCallInstructionHelper<0, 0, 0>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LDefFun : public LCallInstructionHelper<0, 1, 0>
|
class LDefFun : public LCallInstructionHelper<0, 2, 0>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LIR_HEADER(DefFun)
|
LIR_HEADER(DefFun)
|
||||||
|
|
||||||
explicit LDefFun(const LAllocation& scopeChain)
|
LDefFun(const LAllocation& fun, const LAllocation& scopeChain)
|
||||||
{
|
{
|
||||||
setOperand(0, scopeChain);
|
setOperand(0, fun);
|
||||||
|
setOperand(1, scopeChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LAllocation* scopeChain() {
|
const LAllocation* fun() {
|
||||||
return getOperand(0);
|
return getOperand(0);
|
||||||
}
|
}
|
||||||
|
const LAllocation* scopeChain() {
|
||||||
|
return getOperand(1);
|
||||||
|
}
|
||||||
MDefFun* mir() const {
|
MDefFun* mir() const {
|
||||||
return mir_->toDefFun();
|
return mir_->toDefFun();
|
||||||
}
|
}
|
||||||
|
@ -291,6 +291,13 @@ class JSFunction : public js::NativeObject
|
|||||||
flags_ |= RESOLVED_NAME;
|
flags_ |= RESOLVED_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAsyncKind(js::FunctionAsyncKind asyncKind) {
|
||||||
|
if (isInterpretedLazy())
|
||||||
|
lazyScript()->setAsyncKind(asyncKind);
|
||||||
|
else
|
||||||
|
nonLazyScript()->setAsyncKind(asyncKind);
|
||||||
|
}
|
||||||
|
|
||||||
JSAtom* atom() const { return hasGuessedAtom() ? nullptr : atom_.get(); }
|
JSAtom* atom() const { return hasGuessedAtom() ? nullptr : atom_.get(); }
|
||||||
|
|
||||||
js::PropertyName* name() const {
|
js::PropertyName* name() const {
|
||||||
@ -471,6 +478,18 @@ class JSFunction : public js::NativeObject
|
|||||||
|
|
||||||
bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
|
bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
|
||||||
|
|
||||||
|
js::FunctionAsyncKind asyncKind() const {
|
||||||
|
return isInterpretedLazy() ? lazyScript()->asyncKind() : nonLazyScript()->asyncKind();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAsync() const {
|
||||||
|
if (isInterpretedLazy())
|
||||||
|
return lazyScript()->asyncKind() == js::AsyncFunction;
|
||||||
|
if (hasScript())
|
||||||
|
return nonLazyScript()->asyncKind() == js::AsyncFunction;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void setScript(JSScript* script_) {
|
void setScript(JSScript* script_) {
|
||||||
mutableScript() = script_;
|
mutableScript() = script_;
|
||||||
}
|
}
|
||||||
|
@ -867,6 +867,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mode == XDR_DECODE) {
|
if (mode == XDR_DECODE) {
|
||||||
|
/* XXX: AsyncFunction and isAsync not implemented. */
|
||||||
if (!JSScript::partiallyInit(cx, script, nconsts, nobjects, nregexps, ntrynotes,
|
if (!JSScript::partiallyInit(cx, script, nconsts, nobjects, nregexps, ntrynotes,
|
||||||
nblockscopes, nyieldoffsets, nTypeSets))
|
nblockscopes, nyieldoffsets, nTypeSets))
|
||||||
{
|
{
|
||||||
@ -2751,6 +2752,7 @@ JSScript::Create(ExclusiveContext* cx, HandleObject enclosingScope, bool savedCa
|
|||||||
script->setSourceObject(sourceObject);
|
script->setSourceObject(sourceObject);
|
||||||
script->sourceStart_ = bufStart;
|
script->sourceStart_ = bufStart;
|
||||||
script->sourceEnd_ = bufEnd;
|
script->sourceEnd_ = bufEnd;
|
||||||
|
script->isAsync_ = false;
|
||||||
|
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
@ -2915,6 +2917,7 @@ JSScript::linkToFunctionFromEmitter(js::ExclusiveContext* cx, JS::Handle<JSScrip
|
|||||||
|
|
||||||
script->isGeneratorExp_ = funbox->inGenexpLambda;
|
script->isGeneratorExp_ = funbox->inGenexpLambda;
|
||||||
script->setGeneratorKind(funbox->generatorKind());
|
script->setGeneratorKind(funbox->generatorKind());
|
||||||
|
script->setAsyncKind(funbox->asyncKind());
|
||||||
|
|
||||||
// Link the function and the script to each other, so that StaticScopeIter
|
// Link the function and the script to each other, so that StaticScopeIter
|
||||||
// may walk the scope chain of currently compiling scripts.
|
// may walk the scope chain of currently compiling scripts.
|
||||||
@ -2940,6 +2943,7 @@ JSScript::linkToModuleFromEmitter(js::ExclusiveContext* cx, JS::Handle<JSScript*
|
|||||||
script->funLength_ = 0;
|
script->funLength_ = 0;
|
||||||
|
|
||||||
script->isGeneratorExp_ = false;
|
script->isGeneratorExp_ = false;
|
||||||
|
script->isAsync_ = false;
|
||||||
script->setGeneratorKind(NotGenerator);
|
script->setGeneratorKind(NotGenerator);
|
||||||
|
|
||||||
// Link the module and the script to each other, so that StaticScopeIter
|
// Link the module and the script to each other, so that StaticScopeIter
|
||||||
@ -3575,6 +3579,7 @@ js::detail::CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScri
|
|||||||
dst->hasInnerFunctions_ = src->hasInnerFunctions();
|
dst->hasInnerFunctions_ = src->hasInnerFunctions();
|
||||||
dst->isGeneratorExp_ = src->isGeneratorExp();
|
dst->isGeneratorExp_ = src->isGeneratorExp();
|
||||||
dst->setGeneratorKind(src->generatorKind());
|
dst->setGeneratorKind(src->generatorKind());
|
||||||
|
dst->isAsync_ = src->asyncKind() == AsyncFunction;
|
||||||
|
|
||||||
if (nconsts != 0) {
|
if (nconsts != 0) {
|
||||||
HeapValue* vector = Rebase<HeapValue>(dst, src, src->consts()->vector);
|
HeapValue* vector = Rebase<HeapValue>(dst, src, src->consts()->vector);
|
||||||
@ -4275,6 +4280,7 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
|||||||
// Reset runtime flags to obtain a fresh LazyScript.
|
// Reset runtime flags to obtain a fresh LazyScript.
|
||||||
p.hasBeenCloned = false;
|
p.hasBeenCloned = false;
|
||||||
p.treatAsRunOnce = false;
|
p.treatAsRunOnce = false;
|
||||||
|
p.isAsync = false;
|
||||||
|
|
||||||
size_t bytes = (p.numFreeVariables * sizeof(FreeVariable))
|
size_t bytes = (p.numFreeVariables * sizeof(FreeVariable))
|
||||||
+ (p.numInnerFunctions * sizeof(HeapPtrFunction));
|
+ (p.numInnerFunctions * sizeof(HeapPtrFunction));
|
||||||
@ -4306,6 +4312,7 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
|||||||
|
|
||||||
p.version = version;
|
p.version = version;
|
||||||
p.numFreeVariables = numFreeVariables;
|
p.numFreeVariables = numFreeVariables;
|
||||||
|
p.isAsync = false;
|
||||||
p.numInnerFunctions = numInnerFunctions;
|
p.numInnerFunctions = numInnerFunctions;
|
||||||
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
||||||
p.strict = false;
|
p.strict = false;
|
||||||
|
@ -894,6 +894,7 @@ class ScriptSourceObject : public NativeObject
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
|
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
|
||||||
|
enum FunctionAsyncKind { SyncFunction, AsyncFunction };
|
||||||
|
|
||||||
static inline unsigned
|
static inline unsigned
|
||||||
GeneratorKindAsBits(GeneratorKind generatorKind) {
|
GeneratorKindAsBits(GeneratorKind generatorKind) {
|
||||||
@ -906,6 +907,17 @@ GeneratorKindFromBits(unsigned val) {
|
|||||||
return static_cast<GeneratorKind>(val);
|
return static_cast<GeneratorKind>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
AsyncKindAsBits(FunctionAsyncKind asyncKind) {
|
||||||
|
return static_cast<unsigned>(asyncKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline FunctionAsyncKind
|
||||||
|
AsyncKindFromBits(unsigned val) {
|
||||||
|
MOZ_ASSERT(val <= AsyncFunction);
|
||||||
|
return static_cast<FunctionAsyncKind>(val);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NB: after a successful XDR_DECODE, XDRScript callers must do any required
|
* NB: after a successful XDR_DECODE, XDRScript callers must do any required
|
||||||
* subsequent set-up of owning function or script object and then call
|
* subsequent set-up of owning function or script object and then call
|
||||||
@ -1190,6 +1202,8 @@ class JSScript : public js::gc::TenuredCell
|
|||||||
|
|
||||||
bool isDerivedClassConstructor_:1;
|
bool isDerivedClassConstructor_:1;
|
||||||
|
|
||||||
|
bool isAsync_:1;
|
||||||
|
|
||||||
// Add padding so JSScript is gc::Cell aligned. Make padding protected
|
// Add padding so JSScript is gc::Cell aligned. Make padding protected
|
||||||
// instead of private to suppress -Wunused-private-field compiler warnings.
|
// instead of private to suppress -Wunused-private-field compiler warnings.
|
||||||
protected:
|
protected:
|
||||||
@ -1456,6 +1470,14 @@ class JSScript : public js::gc::TenuredCell
|
|||||||
generatorKindBits_ = GeneratorKindAsBits(kind);
|
generatorKindBits_ = GeneratorKindAsBits(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
js::FunctionAsyncKind asyncKind() const {
|
||||||
|
return isAsync_ ? js::AsyncFunction : js::SyncFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAsyncKind(js::FunctionAsyncKind kind) {
|
||||||
|
isAsync_ = kind == js::AsyncFunction;
|
||||||
|
}
|
||||||
|
|
||||||
void setNeedsHomeObject() {
|
void setNeedsHomeObject() {
|
||||||
needsHomeObject_ = true;
|
needsHomeObject_ = true;
|
||||||
}
|
}
|
||||||
@ -2136,7 +2158,8 @@ class LazyScript : public gc::TenuredCell
|
|||||||
// Assorted bits that should really be in ScriptSourceObject.
|
// Assorted bits that should really be in ScriptSourceObject.
|
||||||
uint32_t version : 8;
|
uint32_t version : 8;
|
||||||
|
|
||||||
uint32_t numFreeVariables : 24;
|
uint32_t numFreeVariables : 23;
|
||||||
|
uint32_t isAsync: 1;
|
||||||
uint32_t numInnerFunctions : 20;
|
uint32_t numInnerFunctions : 20;
|
||||||
|
|
||||||
uint32_t generatorKindBits : 2;
|
uint32_t generatorKindBits : 2;
|
||||||
@ -2274,6 +2297,14 @@ class LazyScript : public gc::TenuredCell
|
|||||||
p_.generatorKindBits = GeneratorKindAsBits(kind);
|
p_.generatorKindBits = GeneratorKindAsBits(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionAsyncKind asyncKind() const {
|
||||||
|
return p_.isAsync ? AsyncFunction : SyncFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAsyncKind(FunctionAsyncKind kind) {
|
||||||
|
p_.isAsync = kind == AsyncFunction;
|
||||||
|
}
|
||||||
|
|
||||||
bool strict() const {
|
bool strict() const {
|
||||||
return p_.strict;
|
return p_.strict;
|
||||||
}
|
}
|
||||||
|
@ -3277,9 +3277,10 @@ CASE(JSOP_DEFFUN)
|
|||||||
* a compound statement (not at the top statement level of global code, or
|
* a compound statement (not at the top statement level of global code, or
|
||||||
* at the top level of a function body).
|
* at the top level of a function body).
|
||||||
*/
|
*/
|
||||||
ReservedRooted<JSFunction*> fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc)));
|
ReservedRooted<JSFunction*> fun(&rootFunction0, ®S.sp[-1].toObject().as<JSFunction>());
|
||||||
if (!DefFunOperation(cx, script, REGS.fp()->scopeChain(), fun))
|
if (!DefFunOperation(cx, script, REGS.fp()->scopeChain(), fun))
|
||||||
goto error;
|
goto error;
|
||||||
|
REGS.sp--;
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_DEFFUN)
|
END_CASE(JSOP_DEFFUN)
|
||||||
|
|
||||||
@ -4095,27 +4096,8 @@ js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleVa
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject scopeChain,
|
js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject scopeChain,
|
||||||
HandleFunction funArg)
|
HandleFunction fun)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* If static link is not current scope, clone fun's object to link to the
|
|
||||||
* current scope via parent. We do this to enable sharing of compiled
|
|
||||||
* functions among multiple equivalent scopes, amortizing the cost of
|
|
||||||
* compilation over a number of executions. Examples include XUL scripts
|
|
||||||
* and event handlers shared among Firefox or other Mozilla app chrome
|
|
||||||
* windows, and user-defined JS functions precompiled and then shared among
|
|
||||||
* requests in server-side JS.
|
|
||||||
*/
|
|
||||||
RootedFunction fun(cx, funArg);
|
|
||||||
if (fun->isNative() || fun->environment() != scopeChain) {
|
|
||||||
fun = CloneFunctionObjectIfNotSingleton(cx, fun, scopeChain, nullptr, TenuredObject);
|
|
||||||
if (!fun)
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
MOZ_ASSERT(script->treatAsRunOnce());
|
|
||||||
MOZ_ASSERT(!script->functionNonDelazifying());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We define the function as a property of the variable object and not the
|
* We define the function as a property of the variable object and not the
|
||||||
* current scope chain even for the case of function expression statements
|
* current scope chain even for the case of function expression statements
|
||||||
|
@ -1286,10 +1286,10 @@
|
|||||||
* scripts where use of dynamic scoping inhibits optimization.
|
* scripts where use of dynamic scoping inhibits optimization.
|
||||||
* Category: Variables and Scopes
|
* Category: Variables and Scopes
|
||||||
* Type: Variables
|
* Type: Variables
|
||||||
* Operands: uint32_t funcIndex
|
* Operands:
|
||||||
* Stack: =>
|
* Stack: fun =>
|
||||||
*/ \
|
*/ \
|
||||||
macro(JSOP_DEFFUN, 127,"deffun", NULL, 5, 0, 0, JOF_OBJECT) \
|
macro(JSOP_DEFFUN, 127,"deffun", NULL, 1, 1, 0, JOF_BYTE) \
|
||||||
/* Defines the new constant binding on global lexical scope.
|
/* Defines the new constant binding on global lexical scope.
|
||||||
*
|
*
|
||||||
* Throws if a binding with the same name already exists on the scope, or
|
* Throws if a binding with the same name already exists on the scope, or
|
||||||
|
Loading…
Reference in New Issue
Block a user