mirror of
https://github.com/roytam1/mozilla45esr.git
synced 2026-05-26 06:25:03 +00:00
import changes from tenfourfox:
- #521: async/await M1185106 parts 0, 1 (d0348b2d1) - #521: async/await M1185106 part 2 (f80a788a3) - #521: async/await M1185106 parts 3 and 4 (80646986b) - #521: M1226762 (389ff7a57) - #518: eat our shorts, githubgist too (3660eb7e2)
This commit is contained in:
@@ -6427,7 +6427,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;
|
||||
|
||||
|
||||
@@ -152,6 +152,19 @@ function GetIterator(obj, method) {
|
||||
return iterator;
|
||||
}
|
||||
|
||||
var _builtinCtorsCache = {__proto__: null};
|
||||
|
||||
function GetBuiltinConstructor(builtinName) {
|
||||
var ctor = _builtinCtorsCache[builtinName] ||
|
||||
(_builtinCtorsCache[builtinName] = GetBuiltinConstructorImpl(builtinName));
|
||||
assert(ctor, `No builtin with name "${builtinName}" found`);
|
||||
return ctor;
|
||||
}
|
||||
|
||||
function GetBuiltinPrototype(builtinName) {
|
||||
return (_builtinCtorsCache[builtinName] || GetBuiltinConstructor(builtinName)).prototype;
|
||||
}
|
||||
|
||||
// ES6 draft 20150317 7.3.20.
|
||||
function SpeciesConstructor(obj, defaultConstructor) {
|
||||
// Step 1.
|
||||
|
||||
@@ -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;
|
||||
@@ -635,7 +636,7 @@ BytecodeCompiler::compileFunctionBody(MutableHandleFunction fun,
|
||||
ParseNode* fn;
|
||||
do {
|
||||
Directives newDirectives = directives;
|
||||
fn = parser->standaloneFunctionBody(fun, formals, generatorKind, directives,
|
||||
fn = parser->standaloneFunctionBody(fun, formals, generatorKind, SyncFunction, directives,
|
||||
&newDirectives, enclosingStaticScope);
|
||||
if (!fn && !handleParseFailure(newDirectives))
|
||||
return false;
|
||||
@@ -796,7 +797,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
|
||||
|
||||
Rooted<JSFunction*> fun(cx, lazy->functionNonDelazifying());
|
||||
MOZ_ASSERT(!lazy->isLegacyGenerator());
|
||||
ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->strict(), lazy->generatorKind());
|
||||
ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->strict(), lazy->generatorKind(), lazy->asyncKind());
|
||||
if (!pn)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+29
-19
@@ -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(),
|
||||
@@ -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),
|
||||
@@ -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());
|
||||
@@ -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;
|
||||
@@ -1140,6 +1143,7 @@ ParseNode*
|
||||
Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
|
||||
Handle<PropertyNameVector> formals,
|
||||
GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives,
|
||||
Directives* newDirectives,
|
||||
HandleObject enclosingStaticScope)
|
||||
@@ -1155,7 +1159,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, asyncKind,
|
||||
enclosingStaticScope);
|
||||
if (!funbox)
|
||||
return null();
|
||||
@@ -1606,7 +1610,8 @@ struct BindData
|
||||
template <typename ParseHandler>
|
||||
JSFunction*
|
||||
Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, HandleObject proto)
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
HandleObject proto)
|
||||
{
|
||||
MOZ_ASSERT_IF(kind == Statement, atom != nullptr);
|
||||
|
||||
@@ -2507,7 +2512,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;
|
||||
|
||||
@@ -2715,11 +2720,12 @@ Parser<ParseHandler>::templateLiteral(YieldHandling yieldHandling)
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
/* ::functionDefinition */
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::functionDef(InHandling inHandling, YieldHandling yieldHandling,
|
||||
HandlePropertyName funName, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, InvokedPrediction invoked,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, InvokedPrediction invoked,
|
||||
Node* assignmentForAnnexBOut)
|
||||
{
|
||||
MOZ_ASSERT_IF(kind == Statement, funName);
|
||||
@@ -2750,7 +2756,7 @@ Parser<ParseHandler>::functionDef(InHandling inHandling, YieldHandling yieldHand
|
||||
if (!proto)
|
||||
return null();
|
||||
}
|
||||
RootedFunction fun(context, newFunction(funName, kind, generatorKind, proto));
|
||||
RootedFunction fun(context, newFunction(funName, kind, generatorKind, asyncKind, proto));
|
||||
if (!fun)
|
||||
return null();
|
||||
|
||||
@@ -2765,7 +2771,7 @@ Parser<ParseHandler>::functionDef(InHandling inHandling, YieldHandling yieldHand
|
||||
tokenStream.tell(&start);
|
||||
|
||||
while (true) {
|
||||
if (functionArgsAndBody(inHandling, pn, fun, kind, generatorKind, directives,
|
||||
if (functionArgsAndBody(inHandling, pn, fun, kind, generatorKind, asyncKind, directives,
|
||||
&newDirectives))
|
||||
{
|
||||
break;
|
||||
@@ -2836,6 +2842,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())
|
||||
@@ -2848,18 +2855,19 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ::trySyntaxParseInnerFunction */
|
||||
template <>
|
||||
bool
|
||||
Parser<FullParseHandler>::functionArgsAndBody(InHandling inHandling, ParseNode* pn,
|
||||
HandleFunction fun, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives,
|
||||
Directives* newDirectives)
|
||||
{
|
||||
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, asyncKind);
|
||||
if (!funbox)
|
||||
return false;
|
||||
|
||||
@@ -2953,13 +2961,14 @@ bool
|
||||
Parser<SyntaxParseHandler>::functionArgsAndBody(InHandling inHandling, Node pn, HandleFunction fun,
|
||||
FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives,
|
||||
Directives* newDirectives)
|
||||
{
|
||||
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, asyncKind);
|
||||
if (!funbox)
|
||||
return false;
|
||||
|
||||
@@ -3003,7 +3012,8 @@ Parser<ParseHandler>::appendToCallSiteObj(Node callSiteObj)
|
||||
template <>
|
||||
ParseNode*
|
||||
Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict,
|
||||
GeneratorKind generatorKind)
|
||||
GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind)
|
||||
{
|
||||
MOZ_ASSERT(checkOptionsCalled);
|
||||
|
||||
@@ -3018,7 +3028,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, asyncKind, enclosing);
|
||||
if (!funbox)
|
||||
return null();
|
||||
funbox->length = fun->nargs() - fun->hasRest();
|
||||
@@ -3226,7 +3236,7 @@ Parser<ParseHandler>::functionStmt(YieldHandling yieldHandling, DefaultHandling
|
||||
|
||||
Node assignmentForAnnexB;
|
||||
Node fun = functionDef(InAllowed, yieldHandling, name, Statement, generatorKind,
|
||||
PredictUninvoked, &assignmentForAnnexB);
|
||||
SyncFunction, PredictUninvoked, &assignmentForAnnexB);
|
||||
if (!fun)
|
||||
return null();
|
||||
|
||||
@@ -3284,7 +3294,7 @@ Parser<ParseHandler>::functionExpr(InvokedPrediction invoked)
|
||||
}
|
||||
|
||||
YieldHandling yieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
|
||||
return functionDef(InAllowed, yieldHandling, name, Expression, generatorKind, invoked);
|
||||
return functionDef(InAllowed, yieldHandling, name, Expression, generatorKind, SyncFunction, invoked);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -7748,7 +7758,7 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
if (!tokenStream.peekToken(&ignored, TokenStream::Operand))
|
||||
return null();
|
||||
|
||||
Node arrowFunc = functionDef(inHandling, yieldHandling, nullptr, Arrow, NotGenerator);
|
||||
Node arrowFunc = functionDef(inHandling, yieldHandling, nullptr, Arrow, NotGenerator, SyncFunction);
|
||||
if (!arrowFunc)
|
||||
return null();
|
||||
|
||||
@@ -8626,13 +8636,13 @@ Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKi
|
||||
}
|
||||
|
||||
RootedFunction fun(context, newFunction(/* atom = */ nullptr, Expression,
|
||||
comprehensionKind, proto));
|
||||
comprehensionKind, SyncFunction, proto));
|
||||
if (!fun)
|
||||
return null();
|
||||
|
||||
// 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();
|
||||
|
||||
@@ -9872,7 +9882,7 @@ Parser<ParseHandler>::methodDefinition(YieldHandling yieldHandling, PropertyType
|
||||
{
|
||||
FunctionSyntaxKind kind = FunctionSyntaxKindFromPropertyType(propType);
|
||||
GeneratorKind generatorKind = GeneratorKindFromPropertyType(propType);
|
||||
return functionDef(InAllowed, yieldHandling, funName, kind, generatorKind);
|
||||
return functionDef(InAllowed, yieldHandling, funName, kind, generatorKind, SyncFunction);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
@@ -604,7 +612,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
* a function expression).
|
||||
*/
|
||||
JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
HandleObject proto);
|
||||
FunctionAsyncKind asyncKind, HandleObject proto);
|
||||
|
||||
bool generateBlockId(JSObject* staticScope, uint32_t* blockIdOut) {
|
||||
if (blockScopes.length() == StmtInfoPC::BlockIdLimit) {
|
||||
@@ -671,12 +679,15 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
// Generator constructors.
|
||||
Node standaloneFunctionBody(HandleFunction fun, Handle<PropertyNameVector> formals,
|
||||
GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives, Directives* newDirectives,
|
||||
HandleObject enclosingStaticScope);
|
||||
|
||||
// Parse a function, given only its arguments and body. Used for lazily
|
||||
// parsed functions.
|
||||
Node standaloneLazyFunction(HandleFunction fun, bool strict, GeneratorKind generatorKind);
|
||||
Node standaloneLazyFunction(HandleFunction fun, bool strict,
|
||||
GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind);
|
||||
|
||||
/*
|
||||
* Parse a function body. Pass StatementListBody if the body is a list of
|
||||
@@ -874,10 +885,12 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
|
||||
Node functionDef(InHandling inHandling, YieldHandling uieldHandling, HandlePropertyName name,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind,
|
||||
InvokedPrediction invoked = PredictUninvoked,
|
||||
Node* assignmentForAnnexBOut = nullptr);
|
||||
bool functionArgsAndBody(InHandling inHandling, Node pn, HandleFunction fun,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
|
||||
Node unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op, uint32_t begin);
|
||||
|
||||
@@ -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 */
|
||||
@@ -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>(); }
|
||||
@@ -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) {
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
macro(THROW, "keyword 'throw'") \
|
||||
macro(DEBUGGER, "keyword 'debugger'") \
|
||||
macro(YIELD, "keyword 'yield'") \
|
||||
macro(AWAIT, "keyword 'await'") \
|
||||
macro(LET, "keyword 'let'") \
|
||||
macro(EXPORT, "keyword 'export'") \
|
||||
macro(IMPORT, "keyword 'import'") \
|
||||
|
||||
@@ -981,6 +981,12 @@ TokenStream::putIdentInTokenbuf(const char16_t* identStart)
|
||||
bool
|
||||
TokenStream::checkForKeyword(const KeywordInfo* kw, TokenKind* ttp)
|
||||
{
|
||||
if (!awaitIsKeyword && kw->tokentype == TOK_AWAIT) {
|
||||
if (ttp)
|
||||
*ttp = TOK_NAME;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (kw->tokentype == TOK_RESERVED)
|
||||
return reportError(JSMSG_RESERVED_ID, kw->chars);
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ struct KeywordInfo;
|
||||
namespace js {
|
||||
namespace frontend {
|
||||
|
||||
class AutoAwaitIsKeyword;
|
||||
|
||||
struct TokenPos {
|
||||
uint32_t begin; // Offset of the token's first char.
|
||||
uint32_t end; // Offset of 1 past the token's last char.
|
||||
@@ -452,6 +454,9 @@ class MOZ_STACK_CLASS TokenStream
|
||||
{}
|
||||
};
|
||||
|
||||
bool awaitIsKeyword = false;
|
||||
friend class AutoAwaitIsKeyword;
|
||||
|
||||
public:
|
||||
typedef Token::Modifier Modifier;
|
||||
static MOZ_CONSTEXPR_VAR Modifier None = Token::None;
|
||||
@@ -1034,6 +1039,25 @@ class MOZ_STACK_CLASS TokenStream
|
||||
StrictModeGetter* strictModeGetter; // used to test for strict mode
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoAwaitIsKeyword
|
||||
{
|
||||
private:
|
||||
TokenStream* ts_;
|
||||
bool oldAwaitIsKeyword_;
|
||||
|
||||
public:
|
||||
AutoAwaitIsKeyword(TokenStream* ts, bool awaitIsKeyword) {
|
||||
ts_ = ts;
|
||||
oldAwaitIsKeyword_ = ts_->awaitIsKeyword;
|
||||
ts_->awaitIsKeyword = awaitIsKeyword;
|
||||
}
|
||||
|
||||
~AutoAwaitIsKeyword() {
|
||||
ts_->awaitIsKeyword = oldAwaitIsKeyword_;
|
||||
ts_ = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error
|
||||
// message have const char16_t* type, not const char*.
|
||||
#define JSREPORT_UC 0x100
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
let getCtor = getSelfHostedValue('GetBuiltinConstructor');
|
||||
|
||||
assertEq(getCtor('Array'), Array);
|
||||
|
||||
let origArray = Array;
|
||||
Array = function(){};
|
||||
assertEq(getCtor('Array') == Array, false);
|
||||
assertEq(getCtor('Array'), origArray);
|
||||
|
||||
let origMap = Map;
|
||||
Map = function(){};
|
||||
assertEq(getCtor('Map') == Map, false);
|
||||
assertEq(getCtor('Map'), origMap);
|
||||
@@ -2677,15 +2677,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);
|
||||
|
||||
@@ -3854,7 +3854,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()));
|
||||
|
||||
|
||||
@@ -12932,13 +12932,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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+10
-12
@@ -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* scopeChain() const {
|
||||
MDefinition* fun() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
MDefinition* scopeChain() const {
|
||||
return getOperand(1);
|
||||
}
|
||||
|
||||
bool possiblyCalls() const override {
|
||||
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:
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -867,6 +867,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
/* XXX: AsyncFunction and isAsync not implemented. */
|
||||
if (!JSScript::partiallyInit(cx, script, nconsts, nobjects, nregexps, ntrynotes,
|
||||
nblockscopes, nyieldoffsets, nTypeSets))
|
||||
{
|
||||
@@ -2746,6 +2747,7 @@ JSScript::Create(ExclusiveContext* cx, HandleObject enclosingScope, bool savedCa
|
||||
script->setSourceObject(sourceObject);
|
||||
script->sourceStart_ = bufStart;
|
||||
script->sourceEnd_ = bufEnd;
|
||||
script->isAsync_ = false;
|
||||
|
||||
return script;
|
||||
}
|
||||
@@ -2910,6 +2912,7 @@ JSScript::linkToFunctionFromEmitter(js::ExclusiveContext* cx, JS::Handle<JSScrip
|
||||
|
||||
script->isGeneratorExp_ = funbox->inGenexpLambda;
|
||||
script->setGeneratorKind(funbox->generatorKind());
|
||||
script->setAsyncKind(funbox->asyncKind());
|
||||
|
||||
// Link the function and the script to each other, so that StaticScopeIter
|
||||
// may walk the scope chain of currently compiling scripts.
|
||||
@@ -2935,6 +2938,7 @@ JSScript::linkToModuleFromEmitter(js::ExclusiveContext* cx, JS::Handle<JSScript*
|
||||
script->funLength_ = 0;
|
||||
|
||||
script->isGeneratorExp_ = false;
|
||||
script->isAsync_ = false;
|
||||
script->setGeneratorKind(NotGenerator);
|
||||
|
||||
// Link the module and the script to each other, so that StaticScopeIter
|
||||
@@ -3570,6 +3574,7 @@ js::detail::CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScri
|
||||
dst->hasInnerFunctions_ = src->hasInnerFunctions();
|
||||
dst->isGeneratorExp_ = src->isGeneratorExp();
|
||||
dst->setGeneratorKind(src->generatorKind());
|
||||
dst->isAsync_ = src->asyncKind() == AsyncFunction;
|
||||
|
||||
if (nconsts != 0) {
|
||||
HeapValue* vector = Rebase<HeapValue>(dst, src, src->consts()->vector);
|
||||
@@ -4270,6 +4275,7 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
// Reset runtime flags to obtain a fresh LazyScript.
|
||||
p.hasBeenCloned = false;
|
||||
p.treatAsRunOnce = false;
|
||||
p.isAsync = false;
|
||||
|
||||
size_t bytes = (p.numFreeVariables * sizeof(FreeVariable))
|
||||
+ (p.numInnerFunctions * sizeof(HeapPtrFunction));
|
||||
@@ -4301,6 +4307,7 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
|
||||
p.version = version;
|
||||
p.numFreeVariables = numFreeVariables;
|
||||
p.isAsync = false;
|
||||
p.numInnerFunctions = numInnerFunctions;
|
||||
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
|
||||
p.strict = false;
|
||||
|
||||
+32
-1
@@ -894,6 +894,7 @@ class ScriptSourceObject : public NativeObject
|
||||
};
|
||||
|
||||
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
|
||||
enum FunctionAsyncKind { SyncFunction, AsyncFunction };
|
||||
|
||||
static inline unsigned
|
||||
GeneratorKindAsBits(GeneratorKind generatorKind) {
|
||||
@@ -906,6 +907,17 @@ GeneratorKindFromBits(unsigned 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
|
||||
* 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 isAsync_:1;
|
||||
|
||||
// Add padding so JSScript is gc::Cell aligned. Make padding protected
|
||||
// instead of private to suppress -Wunused-private-field compiler warnings.
|
||||
protected:
|
||||
@@ -1456,6 +1470,14 @@ class JSScript : public js::gc::TenuredCell
|
||||
generatorKindBits_ = GeneratorKindAsBits(kind);
|
||||
}
|
||||
|
||||
js::FunctionAsyncKind asyncKind() const {
|
||||
return isAsync_ ? js::AsyncFunction : js::SyncFunction;
|
||||
}
|
||||
|
||||
void setAsyncKind(js::FunctionAsyncKind kind) {
|
||||
isAsync_ = kind == js::AsyncFunction;
|
||||
}
|
||||
|
||||
void setNeedsHomeObject() {
|
||||
needsHomeObject_ = true;
|
||||
}
|
||||
@@ -2136,7 +2158,8 @@ class LazyScript : public gc::TenuredCell
|
||||
// Assorted bits that should really be in ScriptSourceObject.
|
||||
uint32_t version : 8;
|
||||
|
||||
uint32_t numFreeVariables : 24;
|
||||
uint32_t numFreeVariables : 23;
|
||||
uint32_t isAsync: 1;
|
||||
uint32_t numInnerFunctions : 20;
|
||||
|
||||
uint32_t generatorKindBits : 2;
|
||||
@@ -2274,6 +2297,14 @@ class LazyScript : public gc::TenuredCell
|
||||
p_.generatorKindBits = GeneratorKindAsBits(kind);
|
||||
}
|
||||
|
||||
FunctionAsyncKind asyncKind() const {
|
||||
return p_.isAsync ? AsyncFunction : SyncFunction;
|
||||
}
|
||||
|
||||
void setAsyncKind(FunctionAsyncKind kind) {
|
||||
p_.isAsync = kind == AsyncFunction;
|
||||
}
|
||||
|
||||
bool strict() const {
|
||||
return p_.strict;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
macro(ArrayValues, ArrayValues, "ArrayValues") \
|
||||
macro(ArrayValuesAt, ArrayValuesAt, "ArrayValuesAt") \
|
||||
macro(Async, Async, "Async") \
|
||||
macro(await, await, "await") \
|
||||
macro(breakdown, breakdown, "breakdown") \
|
||||
macro(buffer, buffer, "buffer") \
|
||||
macro(builder, builder, "builder") \
|
||||
|
||||
@@ -3277,9 +3277,10 @@ CASE(JSOP_DEFFUN)
|
||||
* a compound statement (not at the top statement level of global code, or
|
||||
* 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))
|
||||
goto error;
|
||||
REGS.sp--;
|
||||
}
|
||||
END_CASE(JSOP_DEFFUN)
|
||||
|
||||
@@ -4095,27 +4096,8 @@ js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleVa
|
||||
|
||||
bool
|
||||
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
|
||||
* current scope chain even for the case of function expression statements
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
macro(protected, protected_, TOK_STRICT_RESERVED) \
|
||||
macro(public, public_, TOK_STRICT_RESERVED) \
|
||||
macro(static, static_, TOK_STRICT_RESERVED) \
|
||||
macro(await, await, TOK_AWAIT) \
|
||||
/* \
|
||||
* Yield is a token inside function*. Outside of a function*, it is a \
|
||||
* future reserved keyword in strict mode, but a keyword in JS1.7 even \
|
||||
|
||||
+3
-3
@@ -1286,10 +1286,10 @@
|
||||
* scripts where use of dynamic scoping inhibits optimization.
|
||||
* Category: Variables and Scopes
|
||||
* Type: Variables
|
||||
* Operands: uint32_t funcIndex
|
||||
* Stack: =>
|
||||
* Operands:
|
||||
* 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.
|
||||
*
|
||||
* Throws if a binding with the same name already exists on the scope, or
|
||||
|
||||
@@ -148,6 +148,41 @@ intrinsic_IsInstanceOfBuiltin(JSContext* cx, unsigned argc, Value* vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Self-hosting intrinsic returning the original constructor for a builtin
|
||||
* the name of which is the first and only argument.
|
||||
*
|
||||
* The return value is guaranteed to be the original constructor even if
|
||||
* content code changed the named binding on the global object.
|
||||
*
|
||||
* This intrinsic shouldn't be called directly. Instead, the
|
||||
* `GetBuiltinConstructor` and `GetBuiltinPrototype` helper functions in
|
||||
* Utilities.js should be used, as they cache results, improving performance.
|
||||
*/
|
||||
static bool
|
||||
intrinsic_GetBuiltinConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
RootedString str(cx, args[0].toString());
|
||||
JSAtom* atom;
|
||||
if (str->isAtom()) {
|
||||
atom = &str->asAtom();
|
||||
} else {
|
||||
atom = AtomizeString(cx, str);
|
||||
if (!atom)
|
||||
return false;
|
||||
}
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
JSProtoKey key = JS_IdToProtoKey(cx, id);
|
||||
MOZ_ASSERT(key != JSProto_Null);
|
||||
RootedObject ctor(cx);
|
||||
if (!GetBuiltinConstructor(cx, key, &ctor))
|
||||
return false;
|
||||
args.rval().setObject(*ctor);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_SubstringKernel(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
@@ -1467,6 +1502,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||
JS_FN("ToPropertyKey", intrinsic_ToPropertyKey, 1,0),
|
||||
JS_INLINABLE_FN("IsCallable", intrinsic_IsCallable, 1,0, IntrinsicIsCallable),
|
||||
JS_FN("IsConstructor", intrinsic_IsConstructor, 1,0),
|
||||
JS_FN("GetBuiltinConstructorImpl", intrinsic_GetBuiltinConstructor, 1,0),
|
||||
JS_FN("OwnPropertyKeys", intrinsic_OwnPropertyKeys, 1,0),
|
||||
JS_FN("ThrowRangeError", intrinsic_ThrowRangeError, 4,0),
|
||||
JS_FN("ThrowTypeError", intrinsic_ThrowTypeError, 4,0),
|
||||
|
||||
@@ -433,6 +433,7 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request,
|
||||
!hostLine.EqualsLiteral("i.imgur.com") &&
|
||||
!hostLine.EqualsLiteral("imgur.com") &&
|
||||
!hostLine.EqualsLiteral("github.com") &&
|
||||
!hostLine.EqualsLiteral("gist.github.com") &&
|
||||
1)) {
|
||||
rv = request->SetHeader(nsHttp::User_Agent, UserAgent(),
|
||||
false, nsHttpHeaderArray::eVarietyDefault);
|
||||
|
||||
Reference in New Issue
Block a user