Skip to content

Commit

Permalink
#521: async/await M1185106 parts 0, 1
Browse files Browse the repository at this point in the history
  • Loading branch information
classilla committed Sep 15, 2018
1 parent 7e7cdb5 commit d0348b2
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 67 deletions.
2 changes: 1 addition & 1 deletion js/src/asmjs/AsmJSValidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6429,7 +6429,7 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line, unsigned* c
AsmJSParseContext* outerpc = m.parser().pc;

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)
return false;

Expand Down
1 change: 1 addition & 0 deletions js/src/frontend/BytecodeCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ BytecodeCompiler::saveCallerFun(HandleScript evalCaller)
Directives directives(/* strict = */ options.strictOption);
ObjectBox* funbox = parser->newFunctionBox(/* fn = */ nullptr, fun,
directives, fun->generatorKind(),
fun->asyncKind(),
enclosingStaticScope);
if (!funbox)
return false;
Expand Down
11 changes: 10 additions & 1 deletion js/src/frontend/BytecodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6401,6 +6401,13 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
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);
}

Expand Down Expand Up @@ -6441,7 +6448,9 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
MOZ_ASSERT(pn->pn_scopecoord.isFree());
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
switchToPrologue();
if (!emitIndex32(JSOP_DEFFUN, index))
if (!emitIndex32(JSOP_LAMBDA, index))
return false;
if (!emit1(JSOP_DEFFUN))
return false;
if (!updateSourceCoordNotes(pn->pn_pos.begin))
return false;
Expand Down
3 changes: 2 additions & 1 deletion js/src/frontend/ParseNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,8 @@ Parser<FullParseHandler>::cloneParseTree(ParseNode* opn)
RootedFunction fun(context, opn->pn_funbox->function());
NULLCHECK(pn->pn_funbox = newFunctionBox(pn, fun, pc,
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));
pn->pn_scopecoord = opn->pn_scopecoord;
pn->pn_dflags = opn->pn_dflags;
Expand Down
20 changes: 12 additions & 8 deletions js/src/frontend/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,8 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
template <typename ParseHandler>
FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
Directives directives, bool extraWarnings, GeneratorKind generatorKind)
Directives directives, bool extraWarnings, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind)
: ObjectBox(fun, traceListHead),
SharedContext(cx, directives, extraWarnings),
bindings(),
Expand All @@ -771,6 +772,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
startColumn(0),
length(0),
generatorKindBits_(GeneratorKindAsBits(generatorKind)),
asyncKindBits_(AsyncKindAsBits(asyncKind)),
inGenexpLambda(false),
hasDestructuringArgs(false),
useAsm(false),
Expand All @@ -794,6 +796,7 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
ParseContext<ParseHandler>* outerpc,
Directives inheritedDirectives,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind,
JSObject* enclosingStaticScope)
{
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
Expand All @@ -809,7 +812,7 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
FunctionBox* funbox =
alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
inheritedDirectives, options().extraWarningsOption,
generatorKind);
generatorKind, asyncKind);
if (!funbox) {
ReportOutOfMemory(context);
return nullptr;
Expand Down Expand Up @@ -1155,7 +1158,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
return null();
fn->pn_body = argsbody;

FunctionBox* funbox = newFunctionBox(fn, fun, inheritedDirectives, generatorKind,
FunctionBox* funbox = newFunctionBox(fn, fun, inheritedDirectives, generatorKind, SyncFunction,
enclosingStaticScope);
if (!funbox)
return null();
Expand Down Expand Up @@ -2507,7 +2510,7 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
RootedFunction fun(context, handler.nextLazyInnerFunction());
MOZ_ASSERT(!fun->isLegacyGenerator());
FunctionBox* funbox = newFunctionBox(pn, fun, pc, Directives(/* strict = */ false),
fun->generatorKind());
fun->generatorKind(), fun->asyncKind());
if (!funbox)
return false;

Expand Down Expand Up @@ -2836,6 +2839,7 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
if (pc->sc->strict())
lazy->setStrict();
lazy->setGeneratorKind(funbox->generatorKind());
lazy->setAsyncKind(funbox->asyncKind());
if (funbox->isLikelyConstructorWrapper())
lazy->setLikelyConstructorWrapper();
if (funbox->isDerivedClassConstructor())
Expand All @@ -2859,7 +2863,7 @@ Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode*
ParseContext<FullParseHandler>* outerpc = pc;

// 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)
return false;

Expand Down Expand Up @@ -2959,7 +2963,7 @@ Parser<SyntaxParseHandler>::functionArgsAndBody(InHandling inHandling, Node pn,
ParseContext<SyntaxParseHandler>* outerpc = pc;

// 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)
return false;

Expand Down Expand Up @@ -3018,7 +3022,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict

RootedObject enclosing(context, fun->lazyScript()->enclosingScope());
Directives directives(/* strict = */ strict);
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, enclosing);
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, SyncFunction, enclosing);
if (!funbox)
return null();
funbox->length = fun->nargs() - fun->hasRest();
Expand Down Expand Up @@ -8632,7 +8636,7 @@ Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKi

// Create box for fun->object early to root it.
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)
return null();

Expand Down
14 changes: 11 additions & 3 deletions js/src/frontend/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
bool isStarGenerator() const { return generatorKind() == StarGenerator; }

bool isAsync() const {
return sc->isFunctionBox() && sc->asFunctionBox()->isAsync();
}

bool isArrowFunction() const {
return sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow();
}
Expand Down Expand Up @@ -579,22 +583,26 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
ObjectBox* newObjectBox(JSObject* obj);
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
Directives directives, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind,
JSObject* enclosingStaticScope);

// Use when the funbox is the outermost.
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,
asyncKind,
enclosingStaticScope);
}

// Use when the funbox should be linked to the outerpc's innermost scope.
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
Directives directives, GeneratorKind generatorKind)
Directives directives, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind)
{
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);
Expand Down
6 changes: 5 additions & 1 deletion js/src/frontend/SharedContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ class FunctionBox : public ObjectBox, public SharedContext
uint16_t length;

uint8_t generatorKindBits_; /* The GeneratorKind of this function. */
uint8_t asyncKindBits_; /* The FunctionAsyncKing of this function. */
bool inGenexpLambda:1; /* lambda from generator expression */
bool hasDestructuringArgs:1; /* arguments list contains destructuring expression */
bool useAsm:1; /* see useAsmOrInsideUseAsm */
Expand All @@ -350,7 +351,8 @@ class FunctionBox : public ObjectBox, public SharedContext
template <typename ParseHandler>
FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
Directives directives, bool extraWarnings, GeneratorKind generatorKind);
Directives directives, bool extraWarnings, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind);

ObjectBox* toObjectBox() override { return this; }
JSFunction* function() const { return &object->as<JSFunction>(); }
Expand All @@ -365,6 +367,8 @@ class FunctionBox : public ObjectBox, public SharedContext
bool isGenerator() const { return generatorKind() != NotGenerator; }
bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
bool isStarGenerator() const { return generatorKind() == StarGenerator; }
FunctionAsyncKind asyncKind() const { return AsyncKindFromBits(asyncKindBits_); }
bool isAsync() const { return asyncKind() == AsyncFunction; }
bool isArrow() const { return function()->isArrow(); }

void setGeneratorKind(GeneratorKind kind) {
Expand Down
9 changes: 4 additions & 5 deletions js/src/jit/BaselineCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2679,15 +2679,14 @@ static const VMFunction DefFunOperationInfo = FunctionInfo<DefFunOperationFn>(De
bool
BaselineCompiler::emit_JSOP_DEFFUN()
{
RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));

frame.syncStack(0);
masm.loadPtr(frame.addressOfScopeChain(), R0.scratchReg());
frame.popRegsAndSync(1);
masm.unboxObject(R0, R0.scratchReg());
masm.loadPtr(frame.addressOfScopeChain(), R1.scratchReg());

prepareVMCall();

pushArg(ImmGCPtr(fun));
pushArg(R0.scratchReg());
pushArg(R1.scratchReg());
pushArg(ImmGCPtr(script));

return callVM(DefFunOperationInfo);
Expand Down
3 changes: 2 additions & 1 deletion js/src/jit/CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4368,7 +4368,8 @@ CodeGenerator::visitDefFun(LDefFun* lir)
{
Register scopeChain = ToRegister(lir->scopeChain());

pushArg(ImmGCPtr(lir->mir()->fun()));
Register fun = ToRegister(lir->fun());
pushArg(fun);
pushArg(scopeChain);
pushArg(ImmGCPtr(current->mir()->info().script()));

Expand Down
6 changes: 1 addition & 5 deletions js/src/jit/IonBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12927,13 +12927,9 @@ IonBuilder::jsop_deflexical(uint32_t index)
bool
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());

MDefFun* deffun = MDefFun::New(alloc(), fun, current->scopeChain());
MDefFun* deffun = MDefFun::New(alloc(), current->pop(), current->scopeChain());
current->add(deffun);

return resumeAfter(deffun);
Expand Down
6 changes: 5 additions & 1 deletion js/src/jit/Lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ LIRGenerator::visitDefLexical(MDefLexical* ins)
void
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);
assignSafepoint(lir, ins);
}
Expand Down
20 changes: 9 additions & 11 deletions js/src/jit/MIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -7423,30 +7423,28 @@ class MDefLexical
};

class MDefFun
: public MUnaryInstruction,
public NoTypePolicy::Data
: public MBinaryInstruction,
public SingleObjectPolicy::Data
{
CompilerFunction fun_;

private:
MDefFun(JSFunction* fun, MDefinition* scopeChain)
: MUnaryInstruction(scopeChain),
fun_(fun)
MDefFun(MDefinition* fun, MDefinition* scopeChain)
: MBinaryInstruction(fun, scopeChain)
{}

public:
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);
}

JSFunction* fun() const {
return fun_;
MDefinition* fun() const {
return getOperand(0);
}
MDefinition* scopeChain() const {
return getOperand(0);
return getOperand(1);
}

bool possiblyCalls() const override {
return true;
}
Expand Down
12 changes: 8 additions & 4 deletions js/src/jit/shared/LIR-shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
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);
}
const LAllocation* scopeChain() {
return getOperand(1);
}
MDefFun* mir() const {
return mir_->toDefFun();
}
Expand Down
19 changes: 19 additions & 0 deletions js/src/jsfun.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@ class JSFunction : public js::NativeObject
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(); }

js::PropertyName* name() const {
Expand Down Expand Up @@ -471,6 +478,18 @@ class JSFunction : public js::NativeObject

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_) {
mutableScript() = script_;
}
Expand Down
Loading

0 comments on commit d0348b2

Please sign in to comment.