summaryrefslogtreecommitdiff
path: root/js/src/frontend/BytecodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/BytecodeEmitter.cpp')
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp51
1 files changed, 44 insertions, 7 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index e5a47c496a..462edfd91e 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1093,6 +1093,11 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
*answer = false;
return true;
+ case PNK_BIGINT:
+ MOZ_ASSERT(pn->is<BigIntLiteral>());
+ *answer = false;
+ return true;
+
// |this| can throw in derived class constructors, including nested arrow
// functions or eval.
case PNK_THIS:
@@ -4225,6 +4230,9 @@ ParseNode::getConstantValue(ExclusiveContext* cx, AllowConstantObjects allowObje
case PNK_NUMBER:
vp.setNumber(as<NumericLiteral>().value());
return true;
+ case PNK_BIGINT:
+ vp.setBigInt(as<BigIntLiteral>().box()->value());
+ return true;
case PNK_TEMPLATE_STRING:
case PNK_STRING:
vp.setString(as<NameNode>().atom());
@@ -4835,6 +4843,15 @@ BytecodeEmitter::emitCopyDataProperties(CopyOption option)
}
bool
+BytecodeEmitter::emitBigIntOp(BigInt* bigint)
+{
+ if (!constList.append(BigIntValue(bigint))) {
+ return false;
+ }
+ return emitIndex32(JSOP_BIGINT, constList.length() - 1);
+}
+
+bool
BytecodeEmitter::emitIterator()
{
// Convert iterable to iterator.
@@ -7737,10 +7754,23 @@ bool
BytecodeEmitter::emitLeftAssociative(ListNode* node)
{
// Left-associative operator chain.
- if (!emitTree(node->head()))
- return false;
JSOp op = node->getOp();
- ParseNode* nextExpr = node->head()->pn_next;
+ ParseNode* headExpr = node->head();
+ if (op == JSOP_IN && headExpr->isKind(PNK_NAME) && headExpr->as<NameNode>().isPrivateName()) {
+ // {Goanna} The only way a "naked" private name can show up as the leftmost side of an in-chain
+ // is from an ergonomic brand check (`this.#x in ...` would be a PNK_DOT child node).
+ // Instead of going through the emitTree machinery, we pretend that this identifier
+ // reference is actually a string, which allows us to use the JSOP_IN interpreter routines.
+ // This erroneously doesn't call updateLineNumberNotes, but this is not a big issue:
+ // the begin pos is correct as we're on the start of the current tree, the end is on the
+ // same line anyway.
+ if (!emitAtomOp(headExpr->as<NameNode>().atom(), JSOP_STRING))
+ return false;
+ } else {
+ if (!emitTree(headExpr))
+ return false;
+ }
+ ParseNode* nextExpr = headExpr->pn_next;
do {
if (!emitTree(nextExpr))
return false;
@@ -9579,6 +9609,12 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
break;
+ case PNK_BIGINT:
+ if (!emitBigIntOp(pn->as<BigIntLiteral>().box()->value())) {
+ return false;
+ }
+ break;
+
case PNK_REGEXP:
if (!emitRegExp(objectList.add(pn->as<RegExpLiteral>().objbox())))
return false;
@@ -10317,7 +10353,7 @@ CGConstList::finish(ConstArray* array)
MOZ_ASSERT(length() == array->length);
for (unsigned i = 0; i < length(); i++)
- array->vector[i] = list[i];
+ array->vector[i] = vector[i];
}
/*
@@ -10331,6 +10367,7 @@ CGConstList::finish(ConstArray* array)
unsigned
CGObjectList::add(ObjectBox* objbox)
{
+ MOZ_ASSERT(objbox->isObjectBox());
MOZ_ASSERT(!objbox->emitLink);
objbox->emitLink = lastbox;
lastbox = objbox;
@@ -10342,7 +10379,7 @@ CGObjectList::indexOf(JSObject* obj)
{
MOZ_ASSERT(length > 0);
unsigned index = length - 1;
- for (ObjectBox* box = lastbox; box->object != obj; box = box->emitLink)
+ for (ObjectBox* box = lastbox; box->object() != obj; box = box->emitLink)
index--;
return index;
}
@@ -10358,8 +10395,8 @@ CGObjectList::finish(ObjectArray* array)
do {
--cursor;
MOZ_ASSERT(!*cursor);
- MOZ_ASSERT(objbox->object->isTenured());
- *cursor = objbox->object;
+ MOZ_ASSERT(objbox->object()->isTenured());
+ *cursor = objbox->object();
} while ((objbox = objbox->emitLink) != nullptr);
MOZ_ASSERT(cursor == array->vector);
}