mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1199345 - Extend JSOP_NEWARRAY/JSOP_INITELEM_ARRAY/JSOP_SPREADCALLARRAY operand to uint32. r=Waldo
This commit is contained in:
parent
5cd0d0b6d1
commit
656eb59dc5
@ -3889,13 +3889,8 @@ BytecodeEmitter::emitDestructuringOpsArrayHelper(ParseNode* pattern, VarEmitOpti
|
||||
|
||||
if (elem->isKind(PNK_SPREAD)) {
|
||||
/* Create a new array with the rest of the iterator */
|
||||
ptrdiff_t off;
|
||||
if (!emitN(JSOP_NEWARRAY, 3, &off)) // ... OBJ? ITER ARRAY
|
||||
if (!emitUint32Operand(JSOP_NEWARRAY, 0)) // ... OBJ? ITER ARRAY
|
||||
return false;
|
||||
checkTypeSet(JSOP_NEWARRAY);
|
||||
jsbytecode* pc = code(off);
|
||||
SET_UINT24(pc, 0);
|
||||
|
||||
if (!emitNumberOp(0)) // ... OBJ? ITER ARRAY INDEX
|
||||
return false;
|
||||
if (!emitSpread()) // ... OBJ? ARRAY INDEX
|
||||
@ -7214,29 +7209,35 @@ BytecodeEmitter::emitArray(ParseNode* pn, uint32_t count, JSOp op)
|
||||
*/
|
||||
MOZ_ASSERT(op == JSOP_NEWARRAY || op == JSOP_SPREADCALLARRAY);
|
||||
|
||||
int32_t nspread = 0;
|
||||
uint32_t nspread = 0;
|
||||
for (ParseNode* elt = pn; elt; elt = elt->pn_next) {
|
||||
if (elt->isKind(PNK_SPREAD))
|
||||
nspread++;
|
||||
}
|
||||
|
||||
ptrdiff_t off;
|
||||
if (!emitN(op, 3, &off)) // ARRAY
|
||||
return false;
|
||||
checkTypeSet(op);
|
||||
jsbytecode* pc = code(off);
|
||||
// Array literal's length is limited to NELEMENTS_LIMIT in parser.
|
||||
static_assert(NativeObject::MAX_DENSE_ELEMENTS_COUNT <= INT32_MAX,
|
||||
"array literals' maximum length must not exceed limits "
|
||||
"required by BaselineCompiler::emit_JSOP_NEWARRAY, "
|
||||
"BaselineCompiler::emit_JSOP_INITELEM_ARRAY, "
|
||||
"and DoSetElemFallback's handling of JSOP_INITELEM_ARRAY");
|
||||
MOZ_ASSERT(count >= nspread);
|
||||
MOZ_ASSERT(count <= NativeObject::MAX_DENSE_ELEMENTS_COUNT,
|
||||
"the parser must throw an error if the array exceeds maximum "
|
||||
"length");
|
||||
|
||||
// For arrays with spread, this is a very pessimistic allocation, the
|
||||
// minimum possible final size.
|
||||
SET_UINT24(pc, count - nspread);
|
||||
if (!emitUint32Operand(op, count - nspread)) // ARRAY
|
||||
return false;
|
||||
|
||||
ParseNode* pn2 = pn;
|
||||
jsatomid atomIndex;
|
||||
uint32_t index;
|
||||
bool afterSpread = false;
|
||||
for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
|
||||
for (index = 0; pn2; index++, pn2 = pn2->pn_next) {
|
||||
if (!afterSpread && pn2->isKind(PNK_SPREAD)) {
|
||||
afterSpread = true;
|
||||
if (!emitNumberOp(atomIndex)) // ARRAY INDEX
|
||||
if (!emitNumberOp(index)) // ARRAY INDEX
|
||||
return false;
|
||||
}
|
||||
if (!updateSourceCoordNotes(pn2->pn_pos.begin))
|
||||
@ -7262,12 +7263,11 @@ BytecodeEmitter::emitArray(ParseNode* pn, uint32_t count, JSOp op)
|
||||
if (!emit1(JSOP_INITELEM_INC))
|
||||
return false;
|
||||
} else {
|
||||
if (!emitN(JSOP_INITELEM_ARRAY, 3, &off))
|
||||
if (!emitUint32Operand(JSOP_INITELEM_ARRAY, index))
|
||||
return false;
|
||||
SET_UINT24(code(off), atomIndex);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(atomIndex == count);
|
||||
MOZ_ASSERT(index == count);
|
||||
if (afterSpread) {
|
||||
if (!emit1(JSOP_POP)) // ARRAY
|
||||
return false;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "jit/BaselineCompiler.h"
|
||||
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "jit/BaselineIC.h"
|
||||
@ -32,6 +33,8 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::AssertedCast;
|
||||
|
||||
BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script)
|
||||
: BaselineCompilerSpecific(cx, alloc, script),
|
||||
yieldOffsets_(cx),
|
||||
@ -1792,10 +1795,13 @@ BaselineCompiler::emit_JSOP_NEWARRAY()
|
||||
{
|
||||
frame.syncStack(0);
|
||||
|
||||
uint32_t length = GET_UINT24(pc);
|
||||
uint32_t length = GET_UINT32(pc);
|
||||
MOZ_ASSERT(length <= INT32_MAX,
|
||||
"the bytecode emitter must fail to compile code that would "
|
||||
"produce JSOP_NEWARRAY with a length exceeding int32_t range");
|
||||
|
||||
// Pass length in R0.
|
||||
masm.move32(Imm32(length), R0.scratchReg());
|
||||
masm.move32(Imm32(AssertedCast<int32_t>(length)), R0.scratchReg());
|
||||
|
||||
ObjectGroup* group = ObjectGroup::allocationSiteGroup(cx, script, pc, JSProto_Array);
|
||||
if (!group)
|
||||
@ -1849,7 +1855,12 @@ BaselineCompiler::emit_JSOP_INITELEM_ARRAY()
|
||||
|
||||
// Load object in R0, index in R1.
|
||||
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
|
||||
masm.moveValue(Int32Value(GET_UINT24(pc)), R1);
|
||||
uint32_t index = GET_UINT32(pc);
|
||||
MOZ_ASSERT(index <= INT32_MAX,
|
||||
"the bytecode emitter must fail to compile code that would "
|
||||
"produce JSOP_INITELEM_ARRAY with a length exceeding "
|
||||
"int32_t range");
|
||||
masm.moveValue(Int32Value(AssertedCast<int32_t>(index)), R1);
|
||||
|
||||
// Call IC.
|
||||
ICSetElem_Fallback::Compiler stubCompiler(cx);
|
||||
|
@ -3689,7 +3689,11 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
|
||||
if (!InitElemOperation(cx, obj, index, rhs))
|
||||
return false;
|
||||
} else if (op == JSOP_INITELEM_ARRAY) {
|
||||
MOZ_ASSERT(uint32_t(index.toInt32()) == GET_UINT24(pc));
|
||||
MOZ_ASSERT(uint32_t(index.toInt32()) <= INT32_MAX,
|
||||
"the bytecode emitter must fail to compile code that would "
|
||||
"produce JSOP_INITELEM_ARRAY with an index exceeding "
|
||||
"int32_t range");
|
||||
MOZ_ASSERT(uint32_t(index.toInt32()) == GET_UINT32(pc));
|
||||
if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs))
|
||||
return false;
|
||||
} else if (op == JSOP_INITELEM_INC) {
|
||||
|
@ -1794,7 +1794,7 @@ IonBuilder::inspectOpcode(JSOp op)
|
||||
return jsop_newobject();
|
||||
|
||||
case JSOP_NEWARRAY:
|
||||
return jsop_newarray(GET_UINT24(pc));
|
||||
return jsop_newarray(GET_UINT32(pc));
|
||||
|
||||
case JSOP_NEWARRAY_COPYONWRITE:
|
||||
return jsop_newarray_copyonwrite();
|
||||
@ -7052,13 +7052,14 @@ IonBuilder::jsop_initelem_array()
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t index = GET_UINT32(pc);
|
||||
if (needStub) {
|
||||
MCallInitElementArray* store = MCallInitElementArray::New(alloc(), obj, GET_UINT24(pc), value);
|
||||
MCallInitElementArray* store = MCallInitElementArray::New(alloc(), obj, index, value);
|
||||
current->add(store);
|
||||
return resumeAfter(store);
|
||||
}
|
||||
|
||||
return initializeArrayElement(obj, GET_UINT24(pc), value, unboxedType, /* addResumePoint = */ true);
|
||||
return initializeArrayElement(obj, index, value, unboxedType, /* addResumePoint = */ true);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -3609,7 +3609,8 @@ END_CASE(JSOP_NEWINIT)
|
||||
CASE(JSOP_NEWARRAY)
|
||||
CASE(JSOP_SPREADCALLARRAY)
|
||||
{
|
||||
JSObject* obj = NewArrayOperation(cx, script, REGS.pc, GET_UINT24(REGS.pc));
|
||||
uint32_t length = GET_UINT32(REGS.pc);
|
||||
JSObject* obj = NewArrayOperation(cx, script, REGS.pc, length);
|
||||
if (!obj)
|
||||
goto error;
|
||||
PUSH_OBJECT(*obj);
|
||||
@ -3705,7 +3706,7 @@ CASE(JSOP_INITELEM_ARRAY)
|
||||
|
||||
ReservedRooted<JSObject*> obj(&rootObject0, ®S.sp[-2].toObject());
|
||||
|
||||
uint32_t index = GET_UINT24(REGS.pc);
|
||||
uint32_t index = GET_UINT32(REGS.pc);
|
||||
if (!InitArrayElemOperation(cx, REGS.pc, obj, index, val))
|
||||
goto error;
|
||||
|
||||
|
@ -847,10 +847,10 @@
|
||||
* This opcode takes the final length, which is preallocated.
|
||||
* Category: Literals
|
||||
* Type: Array
|
||||
* Operands: uint24_t length
|
||||
* Operands: uint32_t length
|
||||
* Stack: => obj
|
||||
*/ \
|
||||
macro(JSOP_NEWARRAY, 90, "newarray", NULL, 4, 0, 1, JOF_UINT24) \
|
||||
macro(JSOP_NEWARRAY, 90, "newarray", NULL, 5, 0, 1, JOF_UINT32) \
|
||||
/*
|
||||
* Pushes newly created object onto the stack.
|
||||
*
|
||||
@ -920,10 +920,10 @@
|
||||
* property of 'obj' as 'val', pushes 'obj' onto the stack.
|
||||
* Category: Literals
|
||||
* Type: Array
|
||||
* Operands: uint24_t index
|
||||
* Operands: uint32_t index
|
||||
* Stack: obj, val => obj
|
||||
*/ \
|
||||
macro(JSOP_INITELEM_ARRAY,96, "initelem_array", NULL, 4, 2, 1, JOF_UINT24|JOF_ELEM|JOF_SET|JOF_DETECTING) \
|
||||
macro(JSOP_INITELEM_ARRAY,96, "initelem_array", NULL, 5, 2, 1, JOF_UINT32|JOF_ELEM|JOF_SET|JOF_DETECTING) \
|
||||
\
|
||||
/*
|
||||
* Initialize a getter in an object literal.
|
||||
@ -1277,13 +1277,12 @@
|
||||
* the same semantics as JSOP_NEWARRAY, but is distinguished to avoid
|
||||
* using unboxed arrays in spread calls, which would make compiling spread
|
||||
* calls in baseline more complex.
|
||||
*
|
||||
* Category: Literals
|
||||
* Type: Array
|
||||
* Operands: uint24_t length
|
||||
* Operands: uint32_t length
|
||||
* Stack: => obj
|
||||
*/ \
|
||||
macro(JSOP_SPREADCALLARRAY, 126, "spreadcallarray", NULL, 4, 0, 1, JOF_UINT24) \
|
||||
macro(JSOP_SPREADCALLARRAY, 126, "spreadcallarray", NULL, 5, 0, 1, JOF_UINT32) \
|
||||
\
|
||||
/*
|
||||
* Defines the given function on the current scope.
|
||||
|
@ -29,7 +29,7 @@ namespace js {
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 309;
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 310;
|
||||
static const uint32_t XDR_BYTECODE_VERSION =
|
||||
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user