Quellcode-Bibliothek CodeGenerator.cpp
Sprache: C
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "jit/CodeGenerator.h"
#include "mozilla/Assertions.h"
#include "mozilla/CheckedArithmetic.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/EnumeratedRange.h"
#include "mozilla/EnumSet.h"
#include "mozilla/IntegerTypeTraits.h"
#include "mozilla/Latin1.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/SIMD.h"
#include <algorithm>
#include <bit>
#include <cmath>
#include <limits>
#include <type_traits>
#include <utility>
#include "builtin/MapObject.h"
#include "builtin/Math.h"
#include "builtin/Number.h"
#include "builtin/RegExp.h"
#include "builtin/String.h"
#include "irregexp/RegExpTypes.h"
#include "jit/ABIArgGenerator.h"
#include "jit/CompileInfo.h"
#include "jit/InlineScriptTree.h"
#include "jit/Invalidation.h"
#include "jit/IonGenericCallStub.h"
#include "jit/IonIC.h"
#include "jit/IonScript.h"
#include "jit/JitcodeMap.h"
#include "jit/JitFrames.h"
#include "jit/JitRuntime.h"
#include "jit/JitSpewer.h"
#include "jit/JitZone.h"
#include "jit/Linker.h"
#include "jit/MIRGenerator.h"
#include "jit/MoveEmitter.h"
#include "jit/RangeAnalysis.h"
#include "jit/RegExpStubConstants.h"
#include "jit/SafepointIndex.h"
#include "jit/SharedICHelpers.h"
#include "jit/SharedICRegisters.h"
#include "jit/VMFunctions.h"
#include "jit/WarpSnapshot.h"
#include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin
#include "js/experimental/JitInfo.h" // JSJit{Getter,Setter}CallArgs, JSJitMethodCallArgsTraits, JSJitInfo
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
#include "js/RegExpFlags.h" // JS::RegExpFlag
#include "js/ScalarType.h" // js::Scalar::Type
#include "proxy/DOMProxy.h"
#include "proxy/ScriptedProxyHandler.h"
#include "util/DifferentialTesting.h"
#include "util/PortableMath.h"
#include "util/Unicode.h"
#include "vm/ArrayBufferViewObject.h"
#include "vm/AsyncFunction.h"
#include "vm/AsyncIteration.h"
#include "vm/BuiltinObjectKind.h"
#include "vm/DateObject.h"
#include "vm/FunctionFlags.h" // js::FunctionFlags
#include "vm/Interpreter.h"
#include "vm/JSAtomUtils.h" // AtomizeString
#include "vm/MatchPairs.h"
#include "vm/RegExpObject.h"
#include "vm/RegExpStatics.h"
#include "vm/RuntimeFuses.h"
#include "vm/StaticStrings.h"
#include "vm/StringObject.h"
#include "vm/StringType.h"
#include "vm/TypedArrayObject.h"
#include "wasm/WasmCodegenConstants.h"
#include "wasm/WasmPI.h"
#include "wasm/WasmStacks.h"
#include "wasm/WasmValType.h"
#ifdef MOZ_VTUNE
# include "vtune/VTuneWrapper.h"
#endif
#include "wasm/WasmBinary.h"
#include "wasm/WasmGC.h"
#include "wasm/WasmGcObject.h"
#include "wasm/WasmStubs.h"
#include "builtin/Boolean-inl.h"
#include "jit/MacroAssembler-inl.h"
#include "jit/shared/CodeGenerator-shared-inl.h"
#include "jit/TemplateObject-inl.h"
#include "jit/VMFunctionList-inl.h"
#include "vm/BytecodeUtil-inl.h"
#include "vm/JSScript-inl.h"
#include "wasm/WasmInstance-inl.h"
using namespace js;
using namespace js::jit;
using mozilla::CheckedUint32;
using mozilla::DebugOnly;
using mozilla::FloatingPoint;
using mozilla::NegativeInfinity;
using mozilla::PositiveInfinity;
using JS::ExpandoAndGeneration;
namespace js {
namespace jit {
#ifdef CHECK_OSIPOINT_REGISTERS
template < class Op>
static void HandleRegisterDump(Op op, MacroAssembler& masm,
LiveRegisterSet liveRegs, Register activation,
Register scratch) {
const size_t baseOffset = JitActivation::offsetOfRegs();
// Handle live GPRs.
for (GeneralRegisterIterator iter(liveRegs.gprs()); iter.more(); ++iter) {
Register reg = *iter;
Address dump(activation, baseOffset + RegisterDump::offsetOfRegister(reg));
if (reg == activation) {
// To use the original value of the activation register (that's
// now on top of the stack), we need the scratch register.
masm.push(scratch);
masm.loadPtr(Address(masm.getStackPointer(), sizeof(uintptr_t)), scratch);
op(scratch, dump);
masm.pop(scratch);
} else {
op(reg, dump);
}
}
// Handle live FPRs.
for (FloatRegisterIterator iter(liveRegs.fpus()); iter.more(); ++iter) {
FloatRegister reg = *iter;
Address dump(activation, baseOffset + RegisterDump::offsetOfRegister(reg));
op(reg, dump);
}
}
class StoreOp {
MacroAssembler& masm;
public:
explicit StoreOp(MacroAssembler& masm) : masm(masm) {}
void operator()( Register reg, Address dump) { masm.storePtr(reg, dump); }
void operator()(FloatRegister reg, Address dump) {
if (reg.isDouble()) {
masm.storeDouble(reg, dump);
} else if (reg.isSingle()) {
masm.storeFloat32(reg, dump);
} else if (reg.isSimd128()) {
MOZ_CRASH( "Unexpected case for SIMD");
} else {
MOZ_CRASH( "Unexpected register type.");
}
}
};
class VerifyOp {
MacroAssembler& masm;
Label* failure_;
public:
VerifyOp(MacroAssembler& masm, Label* failure)
: masm(masm), failure_(failure) {}
void operator()( Register reg, Address dump) {
masm.branchPtr(Assembler::NotEqual, dump, reg, failure_);
}
void operator()(FloatRegister reg, Address dump) {
if (reg.isDouble()) {
ScratchDoubleScope scratch(masm);
masm.loadDouble(dump, scratch);
masm.branchDouble(Assembler::DoubleNotEqual, scratch, reg, failure_);
} else if (reg.isSingle()) {
ScratchFloat32Scope scratch(masm);
masm.loadFloat32(dump, scratch);
masm.branchFloat(Assembler::DoubleNotEqual, scratch, reg, failure_);
} else if (reg.isSimd128()) {
MOZ_CRASH( "Unexpected case for SIMD");
} else {
MOZ_CRASH( "Unexpected register type.");
}
}
};
void CodeGenerator::verifyOsiPointRegs(LSafepoint* safepoint) {
// Ensure the live registers stored by callVM did not change between
// the call and this OsiPoint. Try-catch relies on this invariant.
// Load pointer to the JitActivation in a scratch register.
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
Register scratch = allRegs.takeAny();
masm.push(scratch);
masm.loadJitActivation(scratch);
// If we should not check registers (because the instruction did not call
// into the VM, or a GC happened), we're done.
Label failure, done;
Address checkRegs(scratch, JitActivation::offsetOfCheckRegs());
masm.branch32(Assembler::Equal, checkRegs, Imm32( 0), &done);
// Having more than one VM function call made in one visit function at
// runtime is a sec-ciritcal error, because if we conservatively assume that
// one of the function call can re-enter Ion, then the invalidation process
// will potentially add a call at a random location, by patching the code
// before the return address.
masm.branch32(Assembler::NotEqual, checkRegs, Imm32( 1), &failure);
// Set checkRegs to 0, so that we don't try to verify registers after we
// return from this script to the caller.
masm.store32(Imm32( 0), checkRegs);
// Ignore clobbered registers. Some instructions (like LValueToInt32) modify
// temps after calling into the VM. This is fine because no other
// instructions (including this OsiPoint) will depend on them. Also
// backtracking can also use the same register for an input and an output.
// These are marked as clobbered and shouldn't get checked.
LiveRegisterSet liveRegs;
liveRegs.set() = RegisterSet::Intersect(
safepoint->liveRegs().set(),
RegisterSet:: Not(safepoint->clobberedRegs().set()));
VerifyOp op(masm, &failure);
HandleRegisterDump<VerifyOp>(op, masm, liveRegs, scratch, allRegs.getAny());
masm.jump(&done);
// Do not profile the callWithABI that occurs below. This is to avoid a
// rare corner case that occurs when profiling interacts with itself:
//
// When slow profiling assertions are turned on, FunctionBoundary ops
// (which update the profiler pseudo-stack) may emit a callVM, which
// forces them to have an osi point associated with them. The
// FunctionBoundary for inline function entry is added to the caller's
// graph with a PC from the caller's code, but during codegen it modifies
// Gecko Profiler instrumentation to add the callee as the current top-most
// script. When codegen gets to the OSIPoint, and the callWithABI below is
// emitted, the codegen thinks that the current frame is the callee, but
// the PC it's using from the OSIPoint refers to the caller. This causes
// the profiler instrumentation of the callWithABI below to ASSERT, since
// the script and pc are mismatched. To avoid this, we simply omit
// instrumentation for these callWithABIs.
// Any live register captured by a safepoint (other than temp registers)
// must remain unchanged between the call and the OsiPoint instruction.
masm.bind(&failure);
masm.assumeUnreachable( "Modified registers between VM call and OsiPoint");
masm.bind(&done);
masm.pop(scratch);
}
bool CodeGenerator::shouldVerifyOsiPointRegs(LSafepoint* safepoint) {
if (!checkOsiPointRegisters) {
return false;
}
if (safepoint->liveRegs().emptyGeneral() &&
safepoint->liveRegs().emptyFloat()) {
return false; // No registers to check.
}
return true;
}
void CodeGenerator::resetOsiPointRegs(LSafepoint* safepoint) {
if (!shouldVerifyOsiPointRegs(safepoint)) {
return;
}
// Set checkRegs to 0. If we perform a VM call, the instruction
// will set it to 1.
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
Register scratch = allRegs.takeAny();
masm.push(scratch);
masm.loadJitActivation(scratch);
Address checkRegs(scratch, JitActivation::offsetOfCheckRegs());
masm.store32(Imm32( 0), checkRegs);
masm.pop(scratch);
}
static void StoreAllLiveRegs(MacroAssembler& masm, LiveRegisterSet liveRegs) {
// Store a copy of all live registers before performing the call.
// When we reach the OsiPoint, we can use this to check nothing
// modified them in the meantime.
// Load pointer to the JitActivation in a scratch register.
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
Register scratch = allRegs.takeAny();
masm.push(scratch);
masm.loadJitActivation(scratch);
Address checkRegs(scratch, JitActivation::offsetOfCheckRegs());
masm.add32(Imm32( 1), checkRegs);
StoreOp op(masm);
HandleRegisterDump<StoreOp>(op, masm, liveRegs, scratch, allRegs.getAny());
masm.pop(scratch);
}
#endif // CHECK_OSIPOINT_REGISTERS
// Before doing any call to Cpp, you should ensure that volatile
// registers are evicted by the register allocator.
void CodeGenerator::callVMInternal(VMFunctionId id, LInstruction* ins) {
TrampolinePtr code = gen->jitRuntime()->getVMWrapper(id);
const VMFunctionData& fun = GetVMFunction(id);
// Stack is:
// ... frame ...
// [args]
#ifdef DEBUG
MOZ_ASSERT(pushedArgs_ == fun.explicitArgs);
pushedArgs_ = 0;
#endif
#ifdef CHECK_OSIPOINT_REGISTERS
if (shouldVerifyOsiPointRegs(ins->safepoint())) {
StoreAllLiveRegs(masm, ins->safepoint()->liveRegs());
}
#endif
#ifdef DEBUG
if (ins->mirRaw()) {
MOZ_ASSERT(ins->mirRaw()->isInstruction());
MInstruction* mir = ins->mirRaw()->toInstruction();
MOZ_ASSERT_IF(mir->needsResumePoint(), mir->resumePoint());
// If this MIR instruction has an overridden AliasSet, set the JitRuntime's/* This Source Code Form is subject to the terms of the Mozilla Public
/ disallowArbitraryCode_ flag so we can assert this VMFunction doesn't call
// RunScript. Whitelist MInterruptCheck and MCheckOverRecursed because
// interrupt callbacks can call JS (chrome JS or shell testing functions).
bool isWhitelisted = mir->isInterruptCheck() || mir->isCheckOverRecursed();
if (!mir->hasDefaultAliasSet() && !isWhitelisted) {
const void* addr = gen->jitRuntime()->addressOfDisallowArbitraryCode();
masm.(Imm32(1),ReturnReg);
masm.store32(ReturnReg, AbsoluteAddress(addr));
}
#includemozillaEnumeratedArray.h"
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 6
// Push an exit frame descriptor.
masm.Push((java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 47
// Call the wrapper function. The wrapper is in charge to unwind the stack
// when returning from the call. Failures are handled with exceptions based
// on the return value of the C functions. To guard the outcome of the"itJitcodeMaphjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
// returned value, use another LIR instruction.
ensureOsiSpace();
uint32_t include jit/MIRGenerator.h"
markSafepointAt#nclude"jit/RegExpStubConstants.h"
#ifdef #include jit/SafepointIndex.h"
aryCode flag after the call.
{
const void* addr = gen->jitRuntime(#nclude "itVMFunctions.h"
)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
masm.move32#nclude "proxy/DOMProxy.h"
asmstore32(ReturnReg, AbsoluteAddress());
#include "util/PortableMath.h"
ejava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
// Pop rest of the exit frame and the arguments left on the stack.
framePop =
sizeof#nclude"vm/SAtomUtils"
asmimplicitPop(fun.explicitStackSlots() * sizeof(void*) + framePop);
// Stack is:
// ... frame ...include "asm/asmCodegenConstantshjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}
name fn
void CodeGeneratorinclude "/asmStubs.h"
VMFunctionId id = VMFunctionToId<Fn, fn>::id;
callVMInternal(id, ins)
}
// ArgSeq store arguments for OutOfLineCallVM.
//
// OutOfLineCallVM are created with "oolCallVM" function. The third argument of
using namespace js;
// of pushing the argument, with "pushArg", for a VMFunction.
//
// Such list of arguments can be created by using the "ArgList" function which
// creates one instance of "ArgSeq", where the type of the arguments are
// inferred from the type of the arguments.
//
// The list of arguments must be written in the same order as if you were
// calling the function in C++.
//
// Example:
// ArgList(ToRegister(lir->lhs()), ToRegister(lir->rhs()))
java.lang.StringIndexOutOfBoundsException: Range [18, 8) out of bounds for length 31
classjava.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 14
std:static void Op &masm,
Register scratch) java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
generate(* codegen,
::index_sequence<ISeq...>)const java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
// Arguments are pushed in reverse order, from last argument to first
// argument.
(codegen->pushArg(std::get<sizeof...(ISeq) - 1 - ISeq>(args_)), ...);
}
public:
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
args_(::forward<ArgTypes>args)...) {}
inline void generate(CodeGenerator* )FloatRegister Address dump) java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
generate(codegen, } else {
}MOZ_CRASH"java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 45
ifdef DEBUG
ize_tnumArgs=sizeof..(rgTypes)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
#endif
};
template <typename... ArgTypes>
inline ArgSeq<masm.loadDoubledumps)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
..>std:forward<().)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
// Store wrappers, to generate the right move of data after the VM call.
::verifyOsiPointRegs(LSafepoint* safepoint) {
inline void generate(CodeGenerator // the call and this OsiPoint. Try-catch relies on this invariant.
red() const{
return LiveRegisterSet(); // No register gets clobbered
}
};
class StoreRegisterTo {
private:
Register out_;
public:
explicit StoreRegisterTo(Register out) : Address checkRegs(scratch, JitActivation::offsetOfCheckRegs())java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
inline void generatemasmbranch32(:N checkRegs,Imm32(),&;
// It's okay to use storePointerResultTo here - the VMFunction wrapper
// ensures the upper bytes are zero for bool/int32 return values.
codegen->storePointerResultTo(out_);
}
inline LiveRegisterSet clobbered() const {
RegisterSet::Not(safepoint->clobberedRegs().set()));
set.dd(out_)java.lang.StringIndexOutOfBoundsException: Range [18, 19) out of bounds for length 18
return // rare corner case that occurs when profiling interacts with itself:
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
};
class StoreFloatRegisterTo {
private:
FloatRegister out_;
public:
explicit StoreFloatRegisterTo(FloatRegister out) :
codegen->storeFloatResultTo(out_);
}
inline LiveRegisterSet // the profiler instrumentation of the callWithABI below to ASSERT, since
LiveRegisterSet set;
set./java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
returnset;
};
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 1
class StoreValueTo_ {
private:
Output out_;
public:
explicit StoreValueTo_(const Output& out) : out_(out) {}
inline void generate(CodeGenerator* codegen) const {
codegenstoreResultValueToo;
}
inline LiveRegisterSet clobbered() const {
/java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
java.lang.StringIndexOutOfBoundsException: Range [18, 4) out of bounds for length 18
returnAddress :offsetOfCheckRegs()java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
};
template </ them in meantime.
Allocatable G:All()
StoreValueTo_<Output>(out;
}
template/CHECK_OSIPOINT_REGISTERS
class OutOfLineCallVM : public OutOfLineCodeBase
atejava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
VMFunctionDat&fun GetVMFunction()java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
ArgSeq args_;
StoreOutputTo out_;
public:
OutOfLineCallVM(LInstruction* lir, const ArgSeq& args,
const StoreOutputTo StoreAllLiveRegs(masm,ins-safepoint)>liveRegs)java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
// If this MIR instruction has an overridden AliasSet, set the JitRuntime's
void /java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
codegenbool isWhitelisted =>isInterruptCheck( | mir>isCheckOverRecursed(;
}
LInstruction*lir) const { return lir_;}
}
const StoreOutputTo& out() const { return out_; }
};
template <Fn,Fn fn,class ArgSeq,class StoreOutputTo>
OutOfLineCode*CodeGenerator::oolCallVM(LInstruction* lir, const ArgSeq& args,
StoreOutputTo) java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
MOZ_ASSERT(lir-> masm.push(ReturnReg);
MOZ_ASSERT(ir->mirRaw)>sInstruction()java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
#ifdef DEBUG
id = VMFunctionToIdF fn>:d;
template <typename Fn, >
java.lang.StringIndexOutOfBoundsException: Range [29, 12) out of bounds for length 47
MOZ_ASSERTjava.lang.StringIndexOutOfBoundsException: Range [12, 13) out of bounds for length 1
// OutOfLineCallVM are created with "oolCallVM" function// this function is an instance of a class which provides a "generate" in charge
#endif
OutOfLineCodejava.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
< , ArgSeq, (lir,args, out);
ool,lirmirRaw)))java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
(codcodegen-pushArg(:sizeof..ISeq -1 - ISeq(rgs_), .)java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
}
Fn fn classArgSeqclass java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 64
void CodeGenerator::visitOutOfLineCallVM(
void generate(*codegen)const }
LInstruction* inline LiveRegisterSet clobbered() const {
#;
{
AutoJitSpewMessage
ublic
lir->opName());
if (const char* extra = lir->getExtraName()) //ensures the bytes for int32 returnvalues.
msgappend("s,extra);
}
}
#endif
perfSpewerLiveRegisterSet set;
if (!
saveLive(lir);
}
ool->args().generate(this);
}
ool->java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 24
if (!lir->isCall()) {
restoreLiveIgnore(lir, ool->out().clobbered());
}
class OutOfLineCallVM publicCodeGenerator> {
}
java.lang.StringIndexOutOfBoundsException: Range [27, 25) out of bounds for length 69
codegen->visitOutOfLineCallVM(this);
LInstruction*lir_;
size_t cacheIndex_;
size_t cacheInfoIndex_;
public:
OutOfLineICFallbacktjava.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 64
size_t cacheInfoIndex)
MOZ_ASSERTlir-mirRaw()java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
void (override {
/ bindingoftheinitialjump isdonei
// CodeGenerator::visitOutOfLineICFallback.
}
size_t cacheIndex( Fn ,,(, java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
AutoJitSpewMessage msg(JitSpew_Codegen,
LInstruction (const *extra g)) java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
void accept(CodeGenerator* }
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
};
void size_t cacheIndex_
if (
masm.setOOM();
return;
}
DataPtr<IonIC> lir_(lir), cacheIndex_(cacheIndex), cacheInfoIndex_(cacheInfoIndex) {}
MInstruction* mir = lir->mirRaw}
cache->size_t cacheIndex)const { return ;}
mir>resumePoint(->pc());
Register tempjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
icInfo_.back).icOffsetForJump = masm.movWithPatch(ImmWord(-1), temp);
.umpAddress(temp, 0));
MOZ_ASSERT(!icInfo_. DataPtr<IonIC>cache(this-info(.script(),
OutOfLineICFallback* ool =
new (alloc()) OutOfLineICFallback(lir, cacheIndex, icInfo_.length;
new (alloc) OutOfLineICFallback(lir,cacheIndex, icInfo_.ength) -1
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
cache->setRejoinOffset(CodeOffset
}
size_t cacheInfoIndex ool-cacheInfoIndex()
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
size_t cacheIndex -cacheIndex(;
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
DataPtr<IonIC> ic(his, cacheIndex;
// Register the location of the OOL path in the IC.
ic->setFallbackOffset(CodeOffset(masm.currentOffset()));
switch (ic->kind()) {
case CacheKind::GetProp:
case CacheKind:GetElem:{
IonGetPropertyIC* getPropIC = ic->asGetPropertyIC();
saveLive(lir);
pushArg(getPropIC->id());
pushArg(getPropIC->value());
icInfo_mp(ool->rejoin());
c :java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
()JSContext, IonGetPropertyIC,
>java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 42
StoreValueTo(>())generate(this);
restoreLiveIgnore(lir, java.lang.StringIndexOutOfBoundsException: Range [0, 41) out of bounds for length 16
masm.jump(ool->rejoin());
return;
}
case CacheKind::GetPropSuper:
case CacheKind::GetElemSuper: {
PropSuperIC();
java.lang.StringIndexOutOfBoundsException: Range [29, 14) out of bounds for length 31
pushArg(getPropSuperIC->id() case CacheKind:SetElem: {
pushArg(getPropSuperIC->receiver());
pushArg>);
icInfo_[cacheInfoIndex]. icInfo_[cacheInfoIndex].icOffsetForPushpushArgWithPatch(ImmWord(-))java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
HandleObject, HandleValue, HandleValue);
using Fn =
()JSContext*, HandleScript, IonGetPropSuperIC*, HandleObject,
IonGetNameIC* getNameICic-asGetNameIC()java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
ImmGCPtrg-outerInfo(.))java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
(etPropSuperIC->output()generatet)java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
restoreLiveIgnore(lir,
StoreValueTo(getPropSuperIC->output()).clobbered()
jump(ool>);
lir;
}
case CacheKind::SetProp:
case CacheKind::SetElem: {
IonSetPropertyIC*setPropIC = ic->asSetPropertyIC();
saveLive JSObject* (*)(JSContext*, HandleScript, IonBindNameIC*, HandleObject);
setPropIC-rhs()java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0
pushArg(setPropIC->pushArg(getIteratorIC->value)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
[java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 78
pushArg(ImmGCPtr(gen->uterInfo().script()));
= bool *)(*, ,
StoreRegisterTo(getIteratorIC>utput().lobbered());
callVMjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
restoreLive(lir);
masm.jump(ool->rejoin());
return;
}
case CacheKind:
IonGetNameIC* getNameIC = ic->icInfo_[cacheInfoIndex].icOffsetForPush pushArgWithPatch(ImmWord(-1));
saveLive(lir);
getNameIC-e()java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
icInfo_[cacheInfoIndex]icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->outerInfo().script()));
IonInIC* inIC = ic->asInIC();
i-()java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
callVM<Fn IonGetNameIC::update>(lir);
StoreValueTo(getNameIC->output()).generate(this);
restoreLiveIgnore(lir StoreValueTo(getNameIC->()clobbered());
masm.jump(ool->rejoin());
return;
}
:BindName java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
pushArg(hasOwnIC()java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
saveLive(lir)u bool *(SContext* * java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
pushArg(bindNameICjumpool>java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 31
icInfo_cijava.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 78
using Fn =
JSObject* (*)pushArg(gen>outerInfo(.script();
callVM<Fn, IonBindNameIC::update>(lir);
StoreRegisterTo(bindNameIC->output()).generate(this);
restoreLiveIgnore(lir, java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 24
masm.jumpool->rejoin());
return
}
IonInstanceOfIC* hasInstanceOfIC = ic->asInstanceOfIC();
IonGetIteratorIC*[.cOffsetForPush=pushArgWithPatch(ImmWord(1);
saveLive(lir callVM:()
pushArg(getIteratorIC->value());
icInfo_[java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 78
pushArg(gen>outerInfo(.cript()java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
ect* ()JSContext* HandleScript, IonGetIteratorICjava.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
HandleValue);
callVM<, IonGetIteratorIC:update>lir)
getIteratorIC>output()).generate(this);
java.lang.StringIndexOutOfBoundsException: Range [6, 1) out of bounds for length 31
StoreRegisterTo( *toPropertyKeyIC -asToPropertyKeyIC)java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
masm.jump(java.lang.StringIndexOutOfBoundsException: Range [26, 19) out of bounds for length 66
return;
}
case CacheKindjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
=ic-)
saveLive(lir);
pushArg(optimizeSpreadCallIC->value(java.lang.StringIndexOutOfBoundsException: Range [27, 23) out of bounds for length 80
icInfo_[cacheInfoIndexIonCompareIC*compareIC =ic-asCompareIC)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
ImmGCPtr(genouterInfo(script();
Fn (), ,
HandleValue, MutableHandleValue);
callVM<Fn, IonOptimizeSpreadCallIC::update>(restoreLiveIgnore(java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 79
StoreValueTo(optimizeSpreadCallIC->output())
java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
lir, StoreValueTo(u =
masm.jump(ool->rejoin());
return;
}
case CacheKind case : java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
IonInIC*inIC = ic-asInIC(;
saveLive(lir);
pushArg(nIC>object()java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
pushArg
pushArg(.jump(ool->rejoin
using Fn = bool (*)(JSContext*, HandleScript,
HandleObject,case :java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 1
as)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
restoreLiveIgnore(lir, StoreRegisterTo(inIC->output()).clobbered());
masm.jump(ool->rejoin());
eturn;
}
case ionScriptLabels_(gen->alloc()),
IonHasOwnIC* hasOwnIC = ic->java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 31
saveLive(lir);
pushArg(hasOwnIC->idRegister output ToRegister(lir->output();
pushArg(hasOwnIC->value());
cacheInfoIndex]icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(gen-outerInfo().cript();
Fn=bool()JSContext*, HandleScript, IonHasOwnIC*, HandleValue,
HandleValue;
callVM<Fn, IonHasOwnIC::update
tput().enerate(java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
restoreLiveIgnorel,StoreRegisterTo(-output());
masm.jump(ool->rejoin());
return;
}
case CacheKind(-)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0
void :(LValueToFloat32*){
pushArg(checkPrivateFieldIC->id());
pushArg(checkPrivateFieldIC->value());
icInfo_[cacheInfoIndex].icOffsetForPush =
pushArg(java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 47
using Fn = bool (*)(JSContextjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
callVM<Fn, IonCheckPrivateFieldIC: masmconvertValueToFloat16( ,volatileRegs &ail)java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
StoreRegisterTo(heckPrivateFieldIC->()generate(this);
(
lir, masm.extractTag(operand, output)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
masm .nboxBigInt(o;
return;
}
{
= java.lang.StringIndexOutOfBoundsException: Range [45, 43) out of bounds for length 62
e(;
pushArg(hasInstanceOfIC->rhs());
pushArg(hasInstanceOfIC->lhs(}
= pushArgWithPatch(ImmWord(-1));
java.lang.StringIndexOutOfBoundsException: Range [22, 13) out of bounds for length 51
using Fn
void CodeGenerator:visitFloat32ToDouble( lir {
callVM<Fn, java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0
StoreRegisterTo(hasInstanceOfIC-output).(this);
restoreLiveIgnore(lir,
StoreRegisterTo(hasInstanceOfIC->output()).java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 63
masm.jumpjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 1
return;
}
case CacheKind::UnaryArith: java.lang.StringIndexOutOfBoundsException: Range [18, 16) out of bounds for length 41
IonUnaryArithIC* unaryArithIC = ic->asUnaryArithIC( java.lang.StringIndexOutOfBoundsException: Range [33, 29) out of bounds for length 59
ToRegisterlir->(),ToRegister(lir->temp1()));
pushArg(unaryArithIC->input());
icInfo_[cacheInfoIndex].icOffsetForPush = java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 47
pushArg(ImmGCPtr(gen->masm.convertFloat32ToFloat16
() ,java.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 66
IonUnaryArithIC** stub, HandleValue val,
MutableHandleValue res);
callVM<Fn, IonUnaryArithIC::update>(java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 0
StoreValueTo(unaryArithIC->output()Register output =ToRegister(lir->output());
restoreLiveIgnore(lir, StoreValueTo(unaryArithIC->outputjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
masm.jump(ool->java.lang.StringIndexOutOfBoundsException: Range [0, 27) out of bounds for length 1
MOZ_ASSERT(lir->mir()->canBeNegative());
*java.lang.StringIndexOutOfBoundsException: Range [28, 26) out of bounds for length 42
case CacheKind::ToPropertyKey: {java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 57
IonToPropertyKeyIC*R ToRegister(>);
saveLive(lir);
:LAdjustDataViewLengthl java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
cacheInfoIndex]icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(java.lang.StringIndexOutOfBoundsException: Range [14, 0) out of bounds for length 0
bailoutFrom(&ail lir>snapshot()java.lang.StringIndexOutOfBoundsException: Range [38, 39) out of bounds for length 38
,java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of bounds for length 66
MutableHandleValue res);
callVM<Fn, IonToPropertyKeyIC::update>(lir);
>).enerate(;
restoreLiveIgnore(lir,
StoreValueTo(RuntimeFuses::FuseIndex::HasSeenObjectEmulateUndefinedFuse scratch);
masm.jump(ool->rejoin());
return;
}
case CacheKind *(
IonBinaryArithIC#endif
saveLive(lir);
pushArg(binaryArithIC->java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 1
// including in object truthiness testing.) We check truthiness // when we're testing it on a proxy, in which case out-of-line code will call
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
pushArg(ImmGCPtr(genjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
using Fn *( ,HandleScriptouterScriptjava.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
codegen>objreg_ java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
, )
Fn,IonBinaryArithIC:update>(ir)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
StoreValueTo(binaryArithIC->output()).generate(this);
restoreLiveIgnore(lir,StoreValueTo(binaryArithIC->output()).clobbered());
masm// the ifTruthy/ifFalsy labels are needed in inline code as well as out-of-line
return;
}
case CacheKind::Compare: {
}
saveLive(lir);
compareIC>rhs());
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0
icInfo_cacheInfoIndex]icOffsetForPush=pushArgWithPatch(ImmWord(1);
pushArg(ImmGCPtr(gen->outerInfo Register Label*ifEmulatesUndefined,
using Fn =
java.lang.StringIndexOutOfBoundsException: Range [72, 14) out of bounds for length 79
,HandleValue rhs res;
allVMFn, :(;
StoreRegisterTo(ompareIC-output()g(his;
()).clobbered());
masm.jump(ool->rejoin());
returnOutOfLineTestObject*ool) java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
}
case CacheKindjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
);
saveLive(lir);
pushArg(closeIterIC->iter .java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 64
pushArggen>outerInfo()script))java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
using Fn =
bool (*) asm.branchTestType(Assembler::Equal, tag, type, ifFalsy);
Fn IonCloseIterIC::>(;
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
masm.jump( ScratchTagSco _&tag;
eturn;
}
case CacheKind::OptimizeGetIterator: {
auto* optimizeGetIteratorICreturnjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
lir);
(->))java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
icInfo_[cacheInfoIndex]){
pushArg(ImmGCPtr(gen->java.lang.StringIndexOutOfBoundsException: Range [5, 37) out of bounds for length 5
= *, java.lang.StringIndexOutOfBoundsException: Range [77, 76) out of bounds for length 78
java.lang.StringIndexOutOfBoundsException: Range [39, 37) out of bounds for length 50
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
>java.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 70
restoreLiveIgnore(
lir, StoreRegisterTo(
masm.jump(oolCodeGenerator:testValueTruthy(onst ValueOperand& java.lang.StringIndexOutOfBoundsException: Range [62, 63) out of bounds for length 62
return;
}
ase :java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
case CacheKind:: const std::initializer_l {
case CacheKind::TypeOfEq:
case CacheKind::ToBool:
case java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 0
case CacheKind::NewArray:
case CacheKind::NewObject:
case CacheKind::Lambda:
case CacheKind::GetImport:
MOZ_CRASH(" ifTruthy,ifFalsy,ool,/*skipTypeTest*/ false);
}
MOZ_CRASH();
}
StringObject* MNewStringObject::templateObj() java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 0
return &templateObj_->as<StringObject>();
}
CodeGeneratorjava.lang.StringIndexOutOfBoundsException: Range [43, 41) out of bounds for length 64
* java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 50
const wasm::java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 1
:CodeGeneratorSpecific(en,graph, wasmCodeMeta,
ionScriptLabels_(gen->alloc()),
if (isNextBlock(ifFalse->lir() {
nurseryValueLabels_(gen->alloc()),
scriptCounts_(nullptr) {}
CodeGenerator .java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 53
CodeGenerator:isitValueToNumberInt32(LValueToNumberInt32* lir {
ValueOperand MBasicBlock* ifTrue test->ifTrue(;
Register output = ToRegister(lir->
FloatRegister temp = ToFloatRegister(lir->temp0());
Label fails;
masm.convertValueToInt32(operand, temp, output, &fails,
lir->mir()->needsNegativeZeroCheck(),
lir->mir()->conversion());
bailoutFrom(&fails, lir->snapshot());
}
void CodeGenerator::visitValueTruncateToInt32(LValueTruncateToInt32* lir) {
ValueOperand operand = ToValue(lir->input());
Register output = ToRegister(lir->output());
FloatRegister temp = ToFloatRegister(lir->temp0());
Register stringReg = ToRegister(lir->temp1());
auto* oolDouble = oolTruncateDouble(temp, output, lir->mir());
using Fn = bool (*)(JSContext*, JSString*, double*);
auto* oolString = oolCallVM<Fn, StringToNumber>(lir, ArgList(stringReg),
StoreFloatRegisterTo(temp));
Label* stringEntry = oolString->java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 25
Label* stringRejoin = oolString->rejoin();
Label fails;
masm.truncateValueToInt32(operand, stringEntry, stringRejoin,
oolDouble->entry(), stringReg, temp, output,
&java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
masm.bind(oolDouble->rejoin());
bailoutFrom(&fails, lir->snapshot()java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
void java.lang.StringIndexOutOfBoundsException: Range [44, 20) out of bounds for length 44
ValueOperand operand = ToValue(lir->input());
FloatRegister output = ToFloatRegister(lir->output());
Label fail;
masm.convertValueToDouble(operand, output, &fail);
bailoutFrom(&fail, lir->snapshot());
}
void CodeGenerator::visitValueToFloat32(LValueToFloat32* lir) {
ValueOperand operand = ToValue(lir->input());
FloatRegister output = ToFloatRegister(lir->output());
Label fail;
masm.convertValueToFloat32(operand, output, &fail);
bailoutFrom(&fail, lir->snapshot());
}
void CodeGenerator::visitValueToFloat16(LValueToFloat16* lir) {
ValueOperand operand = ToValue(lir->input());
Register temp = ToTempRegisterOrInvalid(lir->temp0());
FloatRegister output = ToFloatRegister(lir->output());
LiveRegisterSet volatileRegs;
if (!MacroAssembler::SupportsFloat64To16()) {
volatileRegs = liveVolatileRegs(lir);
}
Label fail;
masm.convertValueToFloat16(operand, output, temp, volatileRegs, &fail);
bailoutFrom(&fail, lir->snapshot());
}
java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for leng th 61
ValueOperand operand = ToValue(lir->input Registeri, temp *mirjava.lang.StringIndexOutOfBoundsException: Range [61, 62) out of bounds for length 61
output (java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 46
using Fn =
auto* ool =
oolCallVM<Fn,java.lang.StringIndexOutOfBoundsException: Range [31, 29) out of bounds for length 31
Register tagjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
Label java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 55
masm.branchTestBigInt Register temp=ToRegisterl>);
masm.unboxBigInt(operand, output);
masm.jump(&done);
masm.bind(¬BigInt);
masm.branchTestBoolean(Assembler::Equal, tag, ool->*ool new(lloc) ()java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
masm.branchTestString(Assembler::Equal, tag, ool->
// ToBigInt(object) can have side-effects; all other types throw a TypeError.
bailout(lir));
masm.bind(ool->rejoin());
masm.bind(&done);
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
void else {
masm.convertInt32ToDouble(ToRegister(lir->input()),
ToFloatRegister(lir->output()));
}
void CodeGenerator::visitFloat32ToDouble(LFloat32ToDouble* lir) {
masm.convertFloat32ToDouble(ToFloatRegister(lir->input()),
ToFloatRegister(lir->output()));
}
void CodeGenerator::visitDoubleToFloat32(LDoubleToFloat32* lir) {
masm.convertDoubleToFloat32(ToFloatRegister(lir->input()),
ToFloatRegister(lir->output()));
}
void CodeGenerator::visitInt32ToFloat32(LInt32ToFloat32* lir) {
masm.convertInt32ToFloat32(ToRegister(lir->input()),
ToFloatRegister(lir->output()));
}
void CodeGenerator::visitDoubleToFloat16(LDoubleToFloat16* lir) {
LiveRegisterSet volatileRegs;
if (!MacroAssembler::SupportsFloat64To16()) {
volatileRegs = liveVolatileRegs(lir);
}
masm.convertDoubleToFloat16(
ToFloatRegister(lir->input()), ToFloatRegister(lir->output()),
ToTempRegisterOrInvalid(lir->temp0()), volatileRegs);
}
void CodeGenerator::visitDoubleToFloat32ToFloat16(
LDoubleToFloat32ToFloat16* lir) {
masm.convertDoubleToFloat16(
ToFloatRegister(lir->input()), ToFloatRegister(lir->output()),
ToRegister(lir->temp0()), ToRegister(lir->temp1()));
}
void CodeGenerator::visitFloat32ToFloat16(LFloat32ToFloat16* lir) {
LiveRegisterSet volatileRegs;
if (!MacroAssembler::SupportsFloat32To16()) {
volatileRegs = liveVolatileRegs(lir);
}
masm.convertFloat32ToFloat16(
MOZ_ASSERT(lir->mir()->eedsSnapshot());
java.lang.StringIndexOutOfBoundsException: Range [16, 11) out of bounds for length 17
}
void CodeGenerator::visitInt32ToFloat16(LInt32ToFloat16* lir) {
LiveRegisterSet volatileRegs;
if (!MacroAssembler::java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 41
volatileRegs ()
}
masm.convertInt32ToFloat16(
-),T(lir>),
ToTempRegisterOrInvalid(lir->temp0()), volatileRegs);
}
void CodeGenerator::visitDoubleToInt32tbuffer);
Label fail;
FloatRegister input = ToFloatRegister(lir->input());
Register output = regs.takeUnchecked(holder).holder)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
masm.convertDoubleToInt32(java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 22
lir->mir()->needsNegativeZeroCheck.addrReg)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
bailoutFrom(&fail, lir->snapshot());
}
void // Warning: this function modifies prev and next.
Label fail;
FloatRegister input =ToFloatRegister(>input()java.lang.StringIndexOutOfBoundsException: Range [54, 55) out of bounds for length 54
Register output = (ir->);
masm.convertFloat32ToInt32(input, output, &fail,
lir->mir()->needsNegativeZeroCheck());
bailoutFrom(&fail, lir->snapshot());
}
void CodeGenerator::visitInt32ToIntPtr(LInt32ToIntPtr* lir) {
#ifdef JS_64BIT
// This LIR instruction is only used if the input can be negative.
MOZ_ASSERT(lir->mir()->canBeNegative());
b(ssembler:Equal, ImmWord0,&checkRemove;
const LAllocation* input = lir->input();
if (input->isGeneralReg()) {
masm.// if (prev
} masm.branchPtr(Assembler:,ImmWord(),&)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
masmb(p;
}
#else.ump(exit;
MOZ_CRASH("Not used on 32-bit platforms");
#endif
}
void CodeGenerator::visitNonNegativeIntPtrToInt32(
LNonNegativeIntPtrToInt32* lir) {
#ifdef.loadStoreBuffer(prev, storebuffer);
Register output =bind&xitjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
MOZ_ASSERT(lirinput)= ;
Label bail;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
bailoutFrom(&bail, lir->snapshot());
#else
MOZ_CRASH("Not used on 32-bit platforms");
#endif
}
void CodeGenerator::visitIntPtrToDouble(LIntPtrToDouble* lir) {
Register input = ToRegister(lir->input());
FloatRegister output = ToFloatRegister(lirjava.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 28
masm.convertIntPtrToDouble(input, output);
}
void CodeGenerator::visitAdjustDataViewLength*providing fast regexp execution inbaseline andIon.
Register output = ToRegister(lir->output());
MOZ_ASSERT *Ingeneral,they -ostedcode.
uint32_tjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
#fdefDEBUG
Label ok;
masm.branchTestPtr(Assembler::NotSigned,
java.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 79
masm.bind(&ok);
#endif
Label bail;
masm execution is java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of bounds for length 67
&,lir>);
}
atorRegister
Label* ifEmulatesUndefined,
Label* ifDoesntEmulateUndefined,
java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 57
Rjava.lang.StringIndexOutOfBoundsException: Range [33, 31) out of bounds for length 75
(FUZZING)
masm.loadRuntimeFuse(
java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 68
static java.lang.StringIndexOutOfBoundsException: Range [63, 62) out of bounds for length 70
masm.setupAlignedABICall();
masm.passABIArg(objreg);
masm.passABIArg java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 41
masm.callWithABI<Fn, RegExpStaticso);
#else
using Fn = bool (*)(JSObject* obj);
masm.setupAlignedABICall();
masm.passABIArg(xperimental_legacy_regexp)) {
masm.allWithABI<n js:>)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
#endif
masm.storeCallPointerResult(scratch);
restoreVolatile(scratch);
temp1 ;
masm.jump(ifDoesntEmulateUndefined);
}
// Base out-of-line code generator for all tests of the truthiness of an
// object, where the object might not be truthy. (Recall that per spec all
// objects are truthy, but we implement the JSCLASS_EMULATES_UNDEFINED class
// flag to permit objects to look like |undefined| in certain contexts,
// including in object truthiness testing.) We check truthiness inline except
// when we're testing it on a proxy, in which case out-of-line code will call
// EmulatesUndefined for a conclusive answer.
CodeGenerator
Register objreg_;
Register scratch_;
Label* ifEmulatesUndefined_;
Label ifDoesntEmulateUndefined_;
#ifdef DEBUG
boolinitialized =nullptr; java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
#endif
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
java.lang.StringIndexOutOfBoundsException: Range [26, 16) out of bounds for length 64
: ifEmulatesUndefined_(nullptr), ifDoesntEmulateUndefined_(nullptr) {}
void accept(CodeGenerator* codegen) final {
MOZ_ASSERT(initialized());
codegen->emitOOLTestObject(objreg_, ifEmulatesUndefined_,
ifDoesntEmulateUndefined_, scratch_);
}
/
// jump to if the object is truthy or falsy, and a scratch register for
// use in the out-of-line path.
voidmasm(regexp, NativeObject::etFixedSlotOffset(
Label* ifDoesntEmulateUndefined, Register scratch) {
MOZ_ASSERT(!initialized());
MOZ_ASSERT( ;
objreg_ = objreg;
static_assert(::java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 80
ifEmulatesUndefined_ = ifEmulatesUndefined;
// Prepare an InputOutputData and optional MatchPairs which space has been
}
};
// A subclass of OutOfLineTestObject containing two extra labels, for use when
// the ifTruthy/ifFalsy labels are needed in inline code as well as out-of-line
// code. The user should bind these labels in inline code, and specify them as
// targets via setInputAndTargets, as appropriate.
class OutOfLineTestObjectWithLabels : public JitSpew # )java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
Label /*
Label label2_;
public:
(;
Label*label1( return label1_;
Label* label2() { return &label2_; }
};
CodeGenerator:java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
* java.lang.StringIndexOutOfBoundsException: Range [57, 58) out of bounds for length 57
*ifDoesntEmulateUndefined, java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
OutOfLineTestObject* ool) {
ool->setInputAndTargets(objreg, ifEmulatesUndefined, ifDoesntEmulateUndefined,
scratch);
// Perform a fast-path check of the object's class flags if the object's
code handle slow casesrequire
java.lang.StringIndexOutOfBoundsException: Range [0, 70) out of bounds for length 63
masm.branchIfObjectEmulatesUndefined(objreg, scratch, ool->entry(),
ifEmulatesUndefined);
}
void CodeGenerator:: * . RegExpObject::MaxPairCount
Register objreg, Label* -------- java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
Label* ifDoesntEmulateUndefined, Register scratch,
OutOfLineTestObject* ool) {
int32_tmatchPairsOffset = +int32_t(izeof(nputOutputData);
"ifDoesntEmulateUndefined
testObjectEmulatesUndefinedKernel(objreg, ifEmulatesUndefined, java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 80
ifDoesntEmulateUndefined, scratch, ool);
masm.bind(ifDoesntEmulateUndefined);
}
void CodeGenerator::java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [0, 53) out of bounds for length 0
Label* ifDoesntEmulateUndefined,
Register scratch,
OutOfLineTestObject* ool) {
(regexp.()
ifDoesntEmulateUndefined, scratch, oolF = JSLinearString*()JSString*;
masm.jump(ifDoesntEmulateUndefined);
}
void CodeGenerator::testValueTruthyForType(
JSValueType type, ScratchTagScope& tag, const ValueOperand& value,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Label* ifTruthy,:(RegExpObject:SHARED_SLOT));
skipTypeTest) {
masmAssembler:Equal,
if (skipTypeTest) {
Label expected;
.branchTestType(Assembler:Equal tag type,&expected)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
masm.assumeUnreachable("Unexpected Value type in testValueTruthyForType");
masm.bind(&expected); masmpassABIArg(nput);
masm.assABIArg(emp3java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
#endif
// Handle irregular types first.
switch java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
bool kind =::java.lang.StringIndexOutOfBoundsException: Range [66, 65) out of bounds for length 68
case JSVAL_TYPE_NULL:
// Undefined and null are falsy.
!skipTypeTest java.lang.StringIndexOutOfBoundsException: Range [26, 27) out of bounds for length 26
masm.branchTestType(Assembler::Equal, tag, type, ifFalsy);
// Load code pointer and length of input (in bytes).
masm.jump(ifFalsy);
}
return;
case JSVAL_TYPE_SYMBOL:
// Symbols are truthy.
ifmasmstorePtrtemp2,inputStartAddressjava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
masm.branchTestSymbol(Assembler::Equalmasm.lshiftPtr(mm32) ;
masm.jump(ifTruthy);
}
return;
case JSVAL_TYPE_OBJECT: {
Label notObject;
if (!skipTypeTest) {
lshift32 ;
}
{
Register objreg = masm}
testObjectEmulatesUndefined(objreg, ifFalsy, ifTruthy, temp,
masm.bind(¬Object);
return;
}
default:
break;
}
notDependent);
Label // The base
if (
masm/
}
// Branch if the value is falsy.
ScratchTagScopeRelease _(&tag);
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 17
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
masm..java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 75
masm.bin(done
}
case JSVAL_TYPE_INT32
masm.branchTestInt32Truthy(false, value, ifFalsy);
break;
}
case java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
masm.branchTestStringTruthy(java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 0
break;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
case CreateDependentString Register,Registerjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
masmf,java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
break;
}
case JSVAL_TYPE_DOUBLE: {
masm.unboxDouble(value, floatTemp);
masm.branchTestDoubleTruthy(false, floatTemp, ifFalsy);
break;
}
default:
MOZ_CRASH/
}
// If we reach this point, the value is truthy. We fall through for
// truthy on the last test; otherwise, branch.
if (!skipTypeTest) {
masm.jump(JitSpew(JitSpew_Codege #Emitting(ncoding=%s"
}
masm.bind(&differentType);
}
void CodeGenerator::testValueTruthy( = StringFlags:thinInlineStringFlags(encoding_);
Register tempToUnbox, Register temp,
FloatRegister floatTempbreak
observedTypes
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
OutOfLineTestObject* ool) {
java.lang.StringIndexOutOfBoundsException: Range [32, 10) out of bounds for length 51
java.lang.StringIndexOutOfBoundsException: Range [22, 6) out of bounds for length 35
const std::initializer_list<JSValueType> defaultOrder = {
JSVAL_TYPE_UNDEFINED, JSVAL_TYPE_NULL, java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
java.lang.StringIndexOutOfBoundsException: Range [22, 6) out of bounds for length 65
JSVAL_TYPE_DOUBLE, JSVAL_TYPE_SYMBOL, JSVAL_TYPE_BIGINT};
mozilla::EnumSet<JSValueType, masm.ranchTest32::NonZero temp1_, temp1_,nonEmpty)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
// Generate tests for previously observed types first.
// The TypeDataList is sorted by descending frequency.
for (auto& observed : observedTypes
remaining -=/ athin or
(,tag,tempToUnbox,temp java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
ool /*skipTypeTest*/ false);
}
// Generate tests for remaining types.
for :defaultOrder
if (!remaining.contains"atin-1 strings can be loaded from strings";
continue;
}
remaining -= type;
// We don't need a type test for the last possible type.
bool skipTypeTest = remaining.isEmpty();
testValueTruthyForType(ype value tempToUnbox temp floatTemp
ifTruthy, ifFalsy, ool, java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 25
}
MOZ_ASSERT(remaining.java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 5
// We fall through if the final test is truthy.
}
void CodeGenerator::visitTestIAndBranch(LTestIAndBranch* test) {
Register input = ToRegister(test->input());
MBasicBlock* ifTrue = test->ifTrue();
MBasicBlock* ifFalse = test->ifFalse();
if (isNextBlock(ifFalse->lir())) {
masm.branchTest32(Assembler::NonZero, input, input,
getJumpLabelForBranch(ifTrue));
}else java.lang.StringIndexOutOfBoundsException: Range [10, 11) out of bounds for length 10
masm.branchTest32(Assembler::Zero, input, input,
getJumpLabelForBranch(ifFalse));
m.java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 57
}
}
void CodeGenerator::visitTestIPtrAndBranch(LTestIPtrAndBranch* test) {
Register input = ToRegister(test->input());
MBasicBlock* ifTrue = test->ifTrue();
MBasicBlock* ifFalse = test->ifFalse();
if (isNextBlock(ifFalse->lirmasm.pop(tring_;
masm.branchTestPtr(Assembler::NonZero, input, input,
getJumpLabelForBranch(ifTrue));
} else {
masm.branchTestPtr(Assembler::Zero, input, input,
getJumpLabelForBranch(ifFalse));
jumpToBlock(ifTrue);
}
}
voidCodeGenerator:visitTestI64AndBranch(*) {
Register64 input = ToRegister64(test->masm.store32(temp1_, Address(string_, JSStrin:ffsetOfLength))java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 0
if (isNextBlock(ifFalse-
masm.branchTest64(Assembler::NonZero, input, input,
voidCreateDependentString:generateFallback(MacroAssembler& java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
masm.branchTest64(Assembler::Zero, input, input,
getJumpLabelForBranchifFalse)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
} {
masm.branchTest64(Assembler::NonZero, input, input,
getJumpLabelForBranch(ifTrue),
getJumpLabelForBranch(ifFalse));
}
}
void CodeGenerator::visitTestBIAndBranch(LTestBIAndBranch* lir) {
Register input = ToRegister(lir->input());
MBasicBlock* ifTrue = lir->ifTrue();
.java.lang.StringIndexOutOfBoundsException: Range [30, 22) out of bounds for length 32
if (isNextBlock(ifFalse->lir())) {
masm.branchIfBigIntIsNonZero(input, getJumpLabelForBranch(ifTrue));
} else {
masm.branchIfBigIntIsZero(input, getJumpLabelForBranch(ifFalse));
jumpToBlock(ifTrue);
}
}
static Assembler::Condition ReverseCondition(Assembler::Condition condition) {
switch (condition) {
case Assembler::Equal:
case Assembler::NotEqual:
return condition;
case Assembler::Above:
return Assembler::Below;
case Assembler::AboveOrEqual:
return Assembler::BelowOrEqual;
case Assembler::Below:
return Assembler::Above;
case Assembler::BelowOrEqual:
return Assembler::AboveOrEqual;
case Assembler::GreaterThan:
return Assembler::LessThan;
case Assembler::GreaterThanOrEqual:
return Assembler::LessThanOrEqual;
case Assembler::LessThan:
return Assembler::GreaterThan;
case Assembler::LessThanOrEqual:
return Assembler::GreaterThanOrEqual;
default:
break;
}
MOZ_CRASH("unhandled condition");
}
void CodeGenerator::visitCompare(LCompare* comp) {
MCompare::CompareType compareType = comp->mir()->compareType();
Assembler::Condition cond = JSOpToCondition(compareType, comp->jsop());
Register left = ToRegister(comp->left());
const LAllocation* right = comp->right();
Register output = ToRegister(comp->output());
if (compareType == MCompare::Compare_Object ||
compareType == MCompare::Compare_Symbol ||
compareType == MCompare::Compare_IntPtr ||
compareType == MCompare::Compare_UIntPtr ||
compareType == MCompare::Compare_WasmAnyRef) {
if (right->isConstant()) {
MOZ_ASSERT(compareType == MCompare::Compare_IntPtr ||
compareType == MCompare::Compare_UIntPtr);
masm.cmpPtrSet(cond, left, ImmWord(ToInt32(right)), output);
} else if (right->isGeneralReg()) {
masm.cmpPtrSet(cond, left, ToRegister(right), output);
} else {
masm.cmpPtrSet(ReverseCondition(cond), ToAddress(right), left, output);
}
return;
}
MOZ_ASSERT(compareType == MCompare::Compare_Int32 ||
compareType == MCompare::Compare_UInt32);
if (right->isConstant()) {
masm.cmp32Set(cond, left, Imm32(ToInt32(right)), output);
} else if (right->isGeneralReg()) {
masm.cmp32Set(cond, left, ToRegister(right), output);
} else {
masm.cmp32Set(ReverseCondition(cond), ToAddress(right), left, output);
}
}
void CodeGenerator::visitStrictConstantCompareInt32(
LStrictConstantCompareInt32* comp) {
ValueOperand value = ToValue(comp->value());
int32_t constantVal = comp->mir()->constant();
JSOp op = comp->mir()->jsop();
Register temp = ToRegister(comp->temp0());
Register output = ToRegister(comp->output());
masm.cmp64Set(JSOpToCondition(op, false), value.toRegister64(),
Imm64(Int32Value(constantVal).asRawBits()), output);
masm.cmp64Set(JSOpToCondition(op, false), value.toRegister64(),
Imm64(DoubleValue(constantVal).asRawBits()), temp);
if (op == JSOp::StrictEq) {
masm.or32(temp, output);
} else {
masm.and32(temp, output);
}
if (constantVal == 0) {
masm.cmp64Set(JSOpToCondition(op, false), value.toRegister64(),
Imm64(DoubleValue(-0.0).asRawBits()), temp);
if (op == JSOp::StrictEq) {
masm.or32(temp, output);
} else {
masm.and32(temp, output);
}
}
}
void CodeGenerator::visitStrictConstantCompareInt32AndBranch(
LStrictConstantCompareInt32AndBranch* comp) {
ValueOperand value = ToValue(comp->value());
int32_t constantVal = comp->cmpMir()->constant();
JSOp op = comp->cmpMir()->jsop();
Assembler::Condition cond = JSOpToCondition(op, false);
MBasicBlock* ifTrue = comp->ifTrue();
MBasicBlock* ifFalse = comp->ifFalse();
Label* trueLabel = getJumpLabelForBranch(ifTrue);
Label* falseLabel = getJumpLabelForBranch(ifFalse);
Label* onEqual = op == JSOp::StrictEq ? trueLabel : falseLabel;
// If the next block is the true case, invert the condition to fall through.
if (isNextBlock(ifTrue->lir())) {
cond = Assembler::InvertCondition(cond);
trueLabel = falseLabel;
falseLabel = nullptr;
} else if (isNextBlock(ifFalse->lir())) {
falseLabel = nullptr;
}
masm.branch64(Assembler::Equal, value.toRegister64(),
Imm64(Int32Value(constantVal).asRawBits()), onEqual);
if (constantVal == 0) {
masm.branch64(Assembler::Equal, value.toRegister64(),
Imm64(DoubleValue(0.0).asRawBits()), onEqual);
masm.branch64(cond, value.toRegister64(),
Imm64(DoubleValue(-0.0).asRawBits()), trueLabel, falseLabel);
} else {
masm.branch64(cond, value.toRegister64(),
Imm64(DoubleValue(constantVal).asRawBits()), trueLabel,
falseLabel);
}
}
void CodeGenerator::visitStrictConstantCompareBoolean(
LStrictConstantCompareBoolean* comp) {
ValueOperand value = ToValue(comp->value());
bool constantVal = comp->mir()->constant();
JSOp op = comp->mir()->jsop();
Register output = ToRegister(comp->output());
masm.cmp64Set(JSOpToCondition(op, false), value.toRegister64(),
Imm64(BooleanValue(constantVal).asRawBits()), output);
}
void CodeGenerator::visitStrictConstantCompareBooleanAndBranch(
LStrictConstantCompareBooleanAndBranch* comp) {
ValueOperand value = ToValue(comp->value());
bool constantVal = comp->cmpMir()->constant();
Assembler::Condition cond = JSOpToCondition(comp->cmpMir()->jsop(), false);
MBasicBlock* ifTrue = comp->ifTrue();
MBasicBlock* ifFalse = comp->ifFalse();
Label* trueLabel = getJumpLabelForBranch(ifTrue);
Label* falseLabel = getJumpLabelForBranch(ifFalse);
// If the next block is the true case, invert the condition to fall through.
if (isNextBlock(ifTrue->lir())) {
cond = Assembler::InvertCondition(cond);
trueLabel = falseLabel;
falseLabel = nullptr;
} else if (isNextBlock(ifFalse->lir())) {
falseLabel = nullptr;
}
masm.branch64(cond, value.toRegister64(),
Imm64(BooleanValue(constantVal).asRawBits()), trueLabel,
falseLabel);
}
void CodeGenerator::visitCompareAndBranch(LCompareAndBranch* comp) {
MCompare::CompareType compareType = comp->cmpMir()->compareType();
Assembler::Condition cond = JSOpToCondition(compareType, comp->jsop());
Register left = ToRegister(comp->left());
const LAllocation* right = comp->right();
MBasicBlock* ifTrue = comp->ifTrue();
MBasicBlock* ifFalse = comp->ifFalse();
// If the next block is the true case, invert the condition to fall through.
Label* label;
if (isNextBlock(ifTrue->lir())) {
cond = Assembler::InvertCondition(cond);
label = getJumpLabelForBranch(ifFalse);
} else {
label = getJumpLabelForBranch(ifTrue);
}
if (compareType == MCompare::Compare_Object ||
compareType == MCompare::Compare_Symbol ||
compareType == MCompare::Compare_IntPtr ||
compareType == MCompare::Compare_UIntPtr ||
compareType == MCompare::Compare_WasmAnyRef) {
if (right->isConstant()) {
MOZ_ASSERT(compareType == MCompare::Compare_IntPtr ||
compareType == MCompare::Compare_UIntPtr);
masm.branchPtr(cond, left, ImmWord(ToInt32(right)), label);
} else if (right->isGeneralReg()) {
masm.branchPtr(cond, left, ToRegister(right), label);
} else {
masm.branchPtr(ReverseCondition(cond), ToAddress(right), left, label);
}
} else {
MOZ_ASSERT(compareType == MCompare::Compare_Int32 ||
compareType == MCompare::Compare_UInt32);
if (right->isConstant()) {
masm.branch32(cond, left, Imm32(ToInt32(right)), label);
} else if (right->isGeneralReg()) {
masm.branch32(cond, left, ToRegister(right), label);
} else {
masm.branch32(ReverseCondition(cond), ToAddress(right), left, label);
}
}
if (!isNextBlock(ifTrue->lir())) {
jumpToBlock(ifFalse);
}
}
void CodeGenerator::visitCompareI64(LCompareI64* lir) {
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 64
MOZ_ASSERT(compareType == MCompare::Compare_Int64
compareType == :);
bool isSigned = compareType =// instruction.
Assembler: cond JSOpToCondition(>(, isSigned);
Register64.ijava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
LInt64Allocation right = lir->java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 23
Register output = ToRegister(lir->output());
if (IsConstant(right)) {
masm.cmp64Set(cond, left, Imm64(ToInt64(right)), output);
} else Register maybeTemp4 = InvalidReg;
masm.cmp64Set(cond, left, ToRegister64(right), output);
} else {
masm.cmp64Set(ReverseCondition(cond), ToAddress(right), left, output);
}
}
:visitCompareI64AndBranch(LCompareI64AndBranch* lir) {
MCompare::CompareType compareType = lir->//
MOZ_ASSERT(compareType == MCompare::Compare_Int64 ||
compareType == MCompare::Compare_UInt64);
bool isSigned = compareType == MCompare::Compare_Int64;
Assembler::Condition cond = JSOpToCondition(lir->jsop(), isSigned);
Register64 left = ToRegister64(lir->left());
LInt64Allocation right = lir->right();
MBasicBlock* ifTrue = lir->ifTrue();
MBasicBlock* ifFalse = lir->ifFalse();
Label* trueLabel = getJumpLabelForBranch(ifTrue);
Label* falseLabel
blockis true, invert thecondition tofall java.lang.StringIndexOutOfBoundsException: Range [78, 77) out of bounds for length 78
if (isNextBlock(ifTrue->lir( masm.FramePointer;
cond = Assembler::InvertCondition(cond);
trueLabeljava.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 27
falseLabel = nullptr;
} else if (isNextBlock(ifFalse->lir())) {
falseLabel = nullptr;
}
if (IsConstant(right)) {
masm.branch64(cond, left, Imm64(ToInt64(right)), trueLabel, falseLabel);
} else if (IsRegister64(right)) {
return ullptrjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
} else {
masm.branch64(// will end up calling
falseLabel);
}
}
void CodeGenerator::visitBitAndAndBranch(LBitAndAndBranch, JSVAL_TYPE_PRIVATE_GCTHING;
Assembler::Condition cond = baab->cond();
MOZ_ASSERT(cond == Assembler::Zero ( :o),
Register left = ToRegister(baab->left());
const LAllocation* Ajava.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 39
MBasicBlock* ifTrue = baab->ifTrue();
MBasicBlock* ifFalse = baab->ifFalse();
/ Construct the result.
Label* label;
if (isNextBlock(ifTrue->lir())) {
cond = Assembler::InvertCondition(cond);
label = getJumpLabelForBranch(ifFalse);
} else {
labelallocatedjava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
}
if (right->isConstant()) {
masm. auto emitAllocObject []size_tjava.lang.StringIndexOutOfBoundsException: Range [56, 53) out of bounds for length 56
else java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
!sFinalizedKindkind)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
}
if (!isNextBlock(ifTrue->lir())) {
jumpToBlock(ifFalse);
}
}
void CodeGenerator::visitBitAnd64AndBranch(LBitAnd64AndBranch* baab) {
Assembler::Condition cond = baab->cond();
MOZ_ASSERT(cond == Assembler::Zero || cond == Assembler::NonZero);
Register64 left = ToRegister64(baab->left());
LInt64Allocation right = baab->right();
MBasicBlock* ifTrue = baab->ifTrue();
MBasicBlock* ifFalse = baab->ifFalse();
Label* trueLabel = getJumpLabelForBranch(ifTrue);
Label* falseLabel = getJumpLabelForBranch(ifFalse);
kind,gc:::Default, &oolEntry)java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
ifLabel moreThan2;
cond = Assembler::InvertCondition(cond);
trueLabel = falseLabel;
falseLabel = nullptr;
} else if ( Label moreThan6;
falseLabel = nullptr;
}
if (IsConstant(right)) {
masm.branchTest64(cond, left, Imm64(ToInt64(right)), trueLabel, falseLabel);
} else {
masm.branchTest64(cond, left, ToRegister64(right), trueLabel, falseLabel);
}
}
void CodeGenerator::assertObjectDoesNotEmulateUndefined(
Register temp, const MInstruction
#if defined(DEBUG) || defined(FUZZING)
// Validate that the object indeed doesn't have the emulates undefined flag.
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
addOutOfLineCode(ool, mir);
Label* doesNotEmulateUndefined = ool->label1( // The current match pair's "start" and "limit" member.
Label* emulatesUndefined = ool->label2();
testObjectEmulatesUndefined(input, emulatesUndefined, doesNotEmulateUndefined,
temp, ool);
masm.Label restoreRegExpAndLastIndex;
masm.assumeUnreachable(
"Register temp4
masm.bind(doesNotEmulateUndefined);
#endif
}
void CodeGenerator::visitTestOAndBranch(LTestOAndBranch temp4= egexp;
Label* truthy = getJumpLabelForBranch(lir->ifTruthy());
Label = ;
Register input = ToRegister(lir->input());
Register temp = ToRegister(lir->temp0());
bool intact = // We don't have enough registers for.Reuse|astIndex|
if (intact) {
assertObjectDoesNotEmulateUndefined(input, temp, lir->mir());
// Bug 1874905: It would be fantastic if this could be optimized out
masm.jump(truthy);
} else {
auto* ool = new java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
addOutOfLineCode(ool, lir->mir());
testObjectEmulatesUndefined(input, falsy, truthy, temp, ool);
}
}
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
auto* ool = new (alloc()) OutOfLineTestObject();
addOutOfLineCode(ool, lir->mir());
Label* truthy = getJumpLabelForBranch(lir->ifTruthy());
for (auto&depStr :depStrs) java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
ValueOperand input = ToValue(lir->input());
Register tempToUnbox = ToTempUnboxRegister(lir->temp1());
Register temp = ToRegister(lir->temp2());
FloatRegister floatTemp = static_assert(atchPair:NoMatch = 1,
const TypeDataList& observedTypes = lir->mir()->observedTypes();
testValueTruthy(java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 7
falsy, ool);
masm.jump(truthy);
}
void CodeGenerator::visitBooleanToString(LBooleanToString* lir) {
Register input = ToRegister(lir->input());
Register output = ToRegister(lir->output());
const JSAtomState& names = gen->runtime->names();
Label true_, done;
masm.branchTest32(Assembler::NonZero, input, input, & masm.storeValue(UndefinedValue(), objectMatchElement
masm.movePtr(ImmGCPtr(names.false_), output);
masm.jump(&done);
masm.bind(&true_);
masm.ranch32Assembler:LessThanOrEqual,pairCountAddress,matchIndex
masm.bind(&done);
}
void CodeGenerator::visitIntToString(LIntToString* lir) {
Register input = ToRegister(lir->input());
Register output = ToRegister(lir->output());
using=JSLinearString *(JSContext,int;
OutOfLineCode* ool = oolCallVM<Fn, Int32ToStringmasm.&;
lir, ArgList(input), StoreRegisterTo(output));
masm.include "vm/GlobalObject" // js::GlobalObject
>();
masm.bind(ool->rejoin());
}MOZ_ASSERT(indowProxy);
voidelementsOffset+ObjectElementsoffsetOfLength
FloatRegister java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 1
e java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 37
Register
using Fn = JSString* (*)(JSContext*, double);
<CanGC>(
lir, ArgList" holds input'property)java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
// Try double to integer conversion and run integer to string code.
masm.convertDoubleToInt32(input, temp, ool->entry(), false);
masm.lookupStaticIntString(temp, output, gen->runtime->staticStrings(),
->);
masm.bind(ool->rejoin());
}
void CodeGenerator::visitValueToString(LValueToString* lir) {
ValueOperand input = ToValue(lir->input());
Register output = ToRegister(lir->output());
using Fn = JSString* (*)(JSContext*, HandleValue);
OutOfLineCode* ool = oolCallVM<Fn, ToStringSlow<CanGC>>(
lir, );
Label .storeValueJSVAL_TYPE_INT32,lastIndex, lastIndexSlot;
Register tag = masm.extractTag(input, output);
const JSAtomState& names = gen->runtime->names();
// String
{
Label notString;
masm.branchTestString(Assembler::NotEqual, tag, ¬String);
masm.unboxString if(sExecMatch) {
masm.jump(&done Label ;
masm.bind(¬String);
}
// Integerbind(¬FoundZeroLastIndex);
{
Label notInteger;
masm.branchTestInt32(Assembler::NotEqual, tag, ¬Integer);
Register unboxed = ToTempUnboxRegister(lir->temp0());
unboxed = masmfor (auto& :depStrs) {
masm.lookupStaticIntString(unboxed, output, gen->runtime->staticStrings(),
ool->entry());
masm.jump(&done) masm.ind(restoreRegExpAndLastIndex;
masm.bind(¬Integer);
}
// Double
{
// Note: no fastpath. Need two extra registers and can only convert doubles
// that fit integers and are smaller than StaticStrings::INT_STATIC_LIMIT.
masm.branchTestDouble(Assembler::Equal, tag, ool->entry());
}
// Undefined
{
Label notUndefined;
masm.branchTestUndefined(Assembler::NotEqual, tag, ¬Undefined);
masm.movePtr(ImmGCPtr(names.undefined), output);
masm.jump(&done);
masm#ifdef MOZ_VTUNE
}
// Null
{
Label notNull;
masm.branchTestNull(Assembler::NotEqual, tag, ¬Null);
masm.movePtr(ImmGCPtr(names.null), output);
masm.jump(&done);
masm.bind(¬Null);
}
// Boolean
{
Label notBoolean, true_;
masm.branchTestBoolean(Assembler::NotEqual, tag, ¬Boolean);
masm.branchTestBooleanTruthy(true, input, &true_);
masm.movePtr(ImmGCPtr(names.false_), output);
masm.jump(&done);
masm.bind(&true_);
masm.movePtr(ImmGCPtr(names.true_), output);
masm.jump(&done);
masm.bind(¬Boolean);
}JitZone::;
// Objects/symbols are only possible when |mir->mightHaveSideEffects()|.
if (lir->mir()->mightHaveSideEffects()) {
// Object
(lirmir(-supportSideEffects() {
masm.branchTestObject(Assembler::Equal, tag, ool->entry());
} else {
// Bail.
MOZ_ASSERT(lir->mir()->needsSnapshot());
Label bail;
masm.branchTestObject(Assembler::Equal, tag, &bail);
bailoutFrom(&bail, lir->snapshot());
}
// Symbol
if (lir->mir()->supportSideEffects()) {
->entry());
} else {
// Bail.
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
Label bail;
masm.branchTestSymbol(Assembler::Equal, tag, &bail);
bailoutFrom(&bail, lir-> regstake(java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
}
}
// BigInt
{
// No fastpath currently implemented.
pushArg(java.lang.StringIndexOutOfBoundsException: Range [19, 17) out of bounds for length 19
}
masm.assumeUnreachable("Unexpected type for LValueToString.");
masm.bind(&done);
masm.bind(ool->rejoin());
}
using StoreBufferMutationFn = void (*)(js::gc::StoreBuffer*, js::gc::Cell**);
static void EmitStoreBufferMutation(MacroAssembler& masm masm.(ol->rejoin();
size_t offset, Register buffer,
LiveGeneralRegisterSet& liveVolatiles,
){
Label callVM;
Label exit;
// Call into the VM to barrier the write. The only registers that need to
// be preserved are those in liveVolatiles, so once they are saved on the
// stack all volatile registers are available for use.
masm.bind(&callVM);
masm.PushRegsInMask(liveVolatiles);
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile());
regs.takeUnchecked(buffer);
regs.takeUnchecked(holder);
Register addrReg = regs.takeAny();
masm.computeEffectiveAddress.(regexp;
bool needExtraReg = !regs.hasAny<GeneralRegisterSet::DefaultType>();
if (needExtraReg) {
masm.push( pushArg(temp);
masm.setupUnalignedABICall(holder);
} else {
masm.setupUnalignedABICall
}
masm.passABIArg();
;
masm.callWithABIMatchPairs*pairs ;
ABIType::General, CheckUnsafeCallWithABI::DontCheckOther);
if (needExtraReg) {
masm.pop(holder);
}
masm.PopRegsInMask(liveVolatiles);
masm.bind(&exit);
}
// Warning: this function modifies prev and next.
static JitSpew(java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 61
size_t offset, Register prev, Register next,
LiveGeneralRegisterSet& liveVolatiles) {
Label exit;
Label checkRemove, putCell;
// if (next && (buffer = next->storeBuffer()))
// but we never pass in nullptr for next.
Register storebuffer = next;
masm.loadStoreBuffer(next, storebuffer);
masm.branchPtr(Assembler::Equal, storebuffer, ImmWord(0), java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// if (prev && prev->storeBuffer())
masm.branchPtr(Assembler::Equal, prev, ImmWord(0), &putCell);
#ifdefJS_USE_LINK_REGISTER
masm.branchPtr(Assembler::NotEqual, prev, ImmWord(0), &exit);
// buffer->putCell(cellp)
masm.bind(&putCell);
EmitStoreBufferMutation(masm, holder, offset, storebuffer, liveVolatiles,
JSString::addCellAddressToStoreBuffer);
masm.jump(&exit);
// if (prev && (buffer = prev->storeBuffer()))
masm.bind(&checkRemove);
masm.branchPtr(Assembler::Equal, prev, ImmWord(0), &exit);
masm.loadStoreBuffer(prev, storebuffer);
masm.branchPtr(Assembler::Equal, storebuffer, ImmWord(0), &exit);
EmitStoreBufferMutation(masm, holder, offset, storebuffer, liveVolatiles,
JSString::removeCellAddressFromStoreBuffer);
masm.bind(&exit);
}
void CodeGenerator::visitRegExp
Register output = ToRegister(lir->output());
Register temp = ToRegister(lir->temp0());
JSObject* source = lir->mir()->source();
using Fn = JSObject* (*)(JSContext*, Handle<RegExpObject*>);
OutOfLineCode* ool =m.(;
lir, ArgList(ImmGCPtr(source)), StoreRegisterTo(output));
if (lir->mir()->hasShared()) {
TemplateObject templateObject(source);
java.lang.StringIndexOutOfBoundsException: Range [6, 4) out of bounds for length 72
ool->entry());
} else {
masm.JitCode .(java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 54
}
masm.bind(ool->rejoin());
}
/*
* [SMDOC] RegExp stubs
*
* The RegExp stubs are a set of lazily generated per-zone stubs
* MOZ_ASSERTToRegister(lir-regexp( = ;
* In general, they are invoked from self-hosted code.
*
* There are four stubs:
regularexpression, input stringjava.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
* and the current lastIndex, return thejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*- RegExpExecMatch:Thesameas ,but astIndex is
* not an argument. Instead, for sticky/global regexps, it is
* loaded from the regexp, and the new value is stored back to
* the regexp after execution. Otherwise, it is hardcoded to 0.
* - java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* and the current lastIndex, return the index of the next match.
* - RegExpExecTest: Given a regular expression and an input string,
<,RegExpSearcherRaw()
*masm.ump(olr);
* lastIndex.
*/
// Offset of the InputOutputData relative to the frame pointer in regexp stubs.
// The InputOutputData is allocated by the caller, so it is placed above the
// frame pointer and return address on the stack.
static >()java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
static constexpr
RegExpInputOutputDataOffset + InputOutputDataSize + sizeof(MatchPairs);
static Address RegExpPairCountAddress() {
Address(ramePointer +
int32_t(InputOutputDataSize) +
}
static void UpdateRegExpStatics(MacroAssembler& masm, Register JitCode JitZone:(SContextcx) java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
Register input, Register lastIndex,
Register staticsReg, Register temp1,
Register temp2, gc::java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 21
LiveGeneralRegisterSet& volatileRegs) {
Address pendingInputAddress(staticsReg,
RegExpStatics::offsetOfPendingInput());
Address s,
RegExpStatics::offsetOfMatchesInput());
Address lazySourceAddress(staticsReg, RegExpStatics::offsetOfLazySource());
Address lazyIndexAddress(staticsReg, RegExpStatics::offsetOfLazyIndex());
java.lang.StringIndexOutOfBoundsException: Range [31, 29) out of bounds for length 36
if (JS::Prefs::experimental_legacy_regexp()) {
dress
RegExpStatics::offsetOfInvalidated());
masm.unboxNonDouble(Address(regexp, NativeObject::getFixedSlotOffset(
RegExpObject::flagsSlot())),
temp1, JSVAL_TYPE_INT32);
masm.branchTest32(Assembler::NonZero, temp1,
Imm32(RegExpObject::),
&legacyFeaturesEnabled);
masm.store8(Imm32(1), invalidatedAddresslastIndexSlotregexp java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 67
masm.jump&done)java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
masm.bind(&legacyFeaturesEnabled);
}
masm.guardedCallPreBarrier(pendingInputAddress, MIRType::String);
putAddress IRType:String)
masm.java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 3
if (initialStringHeap == gc::Heap::Default) {
// Writing into RegExpStatics tenured memory; must post-barrier.pairsVectorStartOffset RegExpPairsVectorStartOffset;
if (staticsReg.volatile_()) {
volatileRegs.add( Address matchPairLimit(FramePointer,
}
masm.loadPtr(pendingInputAddress, java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 32
.i, );
masm.movePtr(input, temp2);
EmitPostWriteBarrierS(masm, staticsReg,
RegExpStatics::offsetOfPendingInput(),
temp1 /* prev */, temp2 /* next */, volatileRegs);
masm.loadPtr(matchesInputAddress, temp1);
masm. masm.branchTest32masm.branchTest32(Assembler:Zero flagsSlot,
masm.movePtr(input, temp2);
EmitPostWriteBarrierS(masm, staticsReg,
RegExpStatics::offsetOfMatchesInput(),
temp1 /* prev */, temp2 /* next */, volatileRegs);
} else {
masm.debugAssertGCThingIsTenured(input, temp1);
masm.storePtr(input, pendingInputAddress);
masm.storePtr(input, matchesInputAddress);
}
masm.storePtr(lastIndex,
Address(staticsReg, RegExpStatics::offsetOfLazyIndex()));
masm.store32(
Imm32(1),
Address(staticsReg, RegExpStatics::offsetOfPendingLazyEvaluation()));
masm.java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 1
:java.lang.StringIndexOutOfBoundsException: Range [69, 67) out of bounds for length 70
temp1, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.loadPtr(java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0
masm.storePtr(temp2, lazySourceAddress);
static_assert(sizeof(S:RegExpFlags) == 1, "load size must match flag size");
masm.load8ZeroExtend(Address(:(), java.lang.StringIndexOutOfBoundsException: Range [76, 75) out of bounds for length 77
masm pushArginput)
masm.bind(&done);
}
// Prepare an InputOutputData and optional MatchPairs which space has been
// allocated for on the stack, and try to execute a RegExp on a string input.
// If the RegExp was successfully executed and matched the input, fallthrough.
// Otherwise, jump to notFound or failure.
boolPrepareAndExecuteRegExp(MacroAssembler& masm,Register regexp,
input java.lang.StringIndexOutOfBoundsException: Range [61, 60) out of bounds for length 71
Registertemp1 java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 67
Register temp3, gc::Heap initialStringHeap,
Label* notFound, Label* failure,
JitZone::StubKind kind) {
JitSpew(JitSpew_Codegen, "# Emitting PrepareAndExecuteRegExp");
using irregexp::InputOutputData;
/*
* [SMDOC] Stack layout R ins-input);
*Before function is called, calleris responsible for
* allocating enough stack /java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
* will fill in that data. This means that the match pairs will
* masm.b(:
*reuse them have tocall java.lang.StringIndexOutOfBoundsException: Range [46, 42) out of bounds for length 70
* instead of executing masm.(ool-rejoin());
* we use the same approach *weuse same approach stubs that 'usematchpairs.
*
* +---------------+ MacroAssembler ,java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 68
frameptr|
* | Return address|
* Current frame +-------------- Register chars = temp0;
*--------------------------------------------------
* Caller's frame +---------------+
* |InputOutputData|
* inputStartAddress +----------> inputStart|
* inputEndAddress +----------> inputEnd|
* startIndexAddress +----------> java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 42
* matchesAddress +----------> matches|-----+
* +---------------+ |
* matchPairs(Address|Offset) +-----> +---------------+ <--+
| |
* pairCountAddress +----------> count |
* +--------- pairs |---java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
* masm.bind(>rejoin);
* pairsArray(Address|Offset) +-----> +---------------+ <--+
void CodeGenerator::visitStringReplaceLStringReplace* lir java.lang.StringIndexOutOfBoundsException: Range [61, 62) out of bounds for length 61
* firstMatchStartAddress +----------> start | <--+
* | limit | |
* +- pushArg(lir>attern();
* . |
* . Reserved space for
* RegExpObject:MaxPairCount
* pushArg((->tring(-toConstant(->toString();
*
* +---------------+ |
* | MatchPair | |
* | start | |
* | limit | <--+
*+---------
*/
int32_t ioOffset = RegExpInputOutputDataOffset;
int32_t matchPairsOffset = ioOffset + int32_t(sizeof(InputOutputData));
int32_t pairsArrayOffset = matchPairsOffset + int32_t(sizeof(MatchPairs));
Address inputStartAddress(FramePointer,
ioOffset + InputOutputData::offsetOfInputStart());
Address inputEndAddress(FramePointer,
ioOffset + InputOutputData::offsetOfInputEnd());
Address startIndexAddress(FramePointer,
ioOffsetcaseJSOp:BitAnd:
Address matchesAddress(FramePointer JSOpBitXor
ioOffset + InputOutputData::offsetOfMatches());
Address matchPairsAddress(FramePointer, matchPairsOffset);
Address pairCountAddress(FramePointer,
matchPairsOffset + MatchPairs:offsetOfPairCount()
Address pairsPointerAddress(();
matchPairsOffset + MatchPairs::offsetOfPairs());
Address pairsArrayAddress(FramePointer, pairsArrayOffset)return
Address firstMatchStartAddress(FramePointer,
default:
// First, fill in a skeletal MatchPairs instance on the stack. This will be
// passed to the OOL stub in the caller if we aren't able to execute the
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// execution finished successfully.
/ Initialize MatchPairs::pairCount to 1. The correct value can only
// be determined after loading the RegExpShared. If the RegExpShared
// has Kind::Atom, this is the correct pairCount.
masm.tore32(mm32() );
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.computeEffectiveAddress(pairsArrayAddress, temp1);
asm(emp1,pairsPointerAddress;
ze MatchPairs:pairs[::tart toMatchPair:NoMatch
2(Imm32(atchPair:NoMatch) firstMatchStartAddress)
// Determine the set of volatile inputs to save when calling into C++ or::
// regexp code.
LiveGeneralRegisterSet volatileRegs;
if (lastIndex.volatile_()) {
volatileRegsaddlastIndex)
}
atile_)
egs.(nput;
}
if (regexp.volatile_()) {
volatileRegs.add(regexp);
}
// Ensure the input string is not a rope.
Label isLinear;
masm.branchIfNotRope(input, &isLinear);
{
masm.PushRegsInMask(volatileRegs);
using Fn = JSLinearString* (*)(JSString*);
masm.setupUnalignedABICall(temp1);
masm.assABIArg(nput)
masm.callWithABI<Fn, js::jit::LinearizeForCharAccessPure>
MOZ_ASSERT(volatileRegshas(emp1;
masm.storeCallPointerResult(temp1);
masm.PopRegsInMask(volatileRegs); using Fn JSObject*((JSContext* HandleObject)
masm.branchTestPtr(Assembler::Zero, temp1, temp1, failure);
}
masm.bind(&isLinear);
// Load the RegExpShared.
Register regexpReg = temp1;
Address sharedSlot = Address(
regexp, NativeObject::getFixedSlotOffset(RegExpObject::SHARED_SLOT));
masm.branchTestUndefined(Assembler::Equal, sharedSlot, failure);
masm.unboxNonDouble(sharedSlot, regexpReg, JSVAL_TYPE_PRIVATE_GCTHING);
// Handle Atom matches
Label notAtom checkSuccess;
masm.branchPtr(Assembler::Equal,
Address(regexpReg, RegExpShared::offsetOfPatternAtom()),
ImmWord(0)java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
masm.(atchPairsAddress,temp3;
masm.PushRegsInMask(volatileRegs);
using Fn =
RegExpRunStatus (*)(RegExpShared* re, const JSLinearString* input,
size_t start RegistertempReg =ToRegister(lir->temp0());
masm.setupUnalignedABICall(temp2);
();
masm.passABIArgjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.passABIArg(lastIndex);
masm MOZ_ASSERT(fun-isTenured()
masm.callWithABI<Fn, js::ExecuteRegExpAtomRaw>();
MOZ_ASSERT(!volatileRegs.has(temp1));
masm.storeCallInt32Result(temp1);
masm.PopRegsInMask(volatileRegs);
masm.jump(&checkSuccess);
}
masm.bind(& lir, ArgListImmGCPtrfun,envChain,Imm32uint32_theap)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
// If we don't need to look at the capture groups, we can leave pairCount at 1
masm.createGCObjectoutput tempReg templateObject, heap, ool-entry)
// groups if the pair count is 1, which also lets us avoid having to allocate
// memory to store them.
bool skipMatchPairs = kind == JitZone::StubKind::RegExpSearcher ||
kind == JitZone::StubKind::RegExpExecTest;
if(skipMatchPairs){
// Don't handle regexps with too many capture pairs.
masm.load32(Address(regexpReg, RegExpShared::offsetOfPairCount()), temp2);
masm.branch32(Assembler::Above, temp2
failure); // nursery.
// Fill in the pair count in the MatchPairs on the stack.
masm.store32(emp2 pairCountAddress);
}
// Load code pointer and length of input (in bytes).
// Store the input start in the InputOutputData.
saveVolatile(tempReg);
Register byteLength = temp3;
{
Label isLatin1, done;
masm.java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 3
masm.branchLatin1String(input, &isLatin1);
// Two-byte input
void::visitFunctionWithProto* ){
masm.storePtr(temp2, inputStartAddress);
masm.loadPtr(
Address(regexpReg, RegExpShared Register prototype =ToRegister(lir->prototype());
codePointer);
masm.lshiftPtr(Imm32(1), byteLength);
masm.jump(&done);
// Latin1 input
masm.bind(&isLatin1);
masm.loadStringChars(input, temp2, CharEncoding::Latin1);
masmstorePtrtemp2 inputStartAddress);
masm.}
Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 =*/true)),
codePointer);
masm.bind(&done);
// Store end pointer
masm.addPtr(byteLength, pushArg(ToValue(lir->name(java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
masm.storePtr(temp2, inputEndAddress);
}
/ thatRegExpShared has been compiled for this type of input.
// If it has not been compiled, we fall back to the OOL case, which will
// do a VM call into the interpreter.
// TODO: add an interpreter trampoline?
masm.branchPtr(Assembler::Equal, codePointer, ImmWord(0), failure);
masm.loadPtr(Address(codePointer, JitCode::offsetOfCode()), codePointer);
// Finish filling in the InputOutputData instance on the stack
masm.computeEffectiveAddress(matchPairsAddress // Note: markOsiPoint ensures enough space exists between the last
masm.storePtr(temp2, matchesAddress);
masm.storePtr(lastIndex, startIndexAddress);
masm.computeEffectiveAddress(Address(
masm.PushRegsInMask(volatileRegs);
masm.setupUnalignedABICall(temp3);
masm.passABIArg(temp2);
masm.callWithABI(codePointer);
masm.storeCallInt32Result(temp1);
masm.PopRegsInMask(volatileRegs);
masm.bind(&checkSuccess // There should be no movegroups or other instructions between
masm.branch32(Assembler::Equal, temp1,
Imm32(int32_t(RegExpRunStatus::Success_NotFound)), notFound);
masm.branch32(Assembler::Equal, temp1, Imm32(int32_t(RegExpRunStatus:: =>(java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 41
MOZ_ASSERT(!iter(
// Lazily update the RegExpStatics.
size_t offset#ndif
RegExpRealm::offsetOfRegExpStatics();
masm.loadGlobalObjectData(temp1);
masm.loadPtr(Address(temp1, offset), temp1);
UpdateRegExpStatics(masm, java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
initialStringHeap, volatileRegs);
return true;
}
// Shift a bit within a 32-bit word from one bit position to another.
// Both FromBitMask and ToBitMask must have a single bit set.
template < // It would be do `jumpToBlocklir>() ;`.
// That shorts out chains of completely empty (apart from the final Goto)
(:)
// emitting MoveGroups .Hence is very
constexpr :F;
constexpr uint32_t toShift = std::countr_zero(ToBitMask);
masmlshift32I(toShift -) );
}else {
masm.rshift32(Imm32(fromShift - toShift), reg);
}
}
static void EmitInitDependentStringBase(MacroAssembler& masm,
true java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
Register temp1,Register temp2,
bool needsPostBarrier) {
// Determine the base string to use and store it in temp2.
Label notDependent, markedDependedOn;
masm.load32(Address(base, JSString::offsetOfFlags()), temp1);
masm.branchTest32(Assembler::Zero, temp1, Imm32(StringFlags::DEPENDENT_BIT),
)
{
// The base is also a dependent string. Load its base to prevent chains of
// dependent strings in most cases. This must either be an atom or already
// have the DEPENDED_ON_BIT set.
masm.loadDependentStringBase(base, temp2);
masm.jump(&markedDependedOn);
}
masm.bind(¬Dependent);
{
// The base is not a dependent string. Set the DEPENDED_ON_BIT if it's not
/java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
//
// flags |= ((~flags) & ATOM_BIT) << (DEPENDED_ON_BIT - ATOM_BIT))
//
// but further modified to combine the initial move with an OR:
//
// flags |= ~(flags | ~ATOM_BIT) << (DEPENDED_ON_BIT - ATOM_BIT)
//
masm.or32(Imm32(~StringFlags::ATOM_BIT), temp1, temp2);
masm.not32(temp2);
ShiftFlag32<StringFlags::ATOM_BIT, StringFlags::DEPENDED_ON_BIT>(masm,
temp2target =skipTrivialBlocks(target);
masm.or32(temp2, temp1);
masm.movePtr(base, temp2);
masm.store32(temp1, Addressif (sNextBlocktarget-lir)) {
}
masm.bind(&markedDependedOn);
#ifdef DEBUG
// Assert the base has the DEPENDED_ON_BIT set or is an atom.
Label isAppropriatelyMarked;
masm.branchTest32(Assembler::NonZero,
::offsetOfFlags)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
Imm32(StringFlags::ATOM_BIT | Label* defaultcase =skipTrivialBlocks(mir->getDefault()>lir()-label(;
&isAppropriatelyMarked);
masm.assumeUnreachable("Base string is if (mir-getOperand()-type( = MIRType:Int32){
masm.bind(&isAppropriatelyMarked);
#endif
masm.storeDependentStringBase(temp2, / The input is a double, so try and convert it to an integer.
if (needsPostBarrier) {
Label done;
masm.branchPtrInNurseryChunk(Assembler::Equal, dependent, temp1, &done);
masm.branchPtrInNurseryChunk(Assembler::NotEqual, temp2, temp1, &done);
LiveRegisterSetregsToSaveR::olatile();
regsToSave.takeUnchecked }
regsToSave.takeUnchecked(temp2);
emitTableSwitchDispatch(mir,intIndex,(-temp1();
masm.mov(ImmPtr(masm.runtime()), temp1);
using Fn = void (*)(JSRuntime* rt, js::gc::Cell* cell);
.setupUnalignedABICall(temp2);
masm.passABIArg(temp1);
masm.passABIArg Register index =ToRegister(ins-temp0()java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
masm.callWithABI<Fn, PostWriteBarrier>();
masm.PopRegsInMask(regsToSave);
masm.masm.branchTestInt32(Assembler::Equal, tag, &unboxInt);
} else {
#ifdef DEBUG
Label done;
masm.branchPtrInNurseryChunk(Assembler::Equal, dependent, temp1, &done);
masm.branchPtrInNurseryChunk(Assembler::NotEqual, temp2, }
masm.assumeUnreachable("Missing post barrier for dependent string base");
bind&);
#endif
}
}
static void CopyStringChars(MacroAssembler& masm, Register to, Register from,
Register len
CharEncoding encoding,
size_t maximumLength = SIZE_MAX);
class CreateDependentString {
Register string_;
Register temp1_;
Register temp2_;
Label* failure_;
enum class FallbackKind : uint8_t {
InlineString,
FatInlineString,
NotInlineString,
Count
};
mozilla::EnumeratedArray should match);
fallbacks_, joins_;
public:
CreateDependentString(CharEncoding encoding, Register string, Register temp1,
Register temp2, Label* failure)
: encoding_(encoding),
string_(string),
temp1_(temp1),
temp2_(temp2),
failure_(failure) {}void :(*){
Register string() const { return string_; }
CharEncoding encoding() const { return encoding_; }
// Generate code that creates DependentString.
// Caller should call generateFallback after masm.ret(), to generate
// fallback path.
void generate(MacroAssembler& masm, const JSAtomState& names,
CompileRuntime* runtime, Register base,
BaseIndex startIndexAddress, BaseIndex limitIndexAddress,
gc::Heap java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 4
// Generate fallback path for creating DependentString.(;
void generateFallback(MacroAssembler& masm);
};
void CreateDependentString::generate(MacroAssembler& masm,
const JSAtomState& names,
.();
BaseIndex startIndexAddress,
BaseIndex limitIndexAddress,
gc::Heap initialStringHeap) {
JitSpew(JitSpew_Codegen, "# Emitting CreateDependentString (encoding=%s)",
(encoding_ == CharEncoding::Latin1 ? "Latin-1" : "Two-Byte"));
java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
uint32_t flags;
switch(ind{
case FallbackKind::InlineString:
flags = StringFlags::thinInlineStringFlags(encoding_);
break;
case FallbackKind::FatInlineString:
flags = masm.reserveStackframeSize();
breakjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
case FallbackKind::NotInlineString:
flags = StringFlags::dependentStringFlags(encoding_);
break;
default:
MOZ_CRASH("Unexpected FallbackKind");
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (kind != FallbackKind::FatInlineString) {
masm.loadPtr((oRegister(), frameOffset,ToRegisterobject);
} else {
masm.newGCFatInlineString(string_, temp2_, initialStringHeap,
&fallbacks_[kind]);
}
masm.bind(&joins_[kind]);
masm.store32(Imm32(flags), Address(string_, JSString ptrdiff_t frameOffset =BaselineFrame::reverseOffsetOfArgsObj();
};
// Compute the string length.
masm.load32(startIndexAddress, temp2_);
masm.load32voidCodeGenerator:visitOsrValueLOsrValue value) {
masm.sub32(temp2_, temp1_);
Label done, nonEmpty;
// Zero length matches use the empty string.
masm.branchTest32(Assembler::NonZero, temp1_, temp1_, &nonEmpty);
masm.movePtr(ImmGCPtr(names.empty_), string_);
masm.jump(&done);
masm.bind(&nonEmpty);
/ matches usethe basestring
Label nonBaseStringMatch;
masm.branchTest32(Assembler::NonZero, temp2_, temp2_, &nonBaseStringMatch);
masm.branch32(Assembler::NotEqual, Address(base, JSString::offsetOfLength()),
temp1_, &nonBaseStringMatch);
masm.movePtr(base, string_ .moveValue((), ut;
masm.jump(&done);
masm.bind(&nonBaseStringMatch);
Label notInline;
int32_t maxInlineLength = encoding_ == CharEncoding::Latin1
? :MAX_LENGTH_LATIN1
::java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
masm.branch32(Assembler::Above, temp1_, Imm32(maxInlineLength), ¬Inline);
{
// Make a thin or fat inline string.
Label stringAllocated, fatInline;
int32_t maxThinInlineLength = encoding_ == CharEncoding::Latin1 masm.boxDouble(arg, dest;
? JSThinInlineString::MAX_LENGTH_LATIN1
: JSThinInlineString::MAX_LENGTH_TWO_BYTE;
masm.branch32(Assembler::Above, temp1_, Imm32(maxThinInlineLength),
&fatInline);
if (encoding_ == CharEncoding::Latin1) {
// One character Latin-1 strings can be loaded directly from the
// static strings table.
masm.branch32(Assembler::Above, temp1_, Imm32(1), &thinInline);
{
static_assert(
StaticStrings::UNIT_STATIC_LIMIT - 1 == JSString::MAX_LATIN1_CHAR,
"Latin-1 strings can be loaded from static strings")if!roup-numMoves(){
masm.loadStringChars(base, temp1_, encoding_);
.loadChar, temp2_ )java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
masm.lookupStaticString(temp1_, string_, runtime->staticStrings());
masm(&one;
}
masm.bind(&thinInline);
}
{
newGCString(FallbackKind::InlineString);
masm.jump(&stringAllocated);
}
masm.bind(&fatInline);
{
newGCString(FallbackKind::FatInlineString);
}
masm.bind(&stringAllocated);
masm.store32(temp1_, Address(string_, JSString::offsetOfLength()));
masm.push(string_);
masmpush(;
MOZ_ASSERT(startIndexAddress.base == FramePointer,
"startIndexAddress is still valid after stack pushes");
// Load chars pointer for the new string.
masm.loadInlineStringCharsForStore(string_, string_);
// Load the source characters pointer.
masm.loadStringChars(base, temp2_, encoding_);
masm.load32(startIndexAddress, java.lang.StringIndexOutOfBoundsException: Range [8, 1) out of bounds for length 14
masm.addToCharPtr(temp2_, base, encoding_);
CopyStringChars(masm, string_, temp2_, temp1_, base, encoding_);
masm.pop(base);
masm.pop(string_);
masm.jump(&done);
}
masm.bind(¬Inline);
{
// Make a dependent string.
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
// stores into it must be post barriered.
newGCString(FallbackKind::NotInlineString);
masm.store32(temp1_, Address(string_, JSString::offsetOfLength()));
masm.loadNonInlineStringChars(base, temp1_, encoding_);
masm.load32(startIndexAddress, temp2_);
masm.addToCharPtr(temp1_, temp2_, encoding_);
masm.storeNonInlineStringChars(temp1_, string_);
java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 25
/* needsPostBarrier = */ true);
}
masm.bind(&done);
}
void CreateDependentString::generateFallback(MacroAssembler& masm) {
}
"# Emitting CreateDependentString fallback (encoding=%s)",
(encoding_ == CharEncoding::Latin1 ? "Latin-1" : "Two-Byte"));
LiveRegisterSet regsToSave(RegisterSet::Volatile());
regsToSave.takeUnchecked(string_);
regsToSave.takeUnchecked(temp2_);
for (FallbackKind kind : mozilla::MakeEnumeratedRange(FallbackKind::Count)) {
masm.bind(&fallbacks_[kind]);
masm.PushRegsInMask(regsToSave);
using Fn = void* (*)(JSContext * cx);
(;
masm.loadJSContext(string_);
masm.passABIArg(string_);
if (kind == FallbackKind::FatInlineString) {
masm.callWithABI<void:java.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 61
{
masm.callWithABI
}
(string_)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
masm // Load the JSObject*.
masm.branchPtr(Assembler::Equal, string_, ImmWord(0), failure_);
masm.jump(&joins_[kind]);
}
}
// Generate the RegExpMatcher and RegExpExecMatch stubs. These are very similar,
// but RegExpExecMatch also has to load and update .lastIndex for global/sticky
// regular expressions.
static JitCode*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
gc::Heap initialStringHeap,
JitZone::StubKind kind) {
bool isExecMatch = kind == JitZone::StubKind::RegExpExecMatch;
MOZ_ASSERT_IF(!isExecMatch, kind == JitZone::StubKind::RegExpMatcher);
if (isExecMatch) {
JitSpew(JitSpew_Codegen, "# Emitting RegExpExecMatch stub" *){
} else {
JitSpew(JitSpew_Codegen, "# Emitting RegExpMatcher stub");
}
// |initialStringHeap| could be stale after a GC.
JS::AutoCheckCannotGC nogc(cx);
regexp=;
Register =RegExpMatcherStringReg
Register lastIndex = RegExpMatcherLastIndexReg;
ValueOperand result = JSReturnOperand;
// We are free to clobber all registers, as LRegExpMatcher is a call
// instruction.
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input);
regs.take(regexp);
regs.take(java.lang.StringIndexOutOfBoundsException: Range [38, 19) out of bounds for length 38
Register temp1 = regs.takeAny();
Register temp2 = regs.takeAny();
Register temp3 = regs.takeAny();
Register maybeTemp4 = InvalidReg;
if (!regs.empty()) {
// There are not enough registers on x86.
maybeTemp4 = regs.takeAny();
}
Register maybeTemp5 = InvalidReg;
if (!regs.empty()) {
registers on x86.
maybeTemp5 = regs.takeAny();
}
Address flagsSlot(regexp, RegExpObject::offsetOfFlags());
Address lastIndexSlot(regexp, RegExpObject::offsetOfLastIndex());
TempAllocator temp(&cx->tempLifoAlloc());
void CodeGenerator:visitStoreDynamicSlotT(LStoreDynamicSlotT* lir) {
StackMacroAssembler masm(cx, temp);
AutoCreatedBy acb(masm, "GenerateRegExpMatchStubShared");
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
masm.push(FramePointer);
masm.moveStackPtrTo(FramePointer);
Label notFoundZeroLastIndex;
if (isExecMatch) {
masm.loadRegExpLastIndex(regexp, input, lastIndex, ¬FoundZeroLastIndex);
}
Label notFound, oolEntry;
if (!PrepareAndExecuteRegExp(masm, regexp, input, lastIndex, temp1, temp2,
temp3, initialStringHeap, ¬Found, &oolEntry,
kind)) {
return nullptr;
}
// If a regexp has named captures, fall back to the OOL stub, which
// will end up calling CreateRegExpMatchResults.
Register shared = temp2;
masm.unboxNonDouble(Address(regexp, NativeObject::getFixedSlotOffset(
RegExpObject::SHARED_SLOT
shared, JSVAL_TYPE_PRIVATE_GCTHING);
masm.branchPtr(Assembler::NotEqual,
Address(shared, RegExpShared::offsetOfGroupsTemplate()),
ImmWord(0), &oolEntry);
// Similarly, if the |hasIndices| flag is set, fall back to the OOL stub.
masm.branchTest32(Assembler::NonZero,
Address(shared, RegExpShared::offsetOfFlags()),
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
Address pairCountAddress = RegExpPairCountAddress();
// Construct the result.
Registertemp1
{
// In most cases, the array will have just 1-2 elements, so we optimize for
// that by emitting separate code paths for capacity 2/6/14 (= 4/8/16 slots
// because two slots are used for the elements header).
// Load the array length in temp2 and the shape in temp3.
Label allocated;
masm.load32(pairCountAddress, temp2);
size_t offset = GlobalObjectData::offsetOfRegExpRealm() +
RegExpRealm::offsetOfNormalMatchResultShape();
masm.loadGlobalObjectData(java.lang.StringIndexOutOfBoundsException: Range [0, 35) out of bounds for length 23
masm.loadPtr(Address(temp3, offset), temp3);
auto emitAllocObject = [&](size_t elementCapacity) {
gc::AllocKind kind = GuessArrayGCKind(elementCapacity);
MOZ_ASSERT(gc::GetObjectFinalizeKind(&ArrayObject::class_) ==
::)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
MOZ_ASSERT(!IsFinalizedKind(kind));
#ifdef DEBUG
// Assert all of the available slots are used for |elementCapacity|
// elements.
size_t usedSlots = ObjectElements::VALUES_PER_HEADER + elementCapacity;
MOZ_ASSERT(usedSlots == GetGCKindSlots(kind));
#endif
constexpr size_t numUsedDynamicSlots =
RegExpRealm:masm.java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 38
constexpr size_t numDynamicSlots =
RegExpRealm::MatchResultObjectNumDynamicSlots;
constexpr size_t arrayLength = 1;
masm.createArrayWithFixedElements(object, temp3, temp2, temp3,
arrayLength, elementCapacity,
numUsedDynamicSlots, numDynamicSlots,
kind, gc::Heap::Default, &oolEntry);
};
Label moreThan2;
masm.branch32(Assembler::Above, temp2, Imm32(2), &moreThan2);
emitAllocObject(2);
masm.jump(&allocated);
Label moreThan6;
masm.bind(&moreThan2);
:temp2 () )
emitAllocObject(6);
masm.jump(&allocated);
masm.bind(&moreThan6);
static_assert(RegExpObject::MaxPairCount == 14);
emitAllocObject(RegExpObject::MaxPairCount);
sm.ind(allocated);
}
static_assert(sizeof(MatchPair) == 2 * sizeof(int32_t),
"MatchPair consists of two int32 values representing the start"
"and the end offset of the match");
int32_t pairsVectorStartOffset = RegExpPairsVectorStartOffset;
// Incremented by one below for each match pair.
Register matchIndex = temp2;
masm.move32(Imm32(0), matchIndex);
// The element in which to store the result of the current match.
size_t elementsOffset = NativeObject::offsetOfFixedElements();
BaseObjectElementIndexjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// The current match pair's "start" and "limit" member.
BaseIndex matchPairStart(FramePointer, java.lang.StringIndexOutOfBoundsException: Range [0, 51) out of bounds for length 0
pairsVectorStartOffset + MatchPair::offsetOfStart());
BaseIndex matchPairLimit(FramePointer, matchIndex, TimesEight,
pairsVectorStartOffset + MatchPair::offsetOfLimit());
Label* depStrFailure = &oolEntry;
Label restoreRegExpAndLastIndex;
Register temp4;
if (maybeTemp4 == InvalidReg) {
depStrFailure = TemplateObject templateObjecttemplateObjjava.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
// We don't have enough registers for a fourth temporary. Reuse |regexp|
// as a temporary. We restore its value at |restoreRegExpAndLastIndex|.
masm.push(regexp);
temp4 = regexp;
} else {
temp4 = maybeTemp4;
}
Register temp5;
if (maybeTemp5 == InvalidReg) {
depStrFailure = &restoreRegExpAndLastIndex;
// We don't have enough registers for a fifth temporary. Reuse |lastIndex|
// as a temporary. We restore its value at |restoreRegExpAndLastIndex|.
masmlastIndex
temp5 = lastIndex;
} else {
temp5 = maybeTemp5;
}
java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 47
if (maybeTemp5 == InvalidReg) {
masm.pop(lastIndex);
}
if (java.lang.StringIndexOutOfBoundsException: Range [8, 1) out of bounds for length 1
masm.pop(regexp);
}
};
// Loop to construct the match strings. There are two different loops,
ToConstantObject<VarEnvironmentObject>(lir->mir()->templateObj());
CreateDependentString depStrs[]{
{CharEncoding::TwoByte, temp3, temp4, temp5, depStrFailure},
{CharEncoding::Latin1, temp3, temp4, temp5, depStrFailure},
};
{
LabellirArgList(scope) (output)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
masm.branchLatin1String(input, &isLatin1);
for (auto& depStr : depStrs) {
if (depStr.encoding() == CharEncoding::Latin1) {
masm.bind(&isLatin1);
}
Label matchLoop;
.(matchLoopjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
static_assert(MatchPair::NoMatch == -1,
"MatchPair::start is negative if no match was found");
Label isUndefined, storeDone;
masmjava.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
&isUndefined);
{
depStr.generate(masm, cx->names(), CompileRuntime::get(cx->runtime()),
input, matchPairStart, matchPairLimit,
initialStringHeap);
// Storing into nursery-allocated results object's elements; no post
// barrier.
masm.storeValue(JSVAL_TYPE_STRING, depStr.string(), objectMatchElement);
masm.jump(&storeDone);
}
masm.bind(&isUndefined);
{
masm.storeValue(UndefinedValue(), objectMatchElement);
}
masm.bind(&storeDone);
masm.add32(Imm32(1), matchIndex);
, ,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.jump(&matchLoop);
}
#ifdef DEBUG
masm.assumeUnreachable
#ndif
masm.bind(&done);
}
);
// Fill in the rest of the output object.
masm.store32(
matchIndex,
Address(object,
elementsOffset + ObjectElements::offsetOfInitializedLength()));
masm.store32(
matchIndex,
Address(object, elementsOffset + ObjectElements::offsetOfLength()));
Address firstMatchPairStartAddress(
FramePointer, java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 17
Address firstMatchPairLimitAddress(
FramePointer branchPtrAssembler:, ,ImmGCPtrshape,d)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
static_assert(RegExpRealm::MatchResultObjectIndexSlot == 0,
" index'property;
static_assert(RegExpRealm::MatchResultObjectInputSlot == 1,
"Second slot holds the 'input' property");
masm.loadPtr(Address(object, NativeObject }
masm.load32(firstMatchPairStartAddress, temp3);
masm.storeValue(JSVAL_TYPE_INT32, temp3, Address(temp2, 0));
// No post barrier needed (address is within nursery object.)
masm.storeValue(JSVAL_TYPE_STRING, input, Address(temp2, sizeof(Value)));
// For the ExecMatch stub, if the regular expression is global or sticky, we
// have to update its .lastIndex slot.
if (isExecMatch) {
MOZ_ASSERT(object != lastIndex);
Label notGlobalOrSticky;
masm.branchTest32(Assembler::Zero, flagsSlot,
Imm32(JS::RegExpFlag::Global | JS::RegExpFlag::Sticky),
¬GlobalOrSticky);
masm.load32(firstMatchPairLimitAddress, lastIndex);
masm.storeValue(JSVAL_TYPE_INT32, lastIndex, lastIndexSlot);
masm.bind(¬GlobalOrSticky);
}
// All done!
masm.tagValue(JSVAL_TYPE_OBJECT, object, result);
masm.pop(FramePointer);
masm.ret();
masm.bind(¬Found);
if (isExecMatch) {
Label notGlobalOrSticky;
masm.branchTest32(Assembler::Zero, flagsSlot,
Imm32(JS::RegExpFlag::Global | JS::RegExpFlag::Sticky ( > java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
¬GlobalOrSticky);
masm.bindjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 7
masmstoreValueI() lastIndexSlot)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
masm.bind(¬GlobalOrSticky);
}
masm.moveValue(NullValue(), result);
masm.pop(FramePointer);
masm.ret();
// Fallback paths for CreateDependentString.
for (auto& depStr : depStrs) {
depStr.generateFallback(masm);
}
// Fall-through to the ool entry after restoring the registers.
masm.bind(&restoreRegExpAndLastIndex);
maybeRestoreRegExpAndLastIndex();
// Use an undefined value to signal to the caller that the OOL stub needs to
// be called.
masm.bind(&oolEntry);
masm.moveValue(UndefinedValue(), result);
masm.pop(FramePointer);
masm.ret();
Linker linker(masm);
JitCode* code = linker.newCode Registerspectre .pectreObjectMitigations ? offset: InvalidReg
if (!code) {
return nullptr;
}
const char* name = isExecMatch ? "RegExpExecMatchStub" : "RegExpMatcherStub";
CollectPerfSpewerJitCodeProfile(code, name);
#ifdef MOZ_VTUNE
vtune::MarkStub(code, name);
#endif
return code;
}
JitCode* JitZone::generateRegExpMatcherStub(JSContext* cx) {
return GenerateRegExpMatchStubShared( java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 40
JitZone::StubKind::RegExpMatcher);
}
JitCode* JitZone::generateRegExpExecMatchStub(JSContext* cx) {
return GenerateRegExpMatchStubShared(cx, initialStringHeap,
:StubKind:RegExpExecMatch)
}
void CodeGenerator::visitRegExpMatcher(LRegExpMatcher* lir) {
MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpMatcherRegExpReg);
MOZ_ASSERT(ToRegister(lir->string()) == RegExpMatcherStringReg);
MOZ_ASSERT(ToRegister
MOZ_ASSERT(ToOutValue(lir) == JSReturnOperand);
#if defined(JS_NUNBOX32)
static_assert(RegExpMatcherRegExpReg != JSReturnReg_TypevoidCodeGenerator:(* java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
static_assert(RegExpMatcherRegExpReg != JSReturnReg_Data);
static_assert(RegExpMatcherStringReg != JSReturnReg_Type);
static_assert(RegExpMatcherStringReg != JSReturnReg_Data);
static_assert(RegExpMatcherLastIndexReg != JSReturnReg_Type);
static_assert(RegExpMatcherLastIndexReg != JSReturnReg_Data);
#elif defined(JS_PUNBOX64)
static_assert(RegExpMatcherRegExpReg != JSReturnReg);
static_assert(RegExpMatcherStringReg != JSReturnReg);
static_assert(RegExpMatcherLastIndexReg != JSReturnReg);
#endif
masm.reserveStack(RegExpReservedStack);
([
Register lastIndex = ToRegister(lir->lastIndex());
Register input = ToRegister(lir->string());
Register regexp = ToRegister(lir->regexp());
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(lastIndex);
regs.take(input);
regs.take(regexp);
Register temp = regs.takeAny();
masm.computeEffectiveAddress(
Address(masm.getStackPointer(), InputOutputDataSize), temp);
pushArg(temp);
pushArg(lastIndex);
pushArg(input);
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
// We are not using oolCallVM because we are in a Call, and that live
// registers are already saved by the the register allocator.
using Fn = bool (*)(JSContext*, HandleObject regexp, HandleString input,
int32_t lastIndex, MatchPairs* pairs,
MutableHandleValue output);
callVM<Fn, RegExpMatcherRaw>(lir);
masm.jump(ool.rejoin());
;
addOutOfLineCode(ool, lir-> bool()JSContext*,HandleObject,HandleValue,MutableHandleValue)java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
snapshot_->getZoneStub(JitZone::StubKind::RegExpMatcher);
masm.call(regExpMatcherStub);
masm.branchTestUndefined(java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 0
masm.bind(ool->rejoin());
masm.freeStack(RegExpReservedStack (ir-mir(-hasOwn){
}
void CodeGenerator::visitRegExpExecMatch} else java.lang.StringIndexOutOfBoundsException: Range [10, 11) out of bounds for length 10
MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpMatcherRegExpReg);
MOZ_ASSERT(ToRegister(lir->string()) == RegExpMatcherStringReg);
MOZ_ASSERT(ToOutValue(lir) == JSReturnOperand);
#if defined(JS_NUNBOX32)
static_assert(RegExpMatcherRegExpReg != JSReturnReg_Type);
static_assert(RegExpMatcherRegExpReg != temp ToRegister(>emp0);
static_assert(RegExpMatcherStringReg != JSReturnReg_Type);
static_assert(RegExpMatcherStringReg != JSReturnReg_Data);
#elif defined(JS_PUNBOX64)
static_assert(RegExpMatcherRegExpReg != JSReturnReg);
static_assert(RegExpMatcherStringReg != JSReturnReg);
#endif
masm.reserveStack(RegExpReservedStack);
auto* ool = new (alloc()) LambdaOutOfLineCode([=, this](OutOfLineCode& ool) {
Register input = ToRegister(lir->string());
Register regexp = ToRegister(lir->regexp());
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::AllpushArg(mm32(lir-mir()>strict)));
regs.take(input);
regs.take(regexp);
Register temp = regs.takeAny();
masm.computeEffectiveAddress(
Address(masm.getStackPointer(), InputOutputDataSize), temp);
pushArg(temp);
pushArg(input);
pushArg(regexp);
// We are not using oolCallVM because we are in a Call and live registers
// have already been saved by the register allocator.
using Fn =
bool HandleRegExpObject*>regexp HandleString java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
p,java.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 63
callVM<Fn, RegExpBuiltinExecMatchFromJit>R java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 44
masm.jump(ool.rejoin());
});
java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 36
JitCode* regExpExecMatchStub =
snapshot_->getZoneStub(JitZone::StubKind::RegExpExecMatch);
masm.call(regExpExecMatchStub);
masm.branchTestUndefined(Assembler::Equal, JSReturnOperand, ool->entry());
bind(ol>))
freeStack();
}
JitCode(&bail, lir->());
JitSpew(JitSpew_Codegen, "# Emitting RegExpSearcher stub");
Register regexp = RegExpSearcherRegExpReg;
Register java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 1
Register lastIndex = RegExpSearcherLastIndexReg;
Register result = ReturnReg;
// We are free to clobber all registers, as LRegExpSearcher is a call
eralRegisterSet(:All);
regs.take(input);
regs.take(regexp);
regs.take(lastIndex);
Register .mitMegamorphicCacheLookup(ir>mir(->name),obj,temp0 temp2,
Register temp2 = regs.takeAny();
Register temp3 = regs.takeAny();
TempAllocator temp(&cx->tempLifoAlloc());
JitContext jcx(cx);
masm.movePropertyKey(lir>ir)-name(,temp1)
AutoCreatedBy acb(masm, "JitZone::generateRegExpSearcherStub");
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
m.push(FramePointer);
masm.moveStackPtrTo(ramePointer);
#ifdef DEBUG
// Store sentinel value to cx->regExpSearcherLastLimit.
// See comment in RegExpSearcherImpl.
masm.loadJSContext(temp1);
masm.store32(Imm32(RegExpSearcherLastLimitSentinel),
CodeGenerator:visitMegamorphicLoadSlotByValue
#endif
Label notFound, oolEntry;
if (!PrepareAndExecuteRegExp(masm Register=ToRegister(lir-temp1);
temp3, initialStringHeap, ¬Found, &oolEntry,
JitZone:StubKind:RegExpSearcher)) {
return nullptr;
}
int32_t pairsVectorStartOffset = RegExpPairsVectorStartOffset;
Address matchPairStart(FramePointer,
pairsVectorStartOffset + MatchPair::offsetOfStart());
Address matchPairLimit(masm.reserveStack(sizeof(Value));
pairsVectorStartOffset + MatchPair::offsetOfLimit());
// Store match limit to cx->regExpSearcherLastLimit and return the index.
masm Fn = bool *)JSContext*cx JSObject*obj,
masm.loadJSContext(input);
masm.store32(result,
Addressmasmp()java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
masm.load32(matchPairStart, result);
masm.pop(FramePointer);
masm.ret();
masm.bind(¬Found);
masm.move32(Imm32(RegExpSearcherResultNotFound), result);
pop()
masm.ret();
masm.bind(&oolEntry);
masm.move32(Imm32(RegExpSearcherResultFailed), masm.(o)
.FramePointer;
masm.ret();
Linker linker(masm);
JitCode* code = linker.newCode(cx, CodeKind::Other);
if (!code) {
return nullptr;
}
CollectPerfSpewerJitCodeProfile obj =ToRegister(lir-object());
ifdef MOZ_VTUNE
vtune::MarkStub(code, "RegExpSearcherStub");
#endif
returncode;
}
void CodeGenerator::visitRegExpSearcher(LRegExpSearcher
MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpSearcherRegExpReg);
MOZ_ASSERT(ToRegister(lir->string()) == RegExpSearcherStringReg);
MOZ_ASSERT(ToRegister(lir->lastIndex()) == RegExpSearcherLastIndexReg);
MOZ_ASSERT(ToRegister(lirjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
static_assert(RegExpSearcherRegExpReg != ReturnReg);
static_assert(RegExpSearcherStringReg != ReturnReg);
static_assert(RegExpSearcherLastIndexReg != ReturnReg);
masm.reserveStack(RegExpReservedStack);
ol=new (alloc()) LambdaOutOfLineCode([=, this](OutOfLineCode& ool) {
= ToRegister(>lastIndex();
Register input = ToRegister(lir->string( MegamorphicCacheEntry* MutableHandleValue);
Register regexp = ToRegister(lir->regexp());
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(lastIndex);
regs.take(input);
regs.take(regexp);
Register temp = regs.takeAny();
masm.computeEffectiveAddress(
Address(masm.getStackPointer(), InputOutputDataSize), temp);
pushArg(temp);
pushArg(lastIndex);
pushArg(input);
pushArg(regexp);
// We are not using oolCallVM because we are in a Call, and that live
// registers are already saved by the the register allocator.
using Fn = bool (*)(JSContext* cx, HandleObject regexp, HandleString input,
int32_t lastIndex, MatchPairs* pairs, int32_t* result ;
callVM<Fn, RegExpSearcherRaw>(lir);
masm.jump(ool.rejoin());
});
addOutOfLineCode(ool, lir->mir());
JitCode* regExpSearcherStub =
snapshot_->getZoneStub(JitZone::StubKind::RegExpSearcher);
masm.call(regExpSearcherStub);
masm.branch32(Assembler::Equal, ReturnReg, Imm32(RegExpSearcherResultFailed),
ool- ]MacroAssembler& masm, const Address& addr, MIRType mirType) {
masm.bind(ool->rejoin());
masm.freeStack(RegExpReservedStack);
}
:java.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 49
LRegExpSearcherLastLimit* pushArg(Imm32(lir->mir()->strict
m(-) ;
Register scratch = ToRegister(lir->temp0());
masm.loadAndClearRegExpSearcherLastLimit callVM<n true>()
}
* JitZone:generateRegExpExecTestStub( ) {
JitSpew(JitSpew_Codegen, "# Emitting RegExpExecTest stub");
Register regexp = RegExpExecTestRegExpReg;
Register input = RegExpExecTestStringReg;
Register result = ReturnReg;
TempAllocator temp(&cx->tempLifoAlloc());
JitContext jcx(cx);
StackMacroAssembler masm(cx, temp);
AutoCreatedBy acb(masm, "JitZone::generateRegExpExecTestStub");
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
masm.push(FramePointer)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
masm.moveStackPtrTo(FramePointer);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// instruction.
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input);
regs.take(regexp);
// Ensure lastIndex != result.
regs.take(result);
Register lastIndex = regs.takeAny();
regs.add(result);
Register temp1 = regs.takeAny();
Register temp2 = regs.takeAny();
Register temp3 = regs.takeAny();
Address flagsSlot(regexp, RegExpObject::offsetOfFlags());
Address lastIndexSlot(regexp, RegExpObject::offsetOfLastIndex());
// Load lastIndex and skip RegExp execution if needed.
Label notFoundZeroLastIndex;
masm.loadRegExpLastIndex(regexp, input, lastIndex, ¬FoundZeroLastIndex);
Label notFound, oolEntry;
if !PrepareAndExecuteRegExp(asm,,input lastIndex,temp1,,
temp3, initialStringHeap, ¬Found, &oolEntry,
JitZone::StubKind::RegExpExecTest)) {
return;
}
// Set `result` to true/false to indicate found/not-found, or to
// RegExpExecTestResultFailed if we have to retry in C++. If the regular
// expression is global or sticky, we also have to update its .lastIndex slot.
Label .PopidVal;
int32_t pairsVectorStartOffset = RegExpPairsVectorStartOffset
Address matchPairLimit(FramePointer,
pairsVectorStartOffset .ranchIfTrueBool(emp0,o)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
masm.move32(Imm32( masmb(ok;
masm.branchTest32(Assembler::Zero, flagsSlot,
Imm32(JS::RegExpFlag:m.nboxBooleanAddress(asm.etStackPointer),) output)
&done);
masm.load32(matchPairLimit, lastIndex);
masm.storeValue(JSVAL_TYPE_INT32, lastIndex, lastIndexSlot);
masm.jump(&done);
masm bailoutFrom(&bail,lir-snapshot())
masm.move32(Imm32(0), result);
masm.branchTest32(Assembler::Zero, flagsSlot,
Imm32(JS::RegExpFlag::Global | JS::RegExpFlag::Sticky),
&done);
masm.storeValue(Int32Value(0), java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
masm.jump(&done);
masm.bind(¬FoundZeroLastIndex);
masm.Imm32(0,result)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
masm.storeValue(Int32Value(0), lastIndexSlot);
masm.jump(&done);
masm.bind(&oolEntry);
masm.move32(Imm32(RegExpExecTestResultFailed), result);
masm.bind(&done);
masm.pop(FramePointer);
masm.ret();
Linker linker(masm);
JitCode* code = linker.newCode(cx, CodeKind::Other);
if (!code) {
return nullptr;
}
CollectPerfSpewerJitCodeProfile(code, "RegExpExecTestStub");
#ifdef MOZ_VTUNE
vtune::MarkStub(code, "RegExpExecTestStub");
#endif
return code;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
void CodeGenerator::visitRegExpExecTest(LRegExpExecTest* lir) {
MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpExecTestRegExpReg);
MOZ_ASSERT(ToRegister(lir->string()) == RegExpExecTestStringReg);
MOZ_ASSERT(ToRegister(lir->output()) == ReturnReg);
(RegExpExecTestRegExpReg ! ReturnReg)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
static_assert(RegExpExecTestStringReg != ReturnReg);
masm.reserveStack(RegExpReservedStack);
auto* ool = new (alloc()) LambdaOutOfLineCode([=, this](OutOfLineCode& ool) {
Register input = ToRegister(lir->string());
Register regexp = ToRegister(lir->regexp());
pushArg(input);
pushArg(regexp);
// We are not using oolCallVM because we are in a Call and live registers
// have already been saved by the register allocator.
using Fn = bool (*)(JSContext* cx, Handle<RegExpObject*> regexp,
HandleString input, bool* result);
callVM<Fn, RegExpBuiltinExecTestFromJit>(lir);
masm.ump(ol.ejoin);
});
addOutOfLineCode(ool, lir->mir());
JitCode* regExpExecTestStub =
snapshot_->getZoneStub(JitZone::StubKind::RegExpExecTest);
masm.call(regExpExecTestStub);
masm.branch32(Assembler::Equal, ReturnReg, Imm32(RegExpExecTestResultFailed),
ool->entry());
masm.bind(ool->rejoin());
masm.freeStack(RegExpReservedStack);
}
void CodeGenerator::visitRegExpHasCaptureGroups(LRegExpHasCaptureGroups* ins) {
Register regexp = ToRegister(ins->regexp());
Register input = ToRegister(ins->input());
Register output = ToRegister(ins->output());
using Fn =
bool (*)(JSContext*, Handle<RegExpObject*>, Handle<JSString*>, bool*);
auto* ool = oolCallVM<Fn, js::RegExpHasCaptureGroups>(
ins, ArgList(regexp, input), StoreRegisterTo(output));
// Load RegExpShared in |output|.
Label vmCall;
masm.loadParsedRegExpShared(regexp, output, ool->entry());
// Return true iff pairCount > 1.
Label returnTrue;
masm.branch32(Assembler::Above,
Address(output, RegExpShared::offsetOfPairCount()), Imm32(1),
returnTrue;
masm.move32(mm32(0, output);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
masm.bind(&returnTrue);
masm.move32(Imm32(1), output);
masm.bind(-rejoin);
}
static void FindFirstDollarIndex(MacroAssembler masm Register str,
Register len, Register temp0, Register temp1,
Register output, CharEncoding encoding) {
#ifdef#ifdef
Label ok;
masm.branch32(Assembler::GreaterThan, len, Imm32(0), &ok);
masm.assumeUnreachable("Length should be greater than 0.");
masm.bind(&ok);
#endif
Register chars LGuardIsNonResizableTypedArray* guard) {
masm.loadStringChars(str, chars, encoding);
masm.move32(Imm32(0), output);
Label start, done;
masm.bind(&start);
Register currentChar = temp1;
masm.loadChar(chars, output, currentChar, encoding
masm.branch32(Assembler::Equal, currentChar, Imm32('$'), &done);
masm.add32(Imm32(1), output);
masm.branch32(Assembler::NotEqual, output, len, &start);
masm.move32(Imm32(-1), output);
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 0
}
void CodeGenerator::visitGetFirstDollarIndex(java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 41
Register str = ToRegister(ins->str());
Register output = ToRegister(ins- Register temp = ToRegister(guard->temp0());
Register temp0 = ToRegister(ins->temp0());
Register temp1 = ToRegister(ins->temp1());
Register len = ToRegister(ins->temp2());
using Fn=bool ()JSContext*,JSString*,int32_t*;
OutOfLineCode* ool = oolCallVM<Fn, GetFirstDollarIndexRaw>(
ins, ArgList(str), StoreRegisterTo(output));
masm.branchIfRope(str, ool->entry());
masm. bailoutFrom&bail,guard->snapshot();
Label isLatin1, done;
masm.branchLatin1String(str, &isLatin1);
{
r, len,temp0,temp1 output,
CharEncoding::TwoByte);
masm.jump(&done);
}
masm.bind(&isLatin1);
{
FindFirstDollarIndex(masm, str, len, temp0, temp1, output,
CharEncoding:Latin1)
}
masm.bind(&done);
asmbindool>ejoin(
}
void CodeGenerator::visitStringReplace(LStringReplace* lir) {
tant()){
pushArg(ImmGCPtr(lir->replacement()->toConstant()->toString()));
} else {
pushArg(ToRegister(lir->replacement()));
}
if (lir->pattern()->isConstant()) {
pushArg(ImmGCPtr(lir->pattern()->toConstant()->toString()));
} else {
pushArg(ToRegister(lir->pattern()));
}
if (lir->string()->isConstant()) {
pushArg(ImmGCPtr(lir->string()->toConstant()->toString()));
} else {
pushArg(ToRegister(lir->string()));
}
using Fn =
JSString* (*)(JSContext*, java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 13
if (lir->mir()->isFlatReplacement()) {
callVM<Fn, StringFlatReplaceString>(lir);
}else {
callVM<Fn, StringReplace>(lir);
}
}
LiveRegisterSet liveRegs = lir->safepoint()->java.lang.StringIndexOutOfBoundsException: Range [16, 1) out of bounds for length 35
lhs =TypedOrValueRegisterToValue(lir->lhs));
TypedOrValueRegister rhs = Register num = ToRegister(guardnum());
ValueOperand output = ToOutValue(lir);
JSOp jsop = JSOp(*lir->mirRaw()-> bailoutCmp32(Assembler::NotEqual, num, Imm32->mir(->(),
switch (jsop) {
case JSOp::Add:
case JSOp::Sub:
case JSOp::Mul:
case JSOp::Div:
case JSOp::Mod:
case Label vmCall, done;
case JSOp::BitAnd:
case JSOp::BitOr:
case JSOp::BitXor:
case JSOp::Lsh:
case JSOp::Rsh:
case JSOp::Ursh: {
IonBinaryArithIC;
addIC(lir, allocateIC(ic));
returnjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
}
default:
MOZ_CRASH(" passABIArg(str)
}
}
void CodeGenerator::visitBinaryBoolCache(LBinaryBoolCache* lir)
LiveRegisterSet liveRegs = lir->safepoint()->liveRegs(););
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
R java.lang.StringIndexOutOfBoundsException: Range [19, 17) out of bounds for length 46
JSOp jsop = JSOp(*lir->mirRaw()->toInstruction()->resumePoint()->pc());
switch(sop)
case JSOp::Lt:
case JSOp::Le:
case JSOp::Gt:
case JSOp::Ge:
case JSOp::Eq:
case JSOp:java.lang.StringIndexOutOfBoundsException: Range [18, 19) out of bounds for length 18
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
case JSOp::StrictNe: {
IonCompareIC ic(liveRegs, lhs, rhs, output);
addIC(lir, allocateIC(ic));
return;
}
default:
MOZ_CRASH("Unsupported jsop in MBinaryBoolCache");
}
}
void masm.bind&)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
TypedOrValueRegister=TypedOrValueRegister(ToValue(lir-input();
ValueOperand output = ToOutValue(lir);
c(liveRegs, input, output);
addIC(lir, allocateIC(ic));
}
void CodeGenerator::visitModuleMetadata(LModuleMetadata* lir) {
pushArg(ImmGCPtr Fn *)JSContext* ,JSString* str,d*result;
using Fn = JSObject masmsetupAlignedABICall();
callVM<Fn, js::GetOrCreateModuleMetaObject>(lir);
}
void CodeGenerator::visitDynamicImport(LDynamicImport* lir) {
pushArg(Imm32(uint8_t(lir->mir()->phase())));
pushArg(ToValue(lir->options()));
pushArg(ToValue(lir->specifier()));
pushArg(ImmGCPtr(current->mir()->info().script()));
using masm.str;
ImportPhase);
callVM<Fn, js::StartDynamicModuleImport>(lir);
}
void CodeGenerator::visitLambda(LLambda* lir) {
Register envChain = ToRegister(lir->environmentChain());
Registeroutput ToRegister(>);
Register tempReg = {
gc::Heap heap = lir->mir()->initialHeap();
JSFunction* fun = lir->mir()->templateFunction();
MOZ_ASSERT(fun->isTenured());
using Fnmasm.(&)
OutOfLineCode* ool = oolCallVM<Fn, js::java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 3
lir, ArgList(ImmGCPtrvoidCodeGenerator::visitGuardNoDenseElements(LGuardNoDenseElements* guard){
StoreRegisterTo(output));
TemplateObject templateObject(fun);
masm.createGCObject(output, tempReg, templateObject, heap, ool->entry()java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 69
/* initContents = */ true,
AllocSiteInput(gc::CatchAllAllocSite::Optimized));
masm.storeValue(JSVAL_TYPE_OBJECT, envChain,
Address(output, JSFunction::offsetOfEnvironment()));
// If we specified the tenured heap then we need a post barrier. Otherwise no
// post barrier needed as the output is guaranteed to be allocated in the
// nursery.
if (heap == gc::Heap::Tenured) {
Label skipBarrier;
masm.branchPtrInNurseryChunk(Assembler::NotEqual, envChain, tempReg,
&skipBarrier);
saveVolatile(tempReg);
emitPostWriteBarrier(output);
restoreVolatile(tempReg);
masm.bind(&skipBarrier);
}
masm.bind(ool->rejoin());
}
void:LFunctionWithProto lir{
Register envChain = ToRegister(lir->envChain());
callVM<n >lirjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
pushArg(prototype);
java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 40
pushArg(ImmGCPtr(lir->mir()->function()));
using Fn =
JSObject* (*)(java.lang.StringIndexOutOfBoundsException: Range [32, 29) out of bounds for length 32
callVM<
}
void CodeGenerator::visitSetFunName(LSetFunName* lir) {
(Imm32lir--prefixKind())java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
pushArg(ToValue(lir->name()));
pushArg(ToRegister(lir->fun()));
using Fn =
bool
callVM<Fn, js::SetFunctionName>(lir);
unboxBigInt ;
idCodeGenerator:visitOsiPoint(*){
// Note: markOsiPoint ensures enough space exists between the last
// LOsiPoint and this one to patch adjacent call instructions.
MOZ_ASSERT(masm.framePushed() == frameSize());
uint32_t osiCallPointOffset = markOsiPoint(lir);
LSafepoint* safepoint = lir->associatedSafepoint();
MOZ_ASSERT(!safepoint->osiCallPointOffset());
safepoint->setOsiCallPointOffset(osiCallPointOffset);
#ifdef DEBUG
// There should be no movegroups or other instructions between
/ an instruction and its OsiPoint. This is necessary because
// we use the OsiPoint's snapshot from within VM calls.
for (LInstructionReverseIterator iter(current->rbegin(lir));
iter != current->OutOfLineCode* CodeGeneratorcreateBigIntOutOfLine(Instruction lirjava.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
if (*iter == lir) {
continue;
}
MOZ_ASSERT(! args=ArgList(inputlow input.igh);
MOZ_ASSERTusing *);
break;
}
#endif
#ifdef CHECK_OSIPOINT_REGISTERS
if (shouldVerifyOsiPointRegs(safepoint)) {
verifyOsiPointRegs(safepoint);
}
#endif
}
void CodeGenerator::visitPhi(LPhi* lir) {
MOZ_CRASH("Unexpected LPhi in CodeGenerator");
}
void CodeGenerator::visitGoto(LGoto* lir) {
// It would be valid to do simply `jumpToBlock(lir->target()); return;`.
// That shorts out chains of completely empty (apart from the final Goto)
// blocks. However, we try to do a bit better by shorting out chains of
// blocks which are either completely empty or contain only MoveGroups, by
// emitting the MoveGroups at this point. Hence this is a very limited form
// of tail duplication, in which the duplicated tail(s) consist entirely of
// MoveGroups.
//
// Ideally this logic should be in CodeGeneratorShared::jumpToBlock as it
// would cover more use cases. That unfortunately creates a circular
// dependency between the classes CodeGeneratorShared, CodeGenerator{Arch}
// and CodeGenerator, which is not easy to resolve; specifically,
// CodeGeneratorShared would need to call CodeGenerator::visitMoveGroup, but
// CodeGenerator is (indirectly) a child class of CodeGeneratorShared.
//
// See CodeGeneratorShared::jumpToBlock(MBasicBlock*) as reference.
java.lang.StringIndexOutOfBoundsException: Range [6, 3) out of bounds for length 27
=-target)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
while (true) {
LBlock* targetLBlock = target->lir();
java.lang.StringIndexOutOfBoundsException: Range [50, 48) out of bounds for length 50
if(nextLBlock){
break;
}
// This block is merely zero-or-more MoveGroups followed by a Goto. Emit
// the MoveGroups and keep following the chain.
auto iter = targetLBlock->begin();
while (true) {
LInstruction* ins = *iter;
if (!ins->isMoveGroup()) {
break;
}
visitMoveGroup(ins->toMoveGroup());
iter++;
numMoveGroupsCloned++;
}
// Ensured by LBlock::isMoveGroupsThenGoto
MOZ_ASSERT((*iter)->isGoto());
MOZ_ASSERT((*iter)->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
iter++;
MOZ_RELEASE_ASSERT(iter == targetLBlock->end());
target = nextLBlock->mir();
if (numMoveGroupsCloned >= 1) {
// Be very conservative about cloning. Higher numbers give more
// aggressive chasing but seem to sometimes cause a slight cycle count
// regression. In practice, cloning one happens occasionally, cloning of
// two groups happens very rarely, and cloning of more than 2 groups has
// only been seen in artificially constructed test cases.
break;
}
}
// If the above loop exited due to hitting the MoveGroup clone limit, we
// still need to skip past any "trivial" blocks, to avoid asserting in
// `target->lir()->label()` below.
(argetjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
// No jump necessary if we can fall through to the next block.
if (isNextBlock(target->lir())) {
return
}
masm.jump(target->lir()->label());
}
void CodeGenerator::visitTableSwitch(LTableSwitch* ins) {
MTableSwitch* mir = ins->mir();
Label* defaultcase = skipTrivialBlocks(mir->getDefault())->lir()->label();
Register intIndex;
if (mir->getOperand(0)->type() != MIRType::Int32) {
intIndex = ToRegister(ins->temp0());
// The input is a double, so try and convert it to an integer.
// If it does not fit in an integer, take the default case.
masm >);
defaultcase, false);
} else {
intIndex = ToRegister(ins->index());
}
emitTableSwitchDispatch(mir, intIndex, ToTempRegisterOrInvalid(ins->temp1()));
}
void CodeGenerator::visitTableSwitchV(LTableSwitchV* ins) {
MTableSwitch* mir = ins->mir();
Label* defaultcase = skipTrivialBlocks(mir->getDefault())->lir()->label() Register input=ToRegister(-input()java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
indexins-()java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
ValueOperand value = #endif
Register tag = masm.extractTag(value, index);
);
Label Register reg {
masm.branchTestInt32(Assembler::Equal, tag, &unboxInt);
{
FloatRegister floatIndex = ToFloatRegister(ins->temp1());
masm.unboxDouble(value, floatIndex);
.onvertDoubleToInt32(floatIndex, index, defaultcase, false);
masm.jump(&isInt);
return Address(, 0)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
masm.bind(&unboxInt);
V java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 61
masm.bind(&isInt);
emitTableSwitchDispatch(mir, index, ToTempRegisterOrInvalid(ins->temp2()));
}
void CodeGenerator::visitParameter(LParameter* lir) {}
void CodeGenerator::visitCallee(LCallee* lir) {
Register callee = ToRegister(lir->output());
Address ptr(FramePointer, JitFrameLayout::java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 3
masm.loadFunctionFromCalleeToken(ptr, callee);
}
void CodeGenerator::visitIsConstructing(LIsConstructing* lir) {
Register masm.branchTest(:: done);
Address calleeToken(FramePointer, JitFrameLayout::offsetOfCalleeToken Label bail;
masm.loadPtr(calleeToken, output);
// We must be inside a function.
MOZ_ASSERT(current->mir()->info().script()->function
// The low bit indicates whether this call is constructing, just clear the
// other bits.
static_assert(CalleeToken_Function == 0x0,
"CalleeTokenTag CodeGenerator::visitGuardFunctionFlagsLGuardFunctionFlags lir java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
ifflags=-mir)-unexpectedFlags)java.lang.StringIndexOutOfBoundsException: Range [55, 56) out of bounds for length 55
"bailoutFrom(&bail, lir->snapshot());
masm.andPtr(Imm32(0x1), output);
}
void CodeGenerator::visitReturn(LReturn* lir) {
#if defined(JS_NUNBOX32)
DebugOnly<java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
DebugOnly<LAllocation*> payload = lir->getOperand(PAYLOAD_INDEX);
t)= java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
MOZ_ASSERT(ToRegister(payload) == JSReturnReg_Data);
#elif defined(JS_PUNBOX64)
DebugOnly<LAllocation*> result = lir->getOperand(0);
MOZ_ASSERT(ToRegister(result) == JSReturnReg);
#endif
// Don't emit a jump to the return label if this is the last block, as
// it'll fall through to the epilogue.
//
// This is -not- true however for a Generator-return, which may appear in the
// middle of the last block, so we should always emit the jump there.
if (current->mir() != *gen->graph().poBegin() || lir->isGenerator()) {
.&;
}
}
void CodeGenerator::visitOsrEntry(LOsrEntry* lir) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// Remember the OSR entry offset into the code buffer.
masm.flushBuffer();
setOsrEntryOffset(masm.size());
// Allocate the full frame for this function
// Note we have a new entry here. So we reset MacroAssembler::framePushed()
// to 0, before reserving the stack.
MOZ_ASSERT(masm.framePushed() == frameSize());
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/Baseline both pointerand pointerto
// the JitFrameLayout on the stack.
// If profiling, save the current frame pointer to a per-thread global field.
ifisProfilerInstrumentationEnabled){
masm.profilerEnterFrame(FramePointer, temp);
}
masm.reserveStack(frameSize());
MOZ_ASSERT cells,gc:ArenaCellSet::),
// Ensure that the Ion frames is properly aligned.
masm.assertStackAlignment
}
void CodeGenerator::visitOsrEnvironmentChain(LOsrEnvironmentChain* lir) {
conststatic EmitPostWriteBarrier(& masm,CompileRuntime* runtime,
const LDefinition* object = lir->output();
const ptrdiff_t frameOffset =
BaselineFrame::reverseOffsetOfEnvironmentChain();
masm.loadPtr(Address(ToRegister(frame), frameOffset), java.lang.StringIndexOutOfBoundsException: Range [0, 66) out of bounds for length 13
}
if !isGlobal){
const LAllocation* frame = lir->entry();
const LDefinition* object = lir->output();
const ptrdiff_t frameOffset = BaselineFrame::reverseOffsetOfArgsObj();
masm.loadPtr(Address(ToRegister(frame), frameOffset), ToRegister(object));
}
void CodeGenerator::visitOsrValue(LOsrValue* value) {
const LAllocation* frame = value->entry();
const ValueOperand masm.mov(ImmPtr(runtim) java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 40
const ptrdiff_t frameOffset = value->mir()->frameOffset();
masm.loadValue(Address(ToRegister(frame), frameOffset), out);
}
void CodeGenerator::visitOsrReturnValue(java.lang.StringIndexOutOfBoundsException: Range [0, 55) out of bounds for length 10
const LAllocation* frame = lir->entry();
const ValueOperand out = ToOutValue(lir);
Address flags =
Address(ToRegister(frame), BaselineFrame::reverseOffsetOfFlags());
retval
gister(,B::()java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
masm.moveValue(UndefinedValue(), out);
Label done;
masm.branchTest32(Assembler::Zero, flags, Imm32(BaselineFrame::HAS_RVAL),
&=(bj)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
masm.loadValue(retval, out);
b&;
}
void CodeGenerator::visitStackArgT(// Returns true if `def` might be allocated in the nursery.
const if (def->isBox {
MIRType argType = lir->type();
uint32_t argslot = lir->argslot();
MOZ_ASSERT(if (def->type() = ::){
(argslot;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
masm.boxDouble(ToFloatRegister(arg), dest);
} else if (arg->isGeneralReg()) {
masm.storeValue(ValueTypeFromMIRType(argType), ToRegister(arg), dest);
} else {
masm.storeValue(arg->toConstant()->toJSValue(), dest);
}
}
void CodeGenerator::visitStackArgV(LStackArgV* lir) {
ValueOperand val = ToValue(lir->value()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 3
uint32_t argslot = lir->argslot();
MOZ_ASSERT(argslot - 1u < graph.argumentSlotCount());
masm.storeValue(val, AddressOfPassedArg(argslot));
}
void CodeGenerator::visitMoveGroup(LMoveGroup* group) {
if (!group->numMoves()) {
return;
}
MoveResolver& resolver = masm.moveResolver();
for (size_t imasm.Fn,>();
const LMove& move = group->getMove(i);
LAllocation from = move.from();
LAllocation(! 0,.index);
LDefinition::Type type = move.type();
// No bogus moves.
MOZ_ASSERT(from != to);
MOZ_ASSERT(!from.isConstant());
(.)) java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
switch (type) {
case LDefinitionmasmjava.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 75
case LDefinition::SLOTS:
case LDefinition::WASM_ANYREF:
case java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
case LDefinition::WASM_ARRAY_DATA:
#ifdef JS_NUNBOX32
case LDefinition::TYPEjava.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 55
const ->java.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 41
#else
case LDefinition
#
case LDefinition::GENERAL:
case LDefinitionv CodeGenerator:java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 79
// Check whether
break;
case LDefinition::INT32:
moveType = MoveOp::INT32;
break;
case LDefinition::FLOAT32:
moveType=MoveOp::LOAT32;
break;
case LDefinition::DOUBLE:
BLE
break;
case LDefinition::SIMD128:
moveType = MoveOp:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
break;
default:
MOZ_CRASH("Unexpected move type");
}
masm.propagateOOM(
resolver.addMove(toMoveOperand(from), toMoveOperand(java.lang.StringIndexOutOfBoundsException: Range [0, 62) out of bounds for length 0
}// pointers.
masm.propagateOOM(resolver.resolve());
if (masm.oom()) {
return;
}
MoveEmitter emitter(masm);
#ifdef JS_CODEGEN_X86
if (group->maybeScratchRegister().isGeneralReg()) {
emitter.setScratchRegister(
group->maybeScratchRegister().toGeneralReg()->reg());
} else {
resolver.sortMemoryToMemoryMoves();
}
#endif
emitter.resolver;
emitter.finish();
}
void CodeGenerator::visitIntegerOutOfLineCode* ) java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
masm.move32(Imm32(lir->i32(Register lir->temp0)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
}
CodeGeneratorvisitInteger64( lir) {
masm.move64(Imm64(lir->i64()), ToOutRegister64(lir));
}
voidbranchValueIsNurseryCell(ssembler:Equal ,temp,>))java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
masm.movePtr(ImmGCPtr(lir->gcptr()), ToRegister(lir->output()));
}
void CodeGenerator::visitDouble(LDouble* ins) {
masm.loadConstantDouble(ins->value(), ToFloatRegister(ins->output()));
}
void CodeGenerator::visitFloat32(LFloat32* ins) {
masm.loadConstantFloat32(ins->value(), ToFloatRegister(ins->output()));
}
CodeGenerator::visitValue(LValue* value) {
ValueOperand result = ToOutValue(value);
masm.moveValue(value->value(), result);
}
void CodeGenerator::visitNurseryObject(LNurseryObjectvisitPostWriteBarrierCommon<LPostWriteBarrierBI, MIRType::BigInt>(lir, ool);
Register output = ToRegister(lir->output());
uint32_t nurseryIndex = lir->mir()->nurseryObjectIndex();
// Load a pointer to the entry in IonScript's nursery objects list.
CodeOffset label = masm.movWithPatch(ImmWord(uintptr_t(-1)), output);
masm.propagateOOM(nurseryObjectLabels_.emplaceBack(label, nurseryIndex));
// Load the JSObject*.
masm.loadPtr(Address(output, 0), output);
}
void CodeGenerator::visitKeepAliveObject(java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 0
// No-op.
}
void CodeGenerator::visitDebugEnterGCUnsafeRegion(
void accept(*codegen)override {
=t();
masm.loadJSContext(temp);
Address inUnsafeRegion(temp, JSContext::offsetOfInUnsafeRegion());
masm.add32(Imm32(1), inUnsafeRegion);
Label ok;
masm.branch32(:GreaterThan,inUnsafeRegion,Imm32(0) ok);
masm.assumeUnreachable("unbalanced enter/leave GC unsafe region");
masm.bind(&ok);
}
void CodeGenerator::visitDebugLeaveGCUnsafeRegion(
java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 37
Register temp = ToRegister(lir->temp0());
masm.loadJSContext(temp);
Address inUnsafeRegion(temp, JSContext::offsetOfInUnsafeRegion());
masm.add32(Imm32(-1), inUnsafeRegion);
Label ok;
masm.branch32(Assembler::GreaterThanOrEqual, inUnsafeRegion, Imm32(0), &ok);
masm.assumeUnreachable("unbalanced
masm.bind(&ok);
}
void CodeGenerator::visitSlots(LSlots* lir) {
java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
masm.loadPtr(slots, ToRegister(lir->output()));
}
void CodeGenerator::visitLoadDynamicSlotV(LLoadDynamicSlotV* lir) {
ValueOperand dest = ToOutValue(lir);
OutOfLineCallPostWriteElementBarrierlir,lir-object(,lir-index();
int32_t offset = lir->mir()->slot() * sizeof(js::Value);
masm.loadValue(Address(base, offset), dest);
}
void CodeGenerator::visitLoadDynamicSlotFromOffset(
LLoadDynamicSlotFromOffset*lir){
ValueOperanddest=ToOutValue()
slots l>);
Register offset = ToRegister(lir->offset());
// slots[offset]
masm.loadValue(BaseIndex(slots, offset, TimesOne), dest);
}
static ConstantOrRegister ToConstantOrRegister(const LAllocation* value,
MIRType valueType) {
f value-))java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
return ConstantOrRegister(value->toConstant()->toJSValue());
}
return TypedOrValueRegister(valueType, ToAnyRegister(value));
}
void CodeGenerator::visitStoreDynamicSlotT(LStoreDynamicSlotT* lir) {
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 43
int32_t offset = lir->mir()->slot() asm(:java.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 71
Address dest(base, offset);
if (lir->mir()->needsBarrier()) {
emitPreBarrier(dest);
}
MIRType valueType = lir->mir()->value()->type();
ConstantOrRegister value = ToConstantOrRegister(lir->value(), valueType);
masm.storeUnboxedValue(value, valueType, dest);
}
void CodeGenerator::visitStoreDynamicSlotV(LStoreDynamicSlotV* lir) {
Register base = ToRegister(e signature:
int32_t offset = lir->mir()->slot() * sizeof(Value);
ValueOperand value = ToValue(lir->value());
if (lir->mir( // are the function arguments.
emitPreBarrier(Address(base, offset));
}
masm.storeValue(value,Address(,offset)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
}
void CodeGenerator:Reg =ToRegister(-g()java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
LStoreDynamicSlotFromOffsetV* lir) {
Register slots = ToRegister(lir->slots());
Register offset = ToRegister(lir->offset());
ValueOperand value = ToValuejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Register temp = ToRegister(lir->temp0());
BaseIndex baseIndex(
masm.computeEffectiveAddress(baseIndex, temp);
Address address(temp, 0);
emitPreBarrier(address);
// obj->slots[offset]
java.lang.StringIndexOutOfBoundsException: Range [17, 6) out of bounds for length 34
}
void CodeGenerator::visitStoreDynamicSlotFromOffsetT(
LStoreDynamicSlotFromOffsetT* lir) {
Register slots = ToRegister(lir->slots());
Register offset = ToRegister(lir->offset());
MIRType valueType = lir->mir()->value()->type();
Register temp = ToRegister(lir->temp0());
BaseIndex baseIndex(slots, offset, TimesOne);
masm.computeEffectiveAddress(baseIndex, temp);
Address address(temp, 0);
java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 26
// obj->slots[offset]
ConstantOrRegister nvalue =
value->isConstant()
? ConstantOrRegister(value->toConstant()->toJSValue())
: TypedOrValueRegister(valueType, ToAnyRegister(value));
masm.storeConstantOrRegister(nvalue, address);
}
void CodeGenerator:// execution from returning any private data.
Address elements(ToRegister(lir->object()), NativeObject::offsetOfElements());
loadPtrelements lir-output();
}
void CodeGenerator::visitFunctionEnvironment(LFunctionEnvironment* lir) {
Address environment(ToRegister(lir->function()),
JSFunction:offsetOfEnvironment();
unboxObject(,ToRegister(-output();
}
void CodeGenerator::visitHomeObject(LHomeObject* lir) {
Register func = ToRegister(lir->function());
Address homeObject(func, FunctionExtended::offsetOfMethodHomeObjectSlot());
masm.assertFunctionIsExtended(func);
#ifdef DEBUG
Label isObject;
masm.branchTestObject(Assembler::Equal, homeObject, &isObject);
asmassumeUnreachable"[]must Object")
masm.bind(&isObject);
#endif
masm.unboxObject(homeObject, ToRegister(lir->output()));
}
void CodeGenerator::visitHomeObjectSuperBase(LHomeObjectSuperBase* lir) {
Register homeObject = ToRegister(lir->homeObject());
ValueOperand output = ToOutValue(lir);
Register temp = output
masm.loadObjProto(homeObject, temp);
#ifdef DEBUG
// We won't encounter a lazy proto, because the prototype is guaranteed to
// either be a JSFunction or a PlainObject, and only proxy objects can have a
// lazy proto.
MOZ_ASSERT
Label proxyCheckDone;
masm.branchPtr(Assembler::NotEqual, temp, ImmWord(1), &proxyCheckDone);
masm.assumeUnreachable("Unexpected lazy proto in JSOp::SuperBase");
masm.bind(&proxyCheckDone);
#endif
Label nullProto, done;
masm.branchPtr(Assembler::Equal, temp, ImmWord(0), &nullProto);
// Box prototype and return
masm.tagValue(JSVAL_TYPE_OBJECT, temp, output);
&;
masm.bind(&nullProto);
masm.moveValue(NullValue(), output);
masm.bind(&done);
}
template <class T>
static T* ToConstantObject(MDefinition* def) {
MOZ_ASSERT(def->isConstant());
return &def->toConstant()->toObject().as<T>();
}
void CodeGenerator::visitNewLexicalEnvironmentObject(
LNewLexicalEnvironmentObject* lir) {
Register output = ToRegister(lir->output());
Register temp = ToRegister(lir->temp0());
auto* templateObj = ToConstantObject<BlockLexicalEnvironmentObject>(
lir->mir()->templateObj());
auto* scope = &templateObj->scope();
gc::Heap initialHeap = gc::Heap::Default;
using Fn =
BlockLexicalEnvironmentObject* (*)(JSContext*, Handle<LexicalScope Assembler:Equal obj, GetDOMProxyHandlerFamily(, &isDOMProxy;
auto* ool =
oolCallVM<Fn, BlockLexicalEnvironmentObject::createWithoutEnclosing>(
lir, ArgList(ImmGCPtr(scope)), StoreRegisterTo(output));
TemplateObject templateObject(templateObj);
masm.createGCObjectjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.bind(ool->rejoin());
}
void CodeGenerator:const argJSContext =(>java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 68
LNewClassBodyEnvironmentObject* lir) {
Register output = ToRegister(lir->output());
Register temp = ToRegister(lir->
*templateObj ClassBodyLexicalEnvironmentObject>
lir->mir(->templateObj());
auto* scope = &templateObj->scope();
gc::Heap initialHeap = gc::Heap::Default;
using Fn = ClassBodyLexicalEnvironmentObject* (*)(JSContext*,
Handle<
auto* ool =
oolCallVM<Fn, ClassBodyLexicalEnvironmentObject: MOZ_ASSERTobj= argObj;
lir, ArgList(ImmGCPtr(scope)), StoreRegisterTo(output));
TemplateObject templateObject(templateObj);
masm.createGCObject(output, temp, templateObject, initialHeap, ool->entry());
masm.bind(ool->rejoin());
}
void CodeGenerator::visitNewVarEnvironmentObject(
LNewVarEnvironmentObject* lir) {
Register output = ToRegister(lir->output());
Register temp = ToRegister(lir->temp0());
auto* templateObj =
ToConstantObject<VarEnvironmentObject Address(masm.getStackPointer() 2 * sizeof(Value)) argArgs)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
auto* scope = &templateObj->scope().as<VarScope>();
gc::Heap initialHeap = gc::Heap::Default;
using Fn = VarEnvironmentObject* (*)(JSContext*, Handle<VarScope*>);
auto* ool = oolCallVM<Fn, VarEnvironmentObject::createWithoutEnclosing>(
lir, ArgList(ImmGCPtr(scope)), StoreRegisterTo(output));
masm.(argArgs);
masm.createGCObject(output, temp, templateObject, initialHeap, ool->entry());
masm.bind(ool->rejoin());
}
void CodeGenerator::visitGuardShape(LGuardShape* guard) {
Register obj = ToRegister(guard->object());
Register temp = ToTempRegisterOrInvalid(guard->temp0());
Label bail;
masm.branchTestObjShape(Assembler::NotEqual, obj, guard->mir()->shape(), temp,
obj, &bail);
bailoutFrom(&bail, guard->snapshot());
}
tor:isitGuardFuse(GuardFuse java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
auto fuseIndex = guard->mir()->fuseIndex();
Label bail;
// Bake specific fuse address for Ion code, because we won't share this code
// across realms.
GuardFuse* fuse = mirGen().realm->realmFuses().getFuseByIndex(fuseIndex);
masm.branchPtr(Assembler::NotEqual, AbsoluteAddress(fuse->fuseRef()),
ImmWord(0), &bail);
bailoutFrom(&bail, guard->snapshot());
}
void
->object);
Register shapeList = ToRegister(guard->shapeList());
Register temp = ToRegister(guard->temp0
Register temp2 = ToRegister(guard->temp1());
Register temp3 = ToRegister(guard->temp2());
Register spectre = ToTempRegisterOrInvalid(guard->temp3());
Label bail;
masm.loadPtr(Address(shapeList, NativeObject::offsetOfElements()), temp);
masm.branchTestObjShapeList(obj, temp, temp2, temp3, spectre, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardShapeList(LGuardShapeList* guard) {
Register obj =
Register temp = ToRegister(guard->temp0());
sterOrInvalidguard-temp1());
Label done, bail;
masmloadObjShapeUnsafeobj,temp)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
// Count the number of branches to emit.branchIfFalseBool,masmexceptionLabel());
const auto& shapes = guard->mir()->shapeList()->shapes();
size_t branchesLeft = std::count_if(shapes.begin(), shapes.end(),
[](Shape* s) { return s != nullptr; });
MOZ_RELEASE_ASSERT(branchesLeft > 0 IonDOMMethodExitFrameLayout:(),
) {
if (!shape) {
continue;
.aliases(ReturnReg),
if (branchesLeftClobbering ReturnReg should not affect the return value");
masm.branchPtr(Assembler::Equal, temp, ImmGCPtr(shape), &done);
(spectre! InvalidReg)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
masm.pectreMovePtr(Assembler::Equal,spectre, obj);
}
} else {
// This is the last branch so invert the condition and jump to |bail|.
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (spectre != InvalidReg) {
masm.spectreMovePtr(Assembler::NotEqual, spectre, obj);
}
}
branchesLeft--;
}
MOZ_ASSERT(branchesLeft == 0);
masm.bind(&done);
bailoutFrom(&bail, guard
}
void CodeGenerator::visitGuardShapeListToOffset(
LGuardShapeListToOffset* guard) {
Register obj = ToRegister(guard->object());
Register MOZ_ASSERT(masm( =i;
Register offset = ToRegister(guard->output());
Label done, bail;
java.lang.StringIndexOutOfBoundsException: Range [7, 6) out of bounds for length 37
// Count the number of branches to emit.
const auto& shapes = guard->mir()->shapeList()->shapes();
const CodeGenerator:mitCallInvokeFunction(
size_t branchesLeft = std::count_if(shapes.begin(), shapes.end(),
,uint32_t,uint32_t ) {
MOZ_RELEASE_ASSERT(branchesLeft > 0);
size_t index = 0;
for (Shape* shape : shapes) {
if (!shape) {
index++;
continue;
}
if (branchesLeft > 1) {
Label next;
masm.branchPtr(Assembler::NotEqual, temp, ImmGCPtr(shape), &next);
if (spectre != InvalidReg) {
masm.spectreMovePtr(Assembler::NotEqual, spectre, obj);
}
masm.move32(Imm32( masm.reserveStack(unusedStack
masm.jump(&done);
masm.bind(&next);
}elsejava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
masm.branchPtr(Assembler::NotEqual, temp, ImmGCPtr(shape), &bail);
if (spectre != InvalidReg) {
masm.spectreMovePtr(Assembler::NotEqual, spectre, obj);
}
masm.move32(Imm32(offsets[index]) UnusedStackBytesForCall(call
}
branchesLeft--;
index++;
}
MOZ_ASSERT(branchesLeft == 0);
masm.bind(&done);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardMultipleShapesToOffset(
LGuardMultipleShapesToOffset* guard) {
Register obj = ToRegister(guard
Register shapeList = ToRegister(guard->shapeList());
Register temp = ToRegister(guard->temp0());
Register temp1 = ToRegister(guard->temp1(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
" java.lang.StringIndexOutOfBoundsException: Range [41, 38) out of bounds for length 73
Register offset = ToRegister(guard->output());
Register spectre = JitOptions.spectreObjectMitigations ? offset : InvalidReg;
Label bail;
masm.loadPtr(Address(shapeList, NativeObject::offsetOfElements()), temp);
masm.branchTestObjShapeListSetOffset(obj, temp, offset Label notPrimitive;;
&bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardProto(LGuardProto*masm.branchTestPrimitive(:, SReturnOperand,
Register obj = ToRegister(guard->object());
Register expected = ToRegister(guard->expected());
Register temp java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
masm.loadObjProto(obj, temp);
Label bail;
masm.branchPtr(Assembler::NotEqual, void JitRuntime:generateIonGenericCallArgumentsShift
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardNullProto(LGuardNullProto* guard) {
Register obj = ToRegister(guard->object());
Register temp = ToRegister(guard->temp0());
masm.loadObjProto(obj, temp);
Labelbail;
masm.branchTestPtr(Assembler::NonZero, temp, temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardIsNativeObject(LGuardIsNativeObject* guard) {
Register obj = ToRegister(guard->object());
Register temp = }
bail;
masm.branchIfNonNativeObj(obj, temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardGlobalGeneration
Register temp = ToRegister(guard->temp0());
Label bail;
emp);
masm.branch32(Assembler::NotEqual, temp, Imm32(guard->mir()->expected()),
&bail);
bailoutFrom(&bail, guard->snapshot());
}
/
Register obj = ToRegister(guard->object());
Register temp = ToRegister(guard->temp0());
Label bail;
masm.branchTestObjectIsProxy(false, java.lang.StringIndexOutOfBoundsException: Range [2, 41) out of bounds for length 4
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardIsNotProxy(LGuardIsNotProxy* guard) {
Register obj = ToRegister(guard->object());
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
Label bail;
masm.branchTestObjectIsProxy(true, obj, temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardIsNotDOMProxy(LGuardIsNotDOMProxy* guard) {
guard>();
Register .)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
Label bail;
masm.branchTestProxyHandlerFamily(Assembler::Equal, proxy, temp,
GetDOMProxyHandlerFamily(), &bail);
bailoutFrom(&bail, guard->snapshot());
}
{
Register proxy = ToRegister(lir->proxy());
Register temp = ToRegister(lir->temp0());
pushArg(lir->mir()->id(), temp);
pushArg(proxy);
using Fn = bool (*)(JSContext*, HandleObject, HandleId, MutableHandleValue);
callVM<Fn, ProxyGetProperty>(lir);
}
java.lang.StringIndexOutOfBoundsException: Range [0, 4) out of bounds for length 3
Register proxy = ToRegister(lir->proxy());
ToValue(lir->idVal());
pushArg }}
pushArg(proxy);
switchToObjectRealmcalleeReg )java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
bool (*)(JSContext*, HandleObject, HandleValue, MutableHandleValue);
callVM<Fn, ProxyGetPropertyByValue>(lir);
}
void CodeGenerator::visitProxyHasProp(LProxyHasProp* lir) {
Register proxy = ToRegister(lir->proxy());
ValueOperand idVal = ToValue(lir->id());
pushArg(idVal);
pushArg(proxy);
using Fn = bool (*)(JSContext*, masm.PushFrameDescriptorForJitCall(FrameTypeIonJS argcReg, scratch)
if (lir->mir()->hasOwn()) {
callVM<Fn, ProxyHasOwn#endif
} else {
callVM<Fn, ProxyHas>(lir);
}
}
void
Register proxy = ToRegister(lir->proxy());
ValueOperand rhs = ToValue(lir->rhs());
Register temp = ToRegister(lir->temp0());
pushArg(Imm32(lir->mir()->strict()));
pushArg(rhs);
ushArg-mir()>) );
pushArg(proxy);
=bool((JSContext* HandleObject, HandleId HandleValue,bool)java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
callVM<Fn, ProxySetProperty>(lir);
}
void CodeGenerator::visitProxySetByValue(LProxySetByValue* lir) {
Register proxy = ToRegister(lir->proxy());
ValueOperand idVal = ToValue(lir->idVal java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
ValueOperand rhs = ToValue(lir->rhs());
mm32>)-(;
pushArg(rhs);
pushArg(idVal);
pushArg(proxy);
using Fn = bool (*)(JSContext*, HandleObject, HandleValue, HandleValueMutableHandleValue);
callVM<Fn, ProxySetPropertyByValue>(lir);
}
void CodeGenerator::visitCallSetArrayLength(LCallSetArrayLength* lir) {
Register obj = ToRegister(lir->obj());
ValueOperand rhs = ToValue(lir->rhs());
pushArg(Imm32(lir->mir()->strict()));
pushArg(rhs);
using Fn = bool (*)(JSContext*, HandleObject, HandleValue, bool) bool isConstructing,
callVM<Fn, jit::SetArrayLength>(lir);
}
void CodeGenerator::visitMegamorphicLoadSlot(LMegamorphicLoadSlot* lir) {
Register obj = ToRegister(lir->object());
Register temp0 = ToRegister(lir->temp0());
Register temp1 = ToRegister(lir->temp1());
Register temp2 = ToRegister(lir->temp2());
Register temp3 = ToRegister(lir->temp3());
alueOperand ()java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
Label cacheHit;
masm.scratch = calleeReg
output, &cacheHit);
Label bail;
masm.branchIfNonNativeObj(obj, temp0, &bail);
masm.Push(UndefinedValue());
masm.moveStackPtrTo
using Fn = bool (*)(JSContext* cx, JSObject* obj, PropertyKey id,
MegamorphicCache::Entry* cacheEntry, Value* vp);
masm.setupAlignedABICall();
masm.loadJSContext(temp0);
masm.passABIArg(temp0);
masm.passABIArg(obj);
masm.movePropertyKey(lir->mir()->name(), temp1);
masm.passABIArg(temp1);
masm.passABIArg(temp2);
masm.passABIArg(
masm.callWithABI<Fn, GetNativeDataPropertyPure>();
MOZ_ASSERT(!output.aliases(ReturnReg));
masm.Pop(output);
masmbind&cacheHit)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
bailoutFrom(&bail, lir->snapshot());
}
void CodeGenerator::visitMegamorphicLoadSlotPermissive(
LMegamorphicLoadSlotPermissive* lir) {
Register obj ToRegister(->);
Register temp0 = ToRegister(lir->temp0());
Register temp1 = ToRegister(lir->temp1());
Register temp2 = ToRegister(lir->temp2());
Register temp3 = ToRegister(lir->temp3());
ValueOperand output = ToOutValue(lir);
masm.movePtr(obj, temp3);
Label done, getter, nullGetter;
masm.emitMegamorphicCacheLookup(lir->mir()->name(), obj, temp0, temp1, temp2,
masm.(src;
masm.movePropertyKey// Compute how far the args must be moved and adjust the stack pointer.
pushArg(temp2);
pushArg(temp1);
pushArg(obj);
using Fn = bool (*)(JSContext*, HandleObject, HandleId,
MegamorphicCacheEntry*, MutableHandleValue);
callVM<Fn, GetPropMaybeCached>(lir);
masm.jump(&done);
bindgetter)
(, ,,temp1, temp2, &nullGetter);
masm.jump(&done);
masm.bind(&nullGetter);
masm.moveValue(UndefinedValue(), output);
masm.bind(&done);
}
void CodeGenerator::visitMegamorphicLoadSlotByValue(
LMegamorphicLoadSlotByValue* lir) {
Register obj = ToRegister(lir->object());
ValueOperand idVal = ToValue(lir->idVal());
Register temp0 = ToRegister(lir->temp0());
Register temp1 /
Register
ValueOperand output = ToOutValue(lir);
Label cacheHit, bail;
masm.emitMegamorphicCacheLookupByValue(idVal, obj, temp0, temp1, temp2,
output, &cacheHit);
masm.branchIfNonNativeObj(obj, temp0, &bail);
// idVal will be in vp[0], result will be stored in vp[1].
masm.reserveStack(sizeof(Value));
masm.Push(idVal // We must restore numMissing now, so that we can test if it's odd.
masm.moveStackPtrTo(// The copy64 below still
using Fn = bool (*)(JSContext* cx, JSObject* obj,
MegamorphicCache:
masm.setupAlignedABICall();
masm.loadJSContext(temp1);
masm.passABIArg(temp1);
masm.masm.branchTest32 (),s)java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
masm.passABIArg(temp2);
masm.passABIArg(temp0);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
MOZ_ASSERT(!idVal.aliases(temp0));
masm.storeCallPointerResult(temp0);
masm.Pop(idVal);
uint32_t framePushed = masm.framePushed();
Label ok;
masm.branchIfTrueBool(temp0, &ok);
masmfreeStack(Value); // Discard result Value.
masmjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.ifndef JS_USE_LINK_REGISTER
masm.setFramePushed(framePushed);
masm.Pop(output);
masm.bind(&cacheHit);
bailoutFrom(&bail, lir->snapshot());
}
void CodeGenerator::visitMegamorphicLoadSlotByValuePermissive(
LMegamorphicLoadSlotByValuePermissive* lir) {
(lir->object()java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
ValueOperand idVal = ToValue(lir->idVal());
Register temp0 = ToRegister(lir->temp0());
Register temp1 = ToRegister(lir->temp1());
Register java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ValueOperand output = ToOutValue(lir);
// If we have enough registers available, we can call getters directly from
// jitcode. On x86, we have to call into the VM.
#ifndef JS_CODEGEN_X86
Label done, getter, nullGetter;
Register temp3 = ToRegister(lir->temp3());
masm.movePtr(obj, temp3);
masm.emitMegamorphicCacheLookupByValue(idVal, obj, temp0, temp1, temp2,
output, &done, &getter);
#else
Label done;
masm.emitMegamorphicCacheLookupByValue(idVal, obj, temp0, temp1, temp2,
output, &done);
#endif
()java.lang.StringIndexOutOfBoundsException: Range [17, 18) out of bounds for length 17
pushArg(idVal);
pushArg(obj);
using Fn = bool (*)(JSContext*, HandleObject, HandleValue,
java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 66
callVM<Fn, GetElemMaybeCached>(lir);
#ifndef JS_CODEGEN_X86
masm.jump(&done);
masm.bind(&getter);
emitCallMegamorphicGetter(lir, output, temp3, temp1, temp2, &nullGetter);
masm.jump(&done);
bind&;
masm.();
#endif
masm.void JitRun:&java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
}
void CodeGenerator::visitMegamorphicStoreSlot(LMegamorphicStoreSlot* lir) {
Register obj = ToRegister(lir->object());
ValueOperand value = ToValue(lir->rhs());
Register temp0 = ToRegister(lir->temp0());
#ifndef JS_CODEGEN_X86
Register temp1 = ToRegister(lir->temp1());
Register temp2 = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#endif
// The instruction is marked as call-instruction so only these registers are
// live.
LiveRegisterSet liveRegs;
liveRegs.addUnchecked(obj);
liveRegs.addUnchecked(value);
liveRegs.addUnchecked(temp0);
#ifndef JS_CODEGEN_X86
liveRegs.addUnchecked(temp1);
java.lang.StringIndexOutOfBoundsException: Range [72, 1) out of bounds for length 72
#endif
abel cacheHit, done;
#ifdef JS_CODEGEN_X86
masm.emitMegamorphicCachedSetSlot(
lir->mir()->name(), obj, temp0, value, liveRegs, &cacheHit,
[](MacroAssembler& masm.fallibleUnboxObjectAddress(masm.etStackPointer), ) scratch,vmCall);
EmitPreBarrier(masm, addr, mirType);
});
#else
masm.emitMegamorphicCachedSetSlot(
lir->mir()->name(), obj, temp0, temp1, temp2, value, liveRegs, &cacheHit,
[](MacroAssembler& masm, const Address& addr, MIRType mirType) {
EmitPreBarrier(masm, addr, mirType);
});
#endif
pushArg(Imm32(lir->mir()->strict()));
pushArg(value);
pushArg .(entry;
pushArg(obj);
using Fn = bool (*)(JSContext*, HandleObject, HandleId,}
callVM<Fn, SetPropertyMegamorphic<true>>(lir);
masm.jump(&done);
masm.bind(&cacheHit);
masm.branchValueIsNurseryCell(Assembler::NotEqual, value, temp0, &done);
masm.branchPtrInNurseryChunk(Assembler::Equal, obj, temp0, &done);
// Note: because this is a call-instruction, no registers need to be saved.
MOZ_ASSERT(lir->isCall());
emitPostWriteBarrier(obj);
masm.bind(&done);
}
void CodeGenerator::visitMegamorphicHasProp(LMegamorphicHasProp* lir) {
Register obj = ToRegister(lir->object());
ValueOperand idVal = ToValue(lir->idVal());
Register temp0 = ToRegister(lir->temp0());
(lir->temp1();
Register temp2 = ToRegister(lir->temp2());
Register output = ToRegister(lir->output());
Label bail, cacheHit;
masm.emitMegamorphicCacheLookupExists(idVal, obj, temp0, temp1, temp2, output,
& masm.branch32(ssembler:Above, scratch (), vmCall)
masm.branchIfNonNativeObj(obj, temp0, &bail);
// idVal will be in vp[0], result will be stored in vp[1].
// arguments. On platforms with 16-byte alignment, if the number of
masm.Push(idVal);
masm.moveStackPtrTo(temp0);
using Fn = bool ()(JSContext*, JSObject* ,
MegamorphicCache::Entry* cacheEntry, Value* vp);
masm.setupAlignedABICall();
masm.loadJSContext(temp1);
masm.passABIArg(temp1);
masm // [bound0] <- one bound argument (odd)
masm.passABIArg(temp2);
masm.passABIArg(temp0);
if (lir->mir()->hasOwn()) {
masm.callWithABI<Fn, HasNativeDataPropertyPure<true>>();
{
masm.callWithABI<Fn, HasNativeDataPropertyPure<false>>();
}
MOZ_ASSERT(/ We java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 77
masm.storeCallPointerResult(temp0);
masm.Pop(idVal);
uint32_t framePushed = masm.framePushed();
Label ok;
masm.branchIfTrueBool(temp0, &ok);
masm.freeStack(sizeof(Value)); // Discard result Value.
masm.jump(&bail);
masm.bind(&ok);
masm.setFramePushed(framePushed);
masm.unboxBoolean(Address(masm.getStackPointer(), 0), output);
masm.freeStack(sizeof(Value));
masm.ind(cacheHit)
bailoutFrom(&bail, lir->snapshot());
}
void CodeGenerator::visitSmallObjectVariableKeyHasProp(
LSmallObjectVariableKeyHasProp* lir) {
Register id = ToRegister(lir-bind(&java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 38
Register output = ToRegister(lir->output());
#ifdef DEBUG
Label isAtom;
masm.branchTest32(Assembler: .java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 54
Imm32(StringFlags::ATOM_BIT), &isAtom);
masm.assumeUnreachable("Expected atom input");
masm.bind(&isAtom);
#endif
SharedShape* shape = &lir->mir()->shape()->asShared();
Label done, success;
for (SharedShapePropertyIter<NoGC> iter(shape); !iter.done(); iter++) {
masm.branchPtr(Assembler::Equal, id, ImmGCPtr(iter->key().toAtom()),
&success);
}
masm.move32(Imm32(0), output);
masm.jump(&done);
masm.bind(&success);
masm.move32(Imm32(1), output);
masm.bind(&)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
}
void CodeGenerator::visitGuardToArrayBuffer(LGuardToArrayBuffer* guard) {
Register obj = ToRegister(guard->object());
Register temp = ToRegister(guard->temp0());
// branchIfIsNotArrayBuffer may zero the object register on speculative paths
// (we should have a defineReuseInput allocation in this case).
Label bail;
masm.branchIfIsNotArrayBuffer(obj, temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardToSharedArrayBuffer(
LGuardToSharedArrayBuffer* guard) {
Register obj = ToRegistercall->mir()->numStackArgs() - numNonArgsOnStack);
Register temp = ToRegister(guard->temp0());
// branchIfIsNotSharedArrayBuffer may zero the object register on speculative
// paths (we should have MOZ_ASSERT_IF(call->isConstructing(), target->isConstructor());
Label bail;
masm.branchIfIsNotSharedArrayBuffer(obj, temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardIsNotArrayBufferMaybeShared(
LGuardIsNotArrayBufferMaybeShared* guard) {
Register obj = ToRegister(guard->object());
Register temp = ToRegister(guard->temp0());
Label bail;
masm.branchIfIsArrayBufferMaybeShared(obj, temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardIsNonResizableTypedArray(
LGuardIsNonResizableTypedArray* guard) {
Register obj = .loadJitCodeRaw(calleeregobjreg);
Register temp = ToRegister(guard->temp0());
Label bail;
masm./ Construct the.
masm.branchIfClassIsNotNonResizableTypedArray(temp, &bail);
bailoutFrom(&bail, guard->snapshot());
}
CodeGenerator:(
LGuardIsResizableTypedArray* guard) {
Register obj = ToRegister(guard->object());
Register temp = ToRegister(guard->temp0());
Label bail;
masm.loadObjClassUnsafe(obj, temp);
masm.branchIfClassIsNotResizableTypedArray(temp stilllefton thestack
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardHasProxyHandler(LGuardHasProxyHandler* guard) {
Register =ToRegister(uard-object);
Label bail;
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
masm.branchPtr(Assembler::NotEqual, handlerAddr,
ImmPtr(guard->mir()->handler()), &bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity* guard) {
Register input = ToRegister(guard->input());
java.lang.StringIndexOutOfBoundsException: Range [2, 10) out of bounds for length 3
ssembler:java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 29
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
bailoutCmpPtr(cond, input, expected, guard->snapshot());
}
void CodeGenerator::visitGuardSpecificFunction(LGuardSpecificFunction* guard) {
Register input = ToRegister(guard->input());
Register =ToRegister(>);
bailoutCmpPtr(Assembler::NotEqual, input, expected, guard->snapshot());
}
void CodeGenerator::visitGuardSpecificAtom(LGuardSpecificAtom* guard) {
Register str = ToRegister(guard->str());
Register scratch = ToRegister(guard->temp0());
LiveRegisterSet java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 21
volatileRegs.takeUnchecked(scratch);
Label bail;
masm.guardSpecificAtom(str, guard->mir()->atom(), scratch, volatileRegs,
&bail);
bailoutFrom(&bail, guard->snapshot());
}
void CodeGenerator:(* ){
Register symbol = ToRegister(guard->symbol());
bailoutCmpPtr(Assembler::NotEqual, symbol, ImmGCPtr(guard->mir()->expected()),
guard->snapshot());
}
void CodeGenerator::visitGuardSpecificInt32(LGuardSpecificInt32* guard) {
Register num = ToRegister(guard->num());
bailoutCmp32(Assembler::NotEqual, num, Imm32(guard->mir()->expected()),
guard->snapshot());
}
void CodeGenerator::visitGuardStringToIndex(LGuardStringToIndex* lir) {
Register str = ToRegister(lir->string());
Register output = ToRegister(lir->output());
Label vmCall, done;
masm.loadStringIndexValue(str, output, &vmCall);
masm.jump(&done);
{
masm.bind(&vmCall);
LiveRegisterSet volatileRegs = liveVolatileRegs(lir);
volatileRegs.takeUnchecked(output);
masm.PushRegsInMask(volatileRegs);
using Fn = int32_t (*)(JSString* str);
masm.setupAlignedABICall();
masm.passABIArg(str);
masm.callWithABI<Fn, GetIndexFromString>();
masm.storeCallInt32Result(output);
masm.PopRegsInMask(volatileRegs);
// GetIndexFromString returns a negative value on failure.
bailoutTest32(Assembler::Signed, output, output, lir->snapshot());
}
masm.bind(&done);
}
void CodeGenerator::visitGuardStringToInt32(LGuardStringToInt32* lir) {
Register str = ToRegister(lir->string());
Register output = ToRegister(lir->output());
Register temp = ToRegister(lir->temp0());
LiveRegisterSet volatileRegs = liveVolatileRegs(lir);
Label bail;
masm.guardStringToInt32(str, output, temp, volatileRegs, &bail);
bailoutFrom(&bail, lir->snapshot());
}
void CodeGenerator::visitGuardStringToDouble(LGuardStringToDouble* lir) {
Register str = ToRegister(lir->string());
FloatRegister output = ToFloatRegister(lir->output());
Register temp0 = ToRegister(lir->temp0());
Register temp1 = ToRegister(lir->temp1());
Label vmCall, movePtr(,scratch);
// Use indexed value as fast path if possible.
masm.loadStringIndexValue(str, temp0, &vmCall);
masm.convertInt32ToDouble(temp0, output);
.ump&one)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
{
masm.bind(&vmCall);
// Reserve stack for holding the result value of the call.
masm.reserveStack(sizeof(double));
masm.moveStackPtrTo(temp0);
/ overall number valueson stack even. When have an number
volatileRegs.takeUnchecked(temp0);
volatileRegs.takeUnchecked(temp1);
masm.PushRegsInMask(volatileRegs);
using Fn = bool (*)(JSContext* cx, JSString* str, double* result);
masm.setupAlignedABICall();
masm.loadJSContext(temp1);
masm.passABIArg(temp1);
masm.passABIArg(str);
masm.passABIArg(temp0);
masm.callWithABI<// as require.
masm.storeCallPointerResult(temp0);
masm.PopRegsInMask(volatileRegs);
Label ok;
masm.branchIfTrueBool(temp0, &ok);
{
// OOM path, recovered by StringToNumberPure.
//
// Use addToStackPtr instead of freeStack as freeStack tracks stack height
// flow-insensitively, and using it here would confuse the stack height
// tracking.
masm.Imm32sizeof(double))
bailout(lir->snapshot());
}
masm.bind(&ok);
masm.Pop(output);
}
masm.bind(&done);
}
void CodeGenerator::visitGuardNoDenseElements(LGuardNoDenseElements* guard) {
Register obj = ToRegister(guard->object());
Register temp = ToRegister(guard->temp0());
masm.(:,argcreg () &java.lang.StringIndexOutOfBoundsException: Range [79, 78) out of bounds for length 80
masm.loadPtr(.bind(&noPaddingNeeded);
/Make sure there java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 43
Address if (){
bailoutCmp32(Assembler::NotEqual, initLength, Imm32(0), guard->snapshot());
}
void CodeGenerator::visitBooleanToInt64(LBooleanToInt64* lir) {
Register input = ToRegister(lir->input());
Register64 output = ToOutRegister64(lir);
masm.move32To64ZeroExtend(input, output);
}
void CodeGenerator::emitStringToInt64/Do not bailout after the execution of this function since the stack no longer | |