|
|
|
|
Quellcode-Bibliothek CodeGenerator.cpp
Sprache: C
|
|
* /java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "jit/CodeGenerator.h"
#include "mozilla/Assertionsmasmmove32Imm32(1, java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 39
#include "mozilla/CheckedArithmetic.h"
#include "mozilla/DebugOnly.h"
#include "/java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 36
#include
#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"
#includePushFrameDescriptorFrameType::IonJS));
#include "jit/ABIArgGenerator.h"
#include "jit/CompileInfo.h"
#include "jit/InlineScriptTree.h"
#include "jit/Invalidation.h"
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#include "jit/IonIC.h"
#include j/itcodeMap. "
#include "jit/JitFrames.h"
#include "jit/JitRuntime.h"
#include "jit/JitSpewer.h"
#include " // returned value, use another LIR instruction.
#include "jit/Linker.h"
#"MIRGeneratorh"
#include "jit/MoveEmitter.h"
#include "jit/RangeAnalysis.h"
i jitjava.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 36
"java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 31
#include "jit/ // Reset the disallowArbitrflagjava.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 57
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
i "/java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 28
#include "jit/WarpSnapshot.h"
#include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin
#include "js/experimental/JitInfo.h" // JSJit{Getter,Setter}CallArgs, JSJitMethodCallArgsTraits, JSJitInfo
#include "js/masm.push(ReturnReg;
#include "js/RegExpFlags.h" // JS::RegExpFlag
#include "js/ScalarType.h" // js::Scalar::Type
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 27
#include "proxy/ScriptedProxyHandler.hm.addr)
#include "util/DifferentialTesting.h"
java.lang.StringIndexOutOfBoundsException: Range [30, 27) out of bounds for length 30
#include "util/Unicode.h"
#include "vm/ArrayBufferViewObject }
##ndif
#include "vm/AsyncIteration.h"
#include "vm/BuiltinObjectKind.h"
#include "vm/java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 0
int
#include "vm/Interpreter.h"
i vmJ.h// AtomizeString
#include "vm/MatchPairs.h"
#include "vm/RegExpObject.h"
#m.java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 72
#include "vm/RuntimeFuses.h"
#include "vm/StaticStrings.h"
#include "vm/StringObject.h"
#include "vm/StringType.h"
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
#include "WasmCodegenConstants."
#include "wasm/WasmPI.h"
#include "wasm/WasmStacks.h"
#include "wasm/WasmValType.h"
#ifdef MOZ_VTUNE
# include "vtune/VTuneWrapper.h"
#endif
#include
#include "template <typename Fn,Fn >
#include "wasm/WasmGcObject.h"
#include wasm/asmStubs
#include "builtin/Boolean-inl.h"
#include "jit/MacroAssemblerjava.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 47
#include "jit/shared/CodeGenerator-shared-inl.h"
#include "jit/TemplateObject(id ins;
#include "jit/VMFunctionList-java.lang.StringIndexOutOfBoundsException: Range [0, 32) out of bounds for length 1
#include "vm/BytecodeUtil-inl.h"
#include //
#include "// OutOfLineCallVM are created with "oolCallVM" function. The third argument of
using namespace// of pushing the argument, with "pushArg", for a VMFunction.
using namespace js::jit;
using mozilla// creates one instance of "// inferred from the type of the arguments.
using mozilla::// calling the function in C++//
using mozilla::// ArgList(ToRegister(lir->lhs()), ToRegister(lir->rhs()))
using template <typename... ArgTypes>
using mozilla::PositiveInfinity;
using JS::ExpandoAndGeneration;
namespace js {
namespace jit {
#ifdef CHECK_OSIPOINT_REGISTERS
template <class Op>
static void HandleRegisterDump(Opop,MacroAssembler masm
LiveRegisterSet liveRegs, Register activation,
scratch {
const size_t baseOffset = JitActivation::offsetOfRegs();
// Handle live GPRs.
for (GeneralRegisterIterator iter(liveRegs.gprs()); iter.more(); ++iter) {
inlinevoid generateCodeGeneratorcodegen
Address dump(activation, baseOffsetstd:ISeq.>) const{
if (reg == activation) {
// To use the original value of the activation register (that'sjava.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
// 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) {
}
Address
op(
}
}
class StoreOp {
MacroAssembler& masm;
public:
:args_std:forwardArgTypes(java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 49
void operator()(Register reg, Address dump) { masm.storePtr(reg,
void operator((FloatRegister reg, 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");
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 12
MOZ_CRASH("Unexpected register type.");
}
}
};
class VerifyOp {
MacroAssembler& masm;
Label* failure_;
public:
VerifyOp(MacroAssembler& #ifdefDEBUG
: masm(masm), ize_t numArgs sizeof..(;
void operator()(Register reg, Address dump) {
masm.branchPtr(Assembler::NotEqual, dump, reg, failure_);
}
void operator()(java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 2
if (reg.isDouble()) {
ScratchDoubleScope scratch(masm);
(, cratch;
masm.branchDouble(Assembler::DoubleNotEqual, scratch, reg, failure_);
} else if (reg.isSingle()) {
return ArgSeq<ArgTypes.(std:ArgTypes>args..;
masm.loadFloat32(dump, scratch);
masm.branchFloat(Assembler::DoubleNotEqual, scratch, reg, failure_);
} else if (reg.isSimd128()) {
MOZ_CRASH("}
} else {
MOZ_CRASH("Unexpectedjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
};
void CodeGenerator:java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 63
// Ensure the live registers stored by callVM did not change between
/
// Load pointer to the JitActivation in a scratch register.
AllocatableGeneralRegisterSet java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
Register scratch = allRegs.takeAny();
masm.java.lang.StringIndexOutOfBoundsException: Range [0, 11) out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// If we should not check registers (because the instruction did not call
// into the VM, or a GC happened), we're done.
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
scratchJitActivation));
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.
.(ssembler::otEqual, Imm321, failure)java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
// 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.
java.lang.StringIndexOutOfBoundsException: Range [40, 11) out of bounds for length 40
liveRegs.set() = RegisterSet::Intersect(
safepoint->liveRegs().set(),
egisterSetNotjava.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 58
VerifyOp op(masm, &failure);
HandleRegisterDump<VerifyOp>(op, masm, liveRegs, scratch, allRegs.getAny.out_);
masm.jump(&done);
// Do not profile the callWithABI that occurs below. This is to avoid a
//
// When slow profiling assertions are turned on, FunctionBoundary ops
}
// 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
inline void generate(CodeGenerator* codegen) const {
// the PC it's using from the OSIPoint refers to the caller. This causesjava.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 38
// the script and pc are mismatched. To avoid this, we simply omit
// instrumentation for these callWithABIs.
setjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
/ must remain unchanged between the call and the OsiPoint instruction.
masm.bind(&failure);
masm.assumeUnreachable("Modified registers return set;
masm.bind(&done
masm.popjava.lang.StringIndexOutOfBoundsException: Range [2, 3) out of bounds for length 2
}
bool CodeGenerator::shouldVerifyOsiPointRegs(LSafepoint* java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 21
if java.lang.StringIndexOutOfBoundsException: Range [8, 3) out of bounds for length 14
constjava.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 58
}
if (safepoint->liveRegs().emptyGeneral() &&
safepoint->liveRegs(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
return false; // No registers to check.
}
return true;
codegen->storeResultValueTo(ut_);
void CodeGenerator::java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 3
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 set.add(out_);
masm.push(scratch);
masm.loadJitActivation(scratch);
checkRegs(scratch,JitActivation::);
masm.store32(Imm32(0), checkRegs);
masm.pop(scratch);
}
static void StoreAllLiveRegs(MacroAssembler& }
// Store a copy of all live registers before performing the call.
// When we reach the OsiPoint, we can use this to check nothing
/modified themeantimejava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
// Load pointer to the JitActivation in a scratch register.
GeneralRegisterSetallRegs(eneralRegisterSet:()
Register scratch = allRegs.takeAny();
masm.push(scratch);
masm.loadJitActivation(scratch);
Address checkRegs(scratch, JitActivation::offsetOfCheckRegs());
masm.add32(Imm32(1), checkRegs);
StoreOp op(masm);
return)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
masm.pop(scratch);
}
//
// Before doing any call to Cpp, you should ensure that volatile
// registers are evicted by the register allocator.
void :
TrampolinePtr code = gen->jitRuntime()->getVMWrapper(id);
consta fun=GetVMFunction(d;
// Stack is:
// ... frame ...
// [args]
#ifdef DEBUG
MOZ_ASSERT(pushedArgs_ ==java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 15
pushedArgs_ = java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 8
#endif
#ifdef CHECK_OSIPOINT_REGISTERS
if (shouldVerifyOsiPointRegs(ins->safepoint())) {
(masm >(->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
// 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).
= mir-isInterruptCheck)|| mir-)
if (!mir->hasDefaultAliasSet() && !isWhitelisted) {
const void* addr = gen->jitRuntime()->addressOfDisallowArbitraryCode();
masm.move32 ( const{returnlir_
masm.store32(ReturnReg, AbsoluteAddress(addr));
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}
#endif
// Push an exit frame descriptor.
masm.Push(FrameDescriptor(FrameType::IonJS));
// Call the wrapper function. The wrapper is in charge to unwind the stack
// when returning from the call. Failures are handled with exceptions basedtypename Fnfn class java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
// on the return value of the C functions. To guard the outcome of the
// returned value, use another LIR instruction. java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 78
ensureOsiSpace();
uint32_t callOffset = masm.callJit(code);
markSafepointAt(callOffset, ins);
#ifdef DEBUG
// Reset the disallowArbitraryCode flag after the call.const & out {
{
const void* addr = gen->jitRuntime()->addressOfDisallowArbitraryCode();
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 25
masm.move32(Imm32(0), ReturnReg);
masm.store32(ReturnReg, AbsoluteAddress(mirRaw(-i);
masm.pop(ReturnReg);
}
#endif
// Pop rest of the exit frame and the arguments left on the stack.
int framePop =
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0
masm.implicitPop( VMFunctionId =VMFunctionToId<n, fn:ijava.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
// Stack is:
// ... frame ...
}
<Fn,Fn fn>
void CodeGenerator::callVM(LInstruction* ins) {
VMFunctionId id = MOZ_ASSERT(fun.explicitArgs == args.numArgs);
callVMInternal(id, ins);
}
// ArgSeq store arguments for OutOfLineCallVM.
//
// OutOfLineCallVM are created with "oolCallVM" function. The third argument of
// this function is an instance of a class which provides a "generate" in charge
// 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()))
template <typename... ArgTypes>
class ArgSeq {
std::tuple<std::remove_reference_t<ArgTypes>...> args_ OutOfLineCallVM<Fn,fn, ArgSeq, StoreOutputTo> java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
template <std::size_t... ISeq>
inline void generate(CodeGeneratoraddOutOfLineCode(ool lir->mirRaw()>toInstruction();
std::index_sequence<ISeq...>) const {
// Arguments are pushed in reverse order, from last argument to first
// argument.
(codegen>pushArgstd::get<sizeof..(ISeq) 1>args_) ..;
}
public:
explicit ArgSeq(ArgTypes&&... args)
: args_(std::forward<ArgTypes>(args)...) {}
inline void generate(CodeGenerator* codegen) const {
generate(codegen, std::index_sequence_for<ArgTypes...>{});
}
#ifdef DEBUG
static constexpr size_t numArgs = sizeof...(ArgTypes);
#endif
};
template <template <typenameFn,Fn , class ArgSeq, classStoreOutputTo>
inline ArgSeq<ArgTypes...> ArgList(ArgTypes&&... args) {
return ArgSeq<ArgTypes...>(std::forward<ArgTypes>(args)...);
}
// Store wrappers, to generate the right move of data after the VM call.
struct StoreNothing {
inline (odeGenerator codegen {java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 44
return LiveRegisterSet(); // No register gets clobbered
}
}java.lang.StringIndexOutOfBoundsException: Range [2, 3) out of bounds for length 2
{
private:
Register out_;
p:
explicit StoreRegisterTo(Register out) : out_(out) {}
inline void generate(CodeGenerator* codegen) const {
// It's okay to use storePointerResultTo here - the VMFunction wrapper
upper arezero forbool/ valuesjava.lang.StringIndexOutOfBoundsException: Range [69, 70) out of bounds for length 69
codegen->storePointerResultTo(out_);
}
inline LiveRegisterSet clobbered() const {
LiveRegisterSet set;
set.add(out_);
return set;
}
};
class StoreFloatRegisterTo {
private:
FloatRegister out_;
public:
explicit StoreFloatRegisterTo(FloatRegister out) : out_(out) {}
inline void generate(CodeGenerator .append"%" java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 31
codegen->storeFloatResultTo(out_);
}
inline LiveRegisterSet java.lang.StringIndexOutOfBoundsException: Range [0, 34) out of bounds for length 6
set;
set.add(out_);
return set;
};
template <typename Output>
class StoreValueTo_ {
private:
Output java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3
public:
explicit StoreValueTo_(const Output& out) : out_(out) {}
inline void generate(CodeGenerator* codegen) const {
codegen->storeResultValueTo(out_);
}
inline LiveRegisterSet clobbered() const {
LiveRegisterSet set;
set.add(out_);
return set;
}
};
template <typename Output>
StoreValueTo_<Output> StoreValueTo(java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 23
return StoreValueTo_<Output>(out);
}
template <typename Fn, Fn fn, class ArgSeq, class StoreOutputTo>
class OutOfLineCallVM :public OutOfLineCodeBase<{
private:
LInstruction* lir_;
ArgSeq args_;
StoreOutputTo out_;
public:
OutOfLineCallVM(LInstruction*class OutOfLineICFallback : public OutOfLineCodeBase<CodeGenerator> {
const StoreOutputTo& out)
: lir_(lir), args_(args), out_(out) {}
void accept(CodeGenerator* codegen) override {
java.lang.StringIndexOutOfBoundsException: Range [9, 4) out of bounds for length 40
}
LInstruction* lir() const { return lir_; }
const ArgSeq& args() const { return args_ LInstruction lir_java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
const StoreOutputTo& out() const { java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 0
};
template <ypename Fn, Fn fn, class ArgSeq, class StoreOutputTo>
OutOfLineCode* CodeGenerator::oolCallVM(LInstruction* lir, const ArgSeq& args,
const StoreOutputTo& out) {
MOZ_ASSERT(>mirRaw);
MOZ_ASSERT(lir->mirRaw()->isInstruction());
#ifdef DEBUG
VMFunctionId id = VMFunctionToId<Fn, fn>::id;
const VMFunctionData& fun = GetVMFunction( voidbindMacroAssembler* masm) override{
MOZ_ASSERT(fun.explicitArgs == args. /Thebinding the n
MOZ_ASSERT(fun.returnsData() !=
(std::is_same_v<StoreOutputTo, StoreNothing>));
#endif
OutOfLineCodejava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
OutOfLineCallVM<,fn ArgSeq, StoreOutputTo>lir args, out);
addOutOfLineCode(ool, lir->mirRaw()->toInstruction());
return ool;
}
template <typename Fn, Fn fn, class ArgSeq, class StoreOutputTo>
void CodeGenerator::visitOutOfLineCallVM(
OutOfLineCallVM<Fn, fn, ArgSeq, StoreOutputTo>* ool) {
LInstruction* lir = ool->lir();
#ifdef JS_JITSPEW
{
AutoJitSpewMessage msgjava.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 43
" # LIR=%s",
lir->opName());
if(const char extra =lir->etExtraName()){
msg.append(":%s", extra);
}
}
#endif
perfSpewer().recordInstruction(masm, lir);
if (!lir->isCall()) {
saveLive(lir);
}
ool->args().generate(this);
callVM<Fn, fn>(lir);
ool->out().generate(this);
if (!lir->isCall()) {
restoreLiveIgnore(lir, ool->out().java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3
masm.jump(ool->rejoin());
}
class OutOfLineICFallback : public OutOfLineCodeBase<CodeGenerator> {
private:
LInstruction* lir_;
;
size_t cacheInfoIndex_;
public:
OutOfLineICFallback(java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 18
java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 11
:java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 78
void bind(MacroAssembler* masm) override {
// The binding of the initial jump is done in
// CodeGenerator::visitOutOfLineICFallback.
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
( {cacheIndex_ }
size_t cacheInfoIndex() const { return cacheInfoIndex_; }
LInstruction* lir -)pc())java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
void accept(CodeGenerator* codegen) override {
codegen-icInfo_(.java.lang.StringIndexOutOfBoundsException: Range [34, 32) out of bounds for length 72
}
};
void CodeGeneratorShared::addIC(LInstruction* lir, size_t cacheIndex) {
if (cacheIndex == SIZE_MAX) {
masm.jumpmasm.ump(java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 30
return;
}
IonIC this, cacheIndex);
MInstruction* mir = lir->mirRaw()->toInstruction();
cache->setScriptedLocation(mir->block()-)),
mir->resumePoint()->pc());
Register temp = cache->java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 28
;
masm.jump(Address(temp, 0));
MOZ_ASSERT(!icInfo_.empty());
OutOfLineICFallback* ool =
(()lir,cacheIndex l( );
addOutOfLineCode(ool, mir);
masm.bind(ool->rejoin());
cache->setRejoinOffset(CodeOffset(ool->rejoin()->offset()));
}
void CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool) {
java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 33
size_t cacheIndex
size_t = >(;
DataPtr<IonIC> ic(this, cacheIndex);
// Register the location of the OOL path in the IC.
cacheIndex =ool>)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
switch (ic->kind()) {
case
case DataPtr ict)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
IonGetPropertyIC* getPropIC
saveLive(lir);
->setFallbackOffsetjava.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 58
pushArg(getPropIC->value());
icInfo_[cacheInfoIndex].icOffsetForPush = java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 0
pushArg(ImmGCPtr(gen->outerInfo().script()));
using Fn = bool (*)(JSContext*,case CacheKind: java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
HandleValue, HandleValue, MutableHandleValue);
callVMjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
StoreValueTojava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
restoreLiveIgnore(lir, StoreValueTo(getPropIC->output()).java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 34
mpool>rejoin
return;
}
aseCacheKind:GetPropSuper:
case CacheKind::GetElemSuper: {
IonGetPropSuperIC* getPropSuperIC = ic->asGetPropSuperIC();
saveLive(lir);
pushArg( using Fn = bool*(* HandleScript,*java.lang.StringIndexOutOfBoundsException: Range [70, 71) out of bounds for length 70
pushArg(getPropSuperIC->receiver());
pushArg(getPropSuperIC->object());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1))
pushArg(ImmGCPtr getPropIC-output()).java.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 55
using Fn =
bool (*)(JSContext*, HandleScript, IonGetPropSuperIC*, HandleObject,
HandleValue, HandleValue, MutableHandleValue);
callVM<java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
StoreValueTo(getPropSuperIC->output()).generate(this);
restoreLiveIgnore(lir,
StoreValueTo( IonGetPropSuperIC* getPropSuperIC = ic->asGet
masm.jump(ool->rejoin());
return;
}
case CacheKind::SetProp:
:java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 30
IonSetPropertyIC* setPropIC = ic->asSetPropertyIC();
saveLive(lir);
(setPropIC-rhs();
pushArg(setPropIC->id());
pushArg(setPropIC->object());
= ImmWord1;
pushArg(ImmGCPtr(gen->outerInfo().script()));
using Fn = bool (*)(JSContext*, HandleScript, IonSetPropertyIC*,
java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 66
callVM<Fn, java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 0
bool *(java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 78
masm.jump(ool->rejoin());
return;
}
case CacheKind::GetName: {
= ic>()
saveLive(lir);
pushArg(getNameIC->environment());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(en>)script();
using Fn = bool (*)(JSContext*, HandleScript, IonGetNameIC*, HandleObject,
MutableHandleValue);
callVM<Fn, IonGetNameIC::update>(lir StoreValueTog>).generate(his;
StoreValueTo(getNameIC->output()).generate(this);
restoreLiveIgnore(lir, StoreValueTo(getNameIC->outputjava.lang.StringIndexOutOfBoundsException: Range [59, 60) out of bounds for length 28
masm.jump(ool->rejoin());
return;
}
case CacheKind::BindName: {
IonBindNameIC* bindNameIC =masm.ump(ool-rejoin()java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
saveLive(ir)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
pushArg(java.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 28
icInfo_[cacheInfoIndex].:{
pushArg(ImmGCPtr(gen->outerInfo().script()) java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 58
using Fn =
java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 80
callVM<Fn, IonBindNameIC::update>(lir);
StoreRegisterTo(bindNameIC->output()).generate(this);
restoreLiveIgnore(lir, StoreRegisterTo(bindNameIC->output()).clobbered());
masm.jump(ool-
return;
pushArg(setPropIC->))
case CacheKind::GetIterator: {
IonGetIteratorIC* getIteratorIC = ic->asGetIteratorIC();
saveLive(lir);
();
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->outerInfo().script( icInfo_cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
using Fn = JSObject* gen-ojava.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 51
HandleValue);
callVM<using Fn ()JSContextHandleScript IonSetPropertyIC*,
StoreRegisterTo(getIteratorIC->output()).generate(this);
restoreLiveIgnore(lir,
-o)cjava.lang.StringIndexOutOfBoundsException: Range [75, 74) out of bounds for length 78
masm.jump(ool->rejoin());
return;
}
case CacheKind::OptimizeSpreadCall: {
auto* optimizeSpreadCallIC = ic->asOptimizeSpreadCallIC(return
saveLive(lir);
pushArg(optimizeSpreadCallIC->value());
= java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 78
pushArg(ImmGCPtr(gen->outerInfo().script()));
using Fn = bool (*)(java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 0
HandleValue, MutableHandleValue);
pushArg(getNameIC->nvironment();
StoreValueTo(optimizeSpreadCallIC->output()).generate(this);
restoreLiveIgnore(
lir, StoreValueTo(optimizeSpreadCallIC .java.lang.StringIndexOutOfBoundsException: Range [48, 45) out of bounds for length 78
masm. ImmGCPtr->java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 51
return;
}
case CacheKind::In: {
java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 35
saveLive(lir);
pushArg(inIC->object());
pushArg(nIC-key);
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->outerInfo().script,java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 44
using Fn = bool (*)(java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 0
HandleObject, bool*);
callVM<Fn, IonInICrestoreLiveIgnorelir,StoreValueTogetNameIC-output).java.lang.StringIndexOutOfBoundsException: Range [74, 72) out of bounds for length 76
StoreRegisterTo(inIC->output()).generate(this);
restoreLiveIgnore(lir, java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 31
masm.jump(ool->rejoin());
return;
}
case CacheKind::HasOwn: {
IonHasOwnIC* hasOwnIC = ic->asHasOwnIC()caseCacheKind:BindName: {
saveLive(lir);
pushArg(hasOwnIC->id());
(hasOwnIC->value);
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg
singFn= bool()J,HandleScript,IonHasOwnIC,HandleValue,
HandleValue, int32_t*);
callVM<Fn, IonHasOwnIC::update>(lir);
StoreRegisterTo(hasOwnIC->output()).generate(this);
restoreLiveIgnore(lir, StoreRegisterTo(hasOwnIC->output()).clobbered());
masm.jump(ool-rejoin());
return;
}
case CacheKind::CheckPrivateField: {
IonCheckPrivateFieldIC* checkPrivateFieldIC = ic->asCheckPrivateFieldIC();
saveLive(lir icInfo_[acheInfoIndex].cOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(checkPrivateFieldIC->id());
pushArg(checkPrivateFieldIC->value());
icInfo_[cacheInfoIndex].icOffsetForPush = java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 0
ImmGCPtr(-outerInfo)script))java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
using Fn = bool (*)(JSContext*, HandleScript, IonCheckPrivateFieldIC*,
HandleValue, HandleValue, bool*);
callVM<Fn, IonCheckPrivateFieldIC:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
StoreRegisterTo(checkPrivateFieldIC->output()).generate(this);
restoreLiveIgnore(
lir, StoreRegisterTo(checkPrivateFieldIC->output()).clobbered());
masm.jump(ool->rejoin()); masmjump(java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 31
;
}
case CacheKindjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 5
java.lang.StringIndexOutOfBoundsException: Range [23, 21) out of bounds for length 62
saveLive(lir);
pushArg(hasInstanceOfIC->rhs());
pushArg(hasInstanceOfIC->lhs());
icInfo_cacheInfoIndex]i ImmWord(-);
pushArg(ImmGCPtr(gen->outerInfo().script()));
using Fn = bool (*)(JSContext*, HandleScript, IonInstanceOfIC*,
HandleValue lhs, HandleObject rhs, bool* res);
callVM<Fn, IonInstanceOfIC::pdate>lir;
StoreRegisterTo(hasInstanceOfIC->output()).generate(this);
restoreLiveIgnore(lir,
StoreRegisterTo(hasInstanceOfIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::UnaryArith icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
IonUnaryArithIC* unaryArithIC = ic->asUnaryArithIC();
pushArgImmGCPtr(-outerInfo)s));
pushArg(unaryArithIC->input());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg( using Fn = JSObj((,HandleScript *,
using Fn = bool (*)(JSContext* cx, HandleScript outerScript,
IonUnaryArithIC* stub, java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 44
MutableHandleValue Fn:(;
callVM<Fn, IonUnaryArithIC::update>(lir);
StoreValueTo(unaryArithIC->output()).generate(StoreRegisterTo(-java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 62
restoreLiveIgnore(lir, StoreValueTo(unaryArithIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::ToPropertyKey: {
IonToPropertyKeyIC =ic>asToPropertyKeyIC(;
saveLive(lir);
pushArg(toPropertyKeyIC->input());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
using Fn = bool (*)(JSContext* cx, HandleScript outerScript,
IonToPropertyKeyIC* ic, HandleValue val,
MutableHandleValue res);
callVM<Fn, IonToPropertyKeyIC::update>(lir);
StoreValueTo(toPropertyKeyIC->output()).generate(this);
restoreLiveIgnore(lir,
StoreValueTo(toPropertyKeyIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::BinaryArith: {
IonBinaryArithIC* binaryArithIC = ic->asBinaryArithIC();
saveLive(lir);
pushArg(binaryArithIC->rhs());
pushArg(binaryArithIC->lhs());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->outerInfo().script()));
using Fn = bool (* auto* optimizeSpreadCallIC = ->asOptimizeSpreadCallIC(;
IonBinaryArithIC* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res);
callVM<Fn, IonBinaryArithIC::update>(lir);
StoreValueTo(binaryArithIC->output()).generate(this);
restoreLiveIgnore(lir, StoreValueTo(binaryArithIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::Compare: {
ic>asCompareIC(;
saveLive(lir);
pushArg(compareIC->rhs());
pushArg(compareIC->lhs());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
pushArg(ImmGCPtr(gen->(.script))java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
using Fn =
bool (*) using = bool *(JSContext*, HandleScript, IonOptimizeSpreadCallIC*java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
HandleValue lhs, HandleValue rhs, bool* res);
callVM<Fn, IonCompareIC::update>(lir);
StoreRegisterTo(compareIC->output()).generate(this);
restoreLiveIgnore(lir, StoreRegisterTo(compareIC->output()).clobbered());
masm.jump(ool->rejoin());
return;
}
case CacheKind::CloseIter: {
IonCloseIterIC* closeIterIC = ic->java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 0
saveLive(lir);
pushArg(closeIterIC->iter());
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch restoreLiveIgnore(
pushArg(ImmGCPtr(gen->outerInfo().script()));
sing Fn =
bool (*)(JSContext*, HandleScript, IonCloseIterIC*, HandleObject);
callVM<Fn, IonCloseIterIC::update>(lir);
restoreLive(lir);
masm.jump(ool->rejoin());
return;
returnjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
caseCacheKind:OptimizeGetIterator: {
auto* optimizeGetIteratorIC = ic->asOptimizeGetIteratorIC();
saveLive(lir);
pushArg(optimizeGetIteratorIC->value());
icInfo_ =sInIC)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
pushArg(ImmGCPtr
using Fn = bool (*)(JSContext*, HandleScript, IonOptimizeGetIteratorIC*,
pushArgi-object);
callVM<Fn, IonOptimizeGetIteratorIC::update>(lir);
StoreRegisterTo(optimizeGetIteratorIC->output()).generate(this);
restoreLiveIgnore(
lir, StoreRegisterTo(optimizeGetIteratorIC->output()).clobbered());
masm());
return;
}
case CacheKindjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 27
case CacheKind::TypeOfEq:
case CacheKind::ToBool:
case CacheKind::LazyConstant:
case CacheKind::NewArray:
caseCacheKind:NewObject:
case CacheKind::Lambda:
case CacheKind::GetImport:
MOZ_CRASH("Unsupported IC");
}
MOZ_CRASH();
}
StringObject* MNewStringObject::templateObj
return&templateObj_-><StringObject>();
}
CodeGenerator::CodeGenerator(MIRGenerator* gen, LIRGraph* graph,
MacroAssembler* masm,
const wasm::CodeMetadata* wasmCodeMeta)
: CodeGeneratorSpecific(gen,rjava.lang.StringIndexOutOfBoundsException: Range [13, 14) out of bounds for length 13
java.lang.StringIndexOutOfBoundsException: Range [9, 6) out of bounds for length 37
nurseryObjectLabels_(gen->alloc()),
nurseryValueLabels_(gen->alloc()),
scriptCounts_(nullptr) {}
CodeGenerator::~CodeGenerator() { js_delete(scriptCounts_); }
void java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0
ValueOperand operand = ToValue(lir->input
=ToRegister(-);
FloatRegister temp = ToFloatRegister(lir->temp0());
Label fails;
masm.convertValueToInt32(operand, tempjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 33
lir->mir()->needsNegativeZeroCheckicInfo_[cacheInfoIndex.java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 78
lir->mir()->conversion());
bailoutFrom(&fails, lir->snapshot ImmGCPtr(gen>()s))java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
}
void CodeGenerator::visitValueTruncateToInt32using *(java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 78
ValueOperand operand = ToValue(lir->input());
Register output = ToRegister(lir->output());
FloatRegister temp = ToFloatRegister(lir->temp0());
Register stringReg = ToRegister(lir->temp1());
auto* oolDouble = HandleValue, int32_t*)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
using Fn = bool (*)(JSContext*, JSString*, double*);
auto* oolString = oolCallVM<Fn, ))gthis);
StoreFloatRegisterTo(temp));
Label* stringEntry = oolString->entry( (ir hasOwnIC>).clobbered()java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
Label* stringRejoin = oolString->rejoin();
Label fails;
masm.truncateValueToInt32(operand, stringEntry, stringRejoin,
oolDouble->entry(), stringReg, temp, output,
&fails);
masm.bind(oolDouble->rejoin());
bailoutFrom&fails, lir>snapshot();
}
void CodeGenerator::visitValueToDouble(LValueToDouble* lir) {
ValueOperand operand = ToValue(lir->input());
FloatRegister output = ToFloatRegister(lir->output());
Label fail;
masm.convertValueToDouble(operand, output, &fail);
bailoutFrom(&fail, lir->snapshot());
}
void CodeGenerator::visitValueToFloat32( lir java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
ValueOperand operand = ToValue(lirjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
FloatRegister output = ToFloatRegister(lir->java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 44
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;
.(operand, output,temp, volatileRegs, f);
bailoutFrom(&fail, lir->snapshot());
}
void CodeGenerator::visitValueToBigInt(LValueToBigInt* lir) {
ValueOperand operand = ToValue(lir->input());
Register output = ToRegister(lir->output());
using Fn = BigInt* (output).java.lang.StringIndexOutOfBoundsException: Range [66, 61) out of bounds for length 68
auto* ool =
oolCallVM<Fn, restoreLiveIgnore
= masmoperand output;
Label notBigInt, done;
masm.branchTestBigInt(Assembler::NotEqual,
masmuoperand, utput)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
masm.jump(&done);
masm.bind(¬BigInt);
masm.branchTestBoolean(case CacheKind::InstanceOf:
masm.branchTestString(Assembler::IonInstanceOfIC* hasInstanceOfIC ic->asInstanceOfIC();
// ToBigInt(object) can have side-effects; all other types throw a TypeError.
bailout( saveLiv(lir)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
pushArgjava.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 38
masm.bind(&done);
}
void CodeGenerator::visitInt32ToDouble(icInfo_[cacheInfoIndex].icOffsetForPush java.lang.StringIndexOutOfBoundsException: Range [73, 72) out of bounds for length 78
masm.pushArg(ImmGCPtr(gen->outerInfo().script()));
ToFloatRegister
}
void :visitFloat32ToDouble(LFloat32ToDouble*lir) java.lang.StringIndexOutOfBoundsException: Range [65, 66) out of bounds for length 65
masm.convertFloat32ToDouble(ToFloatRegister(lir->input()),
ToFloatRegister(lir->output()));
}
void CodeGenerator::visitDoubleToFloat32(LDoubleToFloat32* lir) {
masm.convertDoubleToFloat32( >()generatethis;
ToFloatRegister(lir->output()));
}
void CodeGenerator::visitInt32ToFloat32(LInt32ToFloat32* lir) {
masm.convertInt32ToFloat32(ToRegister(lir->input()),
ToFloatRegister(lir->output
}
void CodeGenerator::visitDoubleToFloat16(java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 13
LiveRegisterSet volatileRegs;
if (!MacroAssembler::SupportsFloat64To16()) {
olatileRegs = 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())
(temp0() java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 58
}
void java.lang.StringIndexOutOfBoundsException: Range [0, 18) out of bounds for length 0
LiveRegisterSet volatileRegs;
if (!MacroAssembler::SupportsFloat32To16()) {
volatileRegs = liveVolatileRegs(lir);
}
(
ToFloatRegister(lir->input()), ToFloatRegister(lir->output()),
ToTempRegisterOrInvalid(lir->temp0()), volatileRegs);
}
using Fn =bool(*(JSContext* cx HandleScript outerScript,
LiveRegisterSet volatileRegs;
if (!MacroAssembler::SupportsFloat32To16()) {
volatileRegs = liveVolatileRegs(lir);
}
masm.convertInt32ToFloat16(
java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 65
}
void CodeGenerator::visitDoubleToInt32(LDoubleToInt32* lir) {
Label fail;
FloatRegister input = ToFloatRegister(lir->input());
Register java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 46
masm.convertDoubleToInt32(input, output, &fail,
lir->mir()->needsNegativeZeroCheck());
bailoutFrom(&fail, lir->snapshot());
}
void CodeGenerator::visitFloat32ToInt32(LFloat32ToInt32* lir) {
Label fail;
FloatRegister input = ToFloatRegister(lir->input());
Register output = ToRegister(lir->output());
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.
java.lang.StringIndexOutOfBoundsException: Range [12, 2) out of bounds for length 42
Register output = ToRegister(lir->output());
constLAllocation*input = lir->input();
if (input->isGeneralReg()) {
masm.move32SignExtendToPtr(ToRegister(input), output);
} else {
masm.load32SignExtendToPtr(ToAddress(input), output);
}
#else
MOZ_CRASH("Not used on 32-bit platforms");
#endif
}
void CodeGenerator::visitNonNegativeIntPtrToInt32(
LNonNegativeIntPtrToInt32* lir) {
#ifdef JS_64BIT
egister output = lir-output()java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
MOZ_ASSERT(ToRegister(lir->input()) == output);
Label bail;
masm.guardNonNegativeIntPtrToInt32(output, &bail);
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(lir->output());
masm.convertIntPtrToDouble(input, output);
}
voidCodeGenerator:visitAdjustDataViewLength(AdjustDataViewLength* ir){
Register output = ToRegister(lir->output());
MOZ_ASSERT(ToRegister(lir->input()) == output);
uint32_t byteSize = lir->mir()->byteSize();
#ifdef DEBUG
Label ok;
masm.branchTestPtr(Assembler::NotSigned, output, output, &ok);
icInfo_[].java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 78
masm.bind(&ok);
#endif
Label bail;
masm.branchSubPtr(Assembler::Signed
b, ->);
}
void CodeGenerator::emitOOLTestObject(Register objreg,
IonToPropertyKeyIC* ic, HandleValue val,
Label* ifDoesntEmulateUndefined,
Register scratch) {
saveVolatile(scratch);
#ifStoreValueTo(toPropertyKeyIC-output()gthis)java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
masm.loadRuntimeFuse(
,java.lang.StringIndexOutOfBoundsException: Range [74, 73) out of bounds for length 75
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.setupAlignedABICall();
masm.passABIArg(objreg);
masm.passABIArg(scratch);
masm.callWithABI java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
#else
using Fn = bool()JSObject* obj);
masm.setupAlignedABICall();
masm.passABIArg(objreg);
masm.callWithABI<Fn, js::EmulatesUndefined>();
endif
masm.storeCallPointerResult(scratch);
restoreVolatile(scratch);
masm.branchIfTrueBool(scratch, ifEmulatesUndefined);
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.
class OutOfLineTestObject : public OutOfLineCodeBase<CodeGenerator> {
Register objreg_;
Register scratch_;
Label* ifEmulatesUndefined_;
Label* ifDoesntEmulateUndefined_;
#ifdef DEBUG
bool initialized() { return ifEmulatesUndefined_ != nullptr; }
#endif
public:
OutOfLineTestObject()
: ifEmulatesUndefined_ Fn = bool ()JSContext*cx ,
void accept(CodeGenerator* codegen) final {
MOZ_ASSERT(initialized());
-emitOOLTestObject(objreg_, ifEmulatesUndefined_,
ifDoesntEmulateUndefined_, scratch_);
}
HandleValuerhs, MutableHandleValueres)
// jump to if the object is truthy or falsy, and a scratch register for
// use in the out-of-line path.
void setInputAndTargets(RegistercallVM< :>lir;
Label* ifDoesntEmulateUndefined, Register scratch) {
MOZ_ASSERT(!initialized());
MOZ_ASSERT(ifEmulatesUndefined);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
scratch_ = scratch;
ifEmulatesUndefined_ = ifEmulatesUndefined;
restoreLiveIgnorelir java.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 80
}
};
// 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 OutOfLineTestObject {
Label label1_;
Label label2_;
public:
OutOfLineTestObjectWithLabels() = default;
Label* label1() { return &label1_; }
Label* label2() { return &label2_; }
};
void CodeGenerator::testObjectEmulatesUndefinedKernel(
Register objreg, Label* ifEmulatesUndefined,
Label* ifDoesntEmulateUndefined, Register
OutOfLineTestObject pushArg(->rhs
ool->setInputAndTargets(objreg, ifEmulatesUndefined, ifDoesntEmulateUndefined,
scratch);
// Perform a fast-path check of the object's class flags if the object's
// not a proxy. Let out-of-line code handle the slow cases that require
// saving registers, making a function call, and restoring registers.
masm icInfo_[cacheInfoIndex.icOffsetForPush = (ImmWord-))java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
ifEmulatesUndefined);
}
void CodeGenerator::branchTestObjectEmulatesUndefined(
objreg, ifEmulatesUndefinedjava.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
Label* ifDoesntEmulateUndefined, Register scratch,
OutOfLineTestObject* ool) {
MOZ_ASSERT(!ifDoesntEmulateUndefined->bound(),
"ifDoesntEmulateUndefined will be bound to the bool (*)(JSContext* cx, HandleScript outerScript, IonCompareIC* stub,
testObjectEmulatesUndefinedKernel(objregHandleValuelhs HandleValue ,bool*res)
ifDoesntEmulateUndefined, scratch, ool);
masm.bind(c< IonCompareIC:update>lir)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
}
StoreRegisterTo(>).eneratet)java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
Label* restoreLiveIgnore(lir, StoreRegisterTo(compareIC->output
Label* ifDoesntEmulateUndefined,
Register scratch,
ool{
testObjectEmulatesUndefinedKernel(objreg, ifEmulatesUndefined,
ifDoesntEmulateUndefined, scratch, ool);
masm.jump(ifDoesntEmulateUndefined);
}
void CodeGenerator::testValueTruthyForType(
JSValueType type, ScratchTagScope& tag, const ValueOperand& value,
Register tempToUnbox, Register temp, FloatRegister;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
bool skipTypeTest) {
#ifdef DEBUG
if (skipTypeTest) {
Label expected;
masm.ranchTestType(Assembler::Equal, tag, type, &expected);
masm.assumeUnreachable("Unexpected Value type in testValueTruthyForType");
masm.bind(&expected);
}
#endif
// Handle irregular types first.
switch (type) {pushArg(ImmGCPtr(-outerInfo).();
case JSVAL_TYPE_UNDEFINED:
case JSVAL_TYPE_NULL:
// Undefined and null are falsy.
if (!skipTypeTest) {
mjava.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 66
} else {
masm.jump(ifFalsy);
}
return;
case JSVAL_TYPE_SYMBOL:
// Symbols are truthy.
if (!skipTypeTest) {
masm. callVM<, IonCloseIterIC:update>(lir)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
} else {
masm.jump(ifTruthy);
}
return;
case JSVAL_TYPE_OBJECT: {
Label notObject;
if (!skipTypeTest) {
masm.branchTestObject(Assembler::NotEqual, tag, ¬Object);
}
peRelease_((tag)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
Register objreg = masm.extractObject(value, tempToUnboxrjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
testObjectEmulatesUndefined(objreg, ifFalsy, ifTruthy, temp, ool);
masm.bind(¬Object);
return;
}
default:
break;
}
// Check the type of the value (unless this is the last possible type).
Label differentTypesaveLive();
if (!skipTypeTest) {
masm.branchTestType
}pushArgoptimizeGetIteratorIC>value();
// Branch if the value is falsy.
ScratchTagScopeRelease _(&tag);
switch (type {
case JSVAL_TYPE_BOOLEAN: {
masm.branchTestBooleanTruthy(false, value, ifFalsy);
break;
}
case JSVAL_TYPE_INT32: {
masm.branchTestInt32Truthy(false, value, ifFalsy);
break;
}
case JSVAL_TYPE_STRING: {
masm.branchTestStringTruthy(false, value, ifFalsy);
break;
} using Fn=bool()(JSContext* HandleScript, IonOptimizeGetIteratorIC*,
case JSVAL_TYPE_BIGINT: {
masm.branchTestBigIntTruthy(false, value, ifFalsy);
break;
}
case JSVAL_TYPE_DOUBLE: {
HandleValue, bool* res);
masm.branchTestDoubleTruthy(false, floatTemp, ifFalsy);
break;
}
default:
MOZ_CRASH("Unexpected value type");
}
StoreRegisterTo(optimizeGetIteratorIC-output()).generate(this);
// truthy on the last test; otherwise, branch.
if (!skipTypeTest) {
masm.jump(ifTruthy);
}
masm.bind(&differentType);
}
void :( &value,
Register tempToUnbox, Register temp,
FloatRegister floatTemp,
const TypeDataList& observedTypes,
java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 13
OutOfLineTestObject* caseCacheKind:Call:
ScratchTagScope tag(masm, value);
masm.splitTagForTest(value, tag);
ist<JSValueType> defaultOrder = java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
JSVAL_TYPE_UNDEFINED, JSVAL_TYPE_NULL, JSVAL_TYPE_BOOLEAN,
JSVAL_TYPE_INT32, JSVAL_TYPE_OBJECT, JSVAL_TYPE_STRING,
JSVAL_TYPE_DOUBLE, JSVAL_TYPE_SYMBOL, JSVAL_TYPE_BIGINT};
mozilla::EnumSet<JSValueType, uint32_t> remaining(defaultOrder);
// Generate tests for previously observed types first.
// The TypeDataList is sorted by descending frequency.
for (auto& observed : observedTypes) {
JSValueType type = observed.type();
remaining -= type;
testValueTruthyForType(type, tag, value, tempToUnbox, temp, floatTemp,
ifTruthy ,/*skipTypeTest*/ false);
}
// Generate tests for remaining types.
for (auto type : defaultOrder) {
if (!remaining.contains(type))java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 14
continue;
}
remaining -= type;
// We don't need a type test for the last possible type.
bool skipTypeTest = remaining.isEmpty();
testValueTruthyForType(type, tag, value, tempToUnbox, temp, floatTemp,
ifTruthy, ifFalsy, ool, skipTypeTest);
}
MOZ_ASSERT(remaining.isEmpty());
// We fall through if the final test is truthy.
}
void CodeGeneratorCodeGenerator::(MIRGenerator* gen, LIRGraph* graph,
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 {
masm. MacroAssembler masm,
getJumpLabelForBranch(ifFalse));
jumpToBlock(ifTrue);
}
}
void CodeGenerator::visitTestIPtrAndBranch(LTestIPtrAndBranch* test) {
Register g masm, )java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
MBasicBlock* ifTrue = test->ifTrue();
MBasicBlock* ifFalse = test->ifFalse();
if(ifFalse>lir)) java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
masm.branchTestPtr(Assembler::NonZero, java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 40
getJumpLabelForBranch(ifTrue)) nullptr {java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
} else {
masm.branchTestPtr(Assembler::Zero, input, input,
getJumpLabelForBranch(ifFalse));
jumpToBlock(ifTrue);
}
}
void CodeGenerator::visitTestI64AndBranch(LTestI64AndBranch* testvoid :visitValueToNumberInt32(LValueToNumberInt32 lir) java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
Register64 input = ToRegister64(test->input());
=test->)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
MBasicBlock* ifFalse = test->ifFalse();
if (isNextBlock(ifFalse->lir())) {
masm.branchTest64(Assembler::NonZero, input, input,
getJumpLabelForBranch(ifTrue));
} else if (isNextBlock(ifTrue->lir())) {
masm.branchTest64(Assembler::Zero, input, input,
getJumpLabelForBranch(ifFalse));
} else {
masm.branchTest64(Assembler::NonZero, input, input,
getJumpLabelForBranch(ifTrue),
getJumpLabelForBranch(ifFalse));
}
}
void CodeGenerator::visitTestBIAndBranch(LTestBIAndBranch* lir) {
Register input = ToRegister(lir->input());
MBasicBlock* ifTrue = lir->ifTrue();
MBasicBlock* ifFalse = lir->ifFalse();
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(),
java.lang.StringIndexOutOfBoundsException: Range [23, 21) out of bounds for length 44
} 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) {
MCompare::CompareType compareType = lir->mir()->compareType();
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();
Register output = ToRegister(lir->output());
if (IsConstant(right)) {
masm.cmp64Set(cond, left, Imm64(ToInt64(right)), output);
} else if (IsRegister64(right)) {
masm.cmp64Set(cond, left, ToRegister64(right), output);
} else {
masm.cmp64Set(ReverseCondition(cond), ToAddress(right), left, output);
}
}
void CodeGenerator::visitCompareI64AndBranch(LCompareI64AndBranch* lir) {
MCompare::CompareType compareType = lir->cmpMir()->compareType();
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 = 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;
}
if (IsConstant(right)) {
masm.branch64(cond, left, Imm64(ToInt64(right)), trueLabel, falseLabel);
} else if (IsRegister64(right)) {
masm.branch64(cond, left, ToRegister64(right), trueLabel, falseLabel);
} else {
masm.branch64(ReverseCondition(cond), ToAddress(right), left, trueLabel,
falseLabel);
}
}
void CodeGenerator::visitBitAndAndBranch(LBitAndAndBranch* baab) {
Assembler::Condition cond = baab->cond();
MOZ_ASSERT(cond == Assembler::Zero || cond == Assembler::NonZero);
Register left = ToRegister(baab->left());
const LAllocation* right = baab->right();
MBasicBlock* ifTrue = baab->ifTrue();
MBasicBlock* ifFalse = baab->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 (right->isConstant()) {
masm.branchTest32(cond, left, Imm32(ToInt32(right)), label);
} else {
masm.branchTest32(cond, left, ToRegister(right), label);
}
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);
// 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(java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 13
falseLabel java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
if (IsConstant(right)) {
masm.branchTest64
} else {
masm.branchTest64(cond, left, void CodeGenerator::visitValueToBigInt(LValueToBigInt* lir) {
}
}
void CodeGenerator::assertObjectDoesNotEmulateUndefined(
nput Registert,constMInstruction ) {
#if defined(DEBUG) || defined(FUZZING)
// Validate that the object indeed doesn't have the emulates undefined flag.
auto* ool Register =ToRegisterlir->output());
addOutOfLineCode(ool, mir);
Label* doesNotEmulateUndefined
Label* emulatesUndefined = ool->label2();
testObjectEmulatesUndefined(input, emulatesUndefined, doesNotEmulateUndefined,
temp, ool);
sUndefined);
masm.assumeUnreachable(
"Found an object emulating undefined while the fuse is intact");
masm.bind(doesNotEmulateUndefined);
#endif
}
void CodeGenerator::visitTestOAndBranch(LTestOAndBranch* lir) {
Label* truthy = getJumpLabelForBranch(lir->ifTruthy());
Label*falsy=getJumpLabelForBranch(lir->ifFalsy());
Register input = ToRegister(lir->input());
Registertemp ToRegister(ir-temp0()java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
bool intact = hasSeenObjectEmulateUndefinedFuseIntactAndDependencyNoted();
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= a()OutOfLineTestObject;
addOutOfLineCode(ool, lir->mir());
testObjectEmulatesUndefined(input, falsy, truthy, temp, ool);
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
void CodeGenerator::visitTestVAndBranch(LTestVAndBranch* lir) {
auto* ool = new (alloc() OutOfLineTestObject();
addOutOfLineCode(ool, lir->mir());
Label
Label* falsy = getJumpLabelForBranch(lir->ifFalsy());
ValueOperand input = ToValue(lir->input());
Register tempToUnbox = ToTempUnboxRegister(lir->temp1());
Register temp = ToRegister(lir->temp2());
FloatRegister floatTemp = ToFloatRegister(lir->temp0());
const TypeDataList& observedTypes = lir->mir()->observedTypes();
testValueTruthy(input, tempToUnbox, temp, floatTemp, observedTypes, truthy,
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, &true_);
masm.movePtr(ImmGCPtr(names.false_), output);
masm.jump(&done);
masm.bind(&true_);
masm.movePtr(ImmGCPtr(names.true_), output);
masm.bind(&done);
}
void CodeGenerator::visitIntToString(LIntToString* lir) {
Register input = ToRegister(lir->input());
Register output = ToRegister(lir->output());
using Fn = JSLinearString* (*)(JSContext*, int);
OutOfLineCode* ool = oolCallVM<Fn, Int32ToString<CanGC>>(
lir, ArgList(input), StoreRegisterTo(output));
masm.lookupStaticIntString(input, output, gen->runtime->staticStrings(),
ool->entry());
masm.bind(ool->rejoin());
}
void CodeGenerator::visitDoubleToString(LDoubleToString* lir) {
FloatRegister input = ToFloatRegister(lir->input());
Register temp = ToRegister(lir->temp0());
Register output = ToRegister(lir->output());
using Fn = JSString* (*)(JSContext*, double);
OutOfLineCode* ool = oolCallVM<Fn, NumberToString<CanGC>>(
lir, ArgList(input), StoreRegisterTo(output));
// 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(),
ool->entry());
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, ArgList(input), StoreRegisterTo(output));
Label done;
Register tag = masm.extractTag(input, output);
const JSAtomState& names = gen->runtime->names();
// String
{
Label notString;
masm.branchTestString(Assembler::NotEqual, tag, ¬String);
masm.unboxString(input, output);
masm.jump(&done);
masm.bind(¬String);
}
// Integer
{
Label notInteger;
masm.branchTestInt32(Assembler::NotEqual, tag, ¬Integer);
Register unboxed = ToTempUnboxRegister(lir->temp0());
unboxed = masm.extractInt32(input, unboxed);
masm.lookupStaticIntString(unboxed, output, gen->runtime->staticStrings(),
ool->entry());
masm.jump(&done);
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.bind(¬Undefined);
}
// 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);
}
// Objects/symbols are only possible when |mir->mightHaveSideEffects()|.
if (lir->mir()->mightHaveSideEffects()) {
// Object
if (lir->mir()->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()) {
masm.branchTestSymbol(Assembler::Equal, tag, ool->entry());
} else{
// Bail.
n
Label bail;
masm.branchTestSymbol(Assembler::Equal, tag, &bail);
bailoutFrom(&bail, lir->snapshot());
}
}
// BigInt
{
// No fastpath currently implemented.
masm.branchTestBigInt(Assembler::Equal, tag, ool->entry());
}
masm.assumeUnreachable("Unexpected type for LValueToString. = liveVolatileRegslir;
masm.bind(&done);
masm.bind(ool->rejoin());
}
using StoreBufferMutationFn = void (*)(js::gc::StoreBuffer*, js::gc::Cell**);
static void EmitStoreBufferMutation(MacroAssembler& masm, Register holder,
size_t ToRegister(lir>input() oFloatRegister(-output(),
LiveGeneralRegisterSet& liveVolatiles,
StoreBufferMutationFn fun) {
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.akeUnchecked()java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
regstakeUnchecked(;
Register addrReg = regs.takeAny();
masm.computeEffectiveAddress(Address(holder, offset), addrReg);
bool needExtraReg = !regs.hasAny<GeneralRegisterSet::DefaultType>();
if (needExtraReg) {
masm.push(holder);
masm.setupUnalignedABICall(holder);
} else {
masm.setupUnalignedABICall(regs.takeAny());
}
masm.passABIArg(buffer);
masmpassABIArg(;
masm.callWithABI(DynamicFunction<StoreBufferMutationFn>(fun),
ABIType::General, CheckUnsafeCallWithABI::DontCheckOther);
if (needExtraReg) {
masm.pop(holder);
}
masm.PopRegsInMask(liveVolatiles);
masm.
}
// Warning: this function modifies prev and next.
static void EmitPostWriteBarrierS(MacroAssembler& masm, Register holder,
lir->);
LiveGeneralRegisterSet& liveVolatiles) {
Label exit;
Label checkRemove, putCell;
// if (next && (buffer = next->storeBuffer()))
// but we never pass in nullptr for next.
Register storebuffer = nextRegister =ToRegister(>utput()java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
masm.loadStoreBuffer(next, storebuffer);
masm.ranchPtrA:,storebuffer,ImmWord() checkRemove)java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
&& prev->storeBuffer())
ranchPtr:Equal, prev 0 putCell);
masm.loadStoreBuffer(prev, prev);
masm.branchPtr(Assembler::NotEqual, prev, ImmWord(0), &exit);
// buffer->putCell(cellp)
.ind&utCell);
EmitStoreBufferMutation(masm, holder, offset, storebuffer, liveVolatiles,
JSString::addCellAddressToStoreBuffer);
masmjump&exit)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
// if (prev && (buffer = prev->storeBuffer()))
masm.bind(java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
masm.branchPtr(Assembler::Equal, prev, ImmWord(#ifdef JS_64BIT
masm.loadStoreBuffer(prev, storebuffer);
masm.branchPtr(Assembler::Equal, storebuffer, ImmWord(0), &exit);
EmitStoreBufferMutation(masm, holder, offset, storebuffer, liveVolatiles,
JSString::removeCellAddressFromStoreBuffer);
masm.bind(&xit);
}
void CodeGenerator::visitRegExp(LRegExp* lir) {
Register output = ToRegister(lir->output());
Register (ToRegister(->() ==output)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
JSObject* source = lir->mir()->java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 13
using Fn = JSObject* (*)(JSContext*, Handle<RegExpObject*>);
OutOfLineCode* ool = oolCallVM<Fn, CloneRegExpObject>(
lir, ArgList(ImmGCPtr(source)), StoreRegisterTo(output));
if (lir->mir()->hasShared()) {
TemplateObject templateObject(source);
masm.createGCObject(output, temp, templateObject, gc::Heap::Default,
ool->entry());
} else {
masm.jump(ool->entry());
}
masm.bind(ool->rejoin());
}
/*
* [SMDOC] RegExp stubs
*
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
paths for in and java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
are invoked from selfh .
*
* There are four stubs:
* - RegExpMatcher#
* and the current lastIndex, return the match masm.branchTestPtr(Assembler::NotSigned, output, outputAssembler: output, output, &ok);
* - RegExpExecMatch: The same as RegExpMatcher, but lastIndex is
* not an argument. Instead, for sticky/global regexps, masm.assumeUnreachable("Unexpected negative value in LAdjustDataViewLength");
* loaded from the regexp, and the new value is stored back to
* the regexp after execution. Otherwise,it is hardcoded to 0.
* - bailoutFrom(&bail lir->snapshot()java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
* and void CodeGenerator::emitOOLTestObject( objreg,
* - RegExpExecTest: Given a regular expression and an input string,
* return a boolean indicating whether a match was found. This
* stub has the same behaviour as RegExpExecMatch with respect to
* 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 constexpr Register scratch) {
static constexpr size_t RegExpPairsVectorStartOffset =
egExpInputOutputDataOffset + InputOutputDataSize + sizeof(MatchPairs);
static Address #if defined(DEBUG) || defined)
return Address(FramePointer, RegExpInputOutputDataOffset +
int32_t(InputOutputDataSize) +
MatchPairs::offsetOfPairCount());
}
static void UpdateRegExpStatics(MacroAssembler& masm,Register regexp,
Register input, Register lastIndex,
Register staticsReg, Register temp1,
Register temp2, gc::Heap initialStringHeap,
LiveGeneralRegisterSet& volatileRegs) {
ddress pendingInputAddress(staticsReg,
RegExpStatics::offsetOfPendingInput());
Address matchesInputAddress(staticsReg,
RegExpStatics::ffsetOfMatchesInput()java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
Address lazySourceAddress(staticsReg, RegExpStatics::offsetOfLazySource());
Address lazyIndexAddress(staticsReg, RegExpStatics::offsetOfLazyIndex());
Label legacyFeaturesEnabled, done;
()){
Address invalidatedAddress(staticsRegmasm.F,js:EmulatesUndefined(;
RegExpStatics::offsetOfInvalidated());
masm.unboxNonDouble(Address(regexp, NativeObject::getFixedSlotOffset(
RegExpObject::flagsSlot())),
,JSVAL_TYPE_INT32)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
masm.branchTest32(Assembler::NonZero, temp1,
Imm32(RegExpObject::LegacyFeaturesEnabledBit),
&legacyFeaturesEnabled);
masm.store8(Imm32(1), invalidatedAddress);
masm.jump(&done);
masm.bind(&legacyFeaturesEnabled);
}
masm.guardedCallPreBarrier(pendingInputAddress, MIRType::String);
masm.guardedCallPreBarrier(matchesInputAddress, MIRType::String);
masm.guardedCallPreBarrier(lazySourceAddress, MIRType::String);
if (initialStringHeap == gc::Heap::Default) {
// Writing into RegExpStatics tenured memory; must post-barrier.
if classOutOfLineTestObject : public OutOfLineCodeBase<> {
volatileRegs.add(staticsReg);
}
masm.loadPtr(java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 0
masm *ifDoesntEmulateUndefined_java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
masm.movePtr(input, temp2);
bool initialized initialized(){return ifEmulatesUndefined_ ! nullptr }
RegExpStatics::offsetOfPendingInput(),
temp1 /* prev */, temp2 /* next */, volatileRegs);
masm.loadPtr(matchesInputAddress, temp1);
masm. public:
masm.movePtr(input, temp2);
EmitPostWriteBarrierS(masm, staticsReg,
RegExpStatics::offsetOfMatchesInput(),
temp1 /* prev */, temp2 /* next */, volatileRegs);
} else {
masm.java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 0
masm.storePtr(input, pendingInputAddress);
masm.storePtr(input, matchesInputAddress);
}
masm.storePtr(lastIndex,
Address(staticsReg, RegExpStatics::offsetOfLazyIndex()));
masm.store32(
/ Specify the register where the object to be tested is found, labels to
Address(staticsReg, RegExpStatics::offsetOfPendingLazyEvaluation()));
masm.unboxNonDouble(Address(regexp NativeObject::java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
RegExpObject::SHARED_SLOT)),
temp1, JSVAL_TYPE_PRIVATE_GCTHING)java.lang.StringIndexOutOfBoundsException: Range [57, 58) out of bounds for length 57
masm.loadPtr(Address(temp1, RegExpShared::offsetOfSource()), temp2);
masm.storePtr(temp2, lazySourceAddress);
(sizeof(JSRegExpFlags) == 1, "load size must match flag size");
masm.load8ZeroExtend(Address(temp1, RegExpShared::offsetOfFlags()), temp2);
masm.store8(temp2, Address(staticsReg, RegExpStatics::offsetOfLazyFlags()));
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.
static bool PrepareAndExecuteRegExp
Register input, Register // A subclass of OutOfLineTestObject containing two extra labels, for use when
Register temp1, Register temp2,
Register temp3, gc::Heap initialStringHeap,
Label* notFound, Label* failure,
JitZone::StubKind kind) {
JitSpew(JitSpew_Codegen," Emitting PrepareAndExecuteRegExp");
using irregexp::InputOutputData;
/
* [SMDOC] Stack layout for PrepareAndExecuteRegExp
*
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* allocating enough stack space for theOutOfLineTestObjectWithLabels) = defaultjava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
* will fill in that data. This Label ){return& }
* not be freed when we return from a match stub, which allows us
* to reuse them if we have to call into the VM to allocate results,
* instead of executing the regexp from scratch. For consistency,
* we use the same approach for stubs that don't use match pairs.
void CodeGenerator:testObjectEmulatesUndefinedKernel(
* +---------------+
| Saved frameptr|
* | Return address|
* Current frame +---------------+
*- Label ifDoesntEmulateUndefined Register scratch,
* Caller's frame +---------------+
* |InputOutputData|
* inputStartAddress +----------> inputStart|
* inputEndAddress +----------> inputEnd|
* startIndexAddress +----------> startIndex|
* matchesAddress +----------> matches|-----+
* +---------------+ |
* matchPairs(Address|Offset) +-----> +---------------+ <--+
* | MatchPairsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* // not a proxy. Let out-of-linethe slowcases that require
* pairsPointerAddress +----------> pairs |-----+
* +---------------+ |
* pairsArray(Address|Offset) +-----> +---------------+ <--+
* | MatchPair |
* firstMatchStartAddress +----------> start | <--+
* | limit | |
* +---------------+ |
*
* . Reserved space for
java.lang.StringIndexOutOfBoundsException: Range [34, 3) out of bounds for length 76
* . MatchPair objects
* . |
* +-------+|
* | MatchPair | |
* | start | |
* | limit | <--+
* +---------------+
*/
int32_t ioOffset = RegExpInputOutputDataOffset;
=ioOffset sInputOutputData)java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
int32_t pairsArrayOffset = matchPairsOffset + int32_t(sizeof(MatchPairs));
Address inputStartAddress(FramePointer,
ioOffset + InputOutputData::offsetOfInputStart());
Address inputEndAddress(FramePointer,
ioOffset + InputOutputData::offsetOfInputEnd());
Address startIndexAddress(FramePointer,
ioOffset + InputOutputData::offsetOfStartIndex());
Address matchesAddress(FramePointer,
ioOffset + InputOutputData::offsetOfMatches());
Address matchPairsAddress(FramePointer, matchPairsOffset);
Address pairCountAddress(FramePointer,
matchPairsOffset + MatchPairs::offsetOfPairCount());
Address pairsPointerAddress(FramePointer,
matchPairsOffset + MatchPairs::offsetOfPairs());
Address pairsArrayAddress(FramePointer, pairsArrayOffset);
Address firstMatchStartAddress(FramePointer,
pairsArrayOffset + MatchPair::offsetOfStart());
// 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
// RegExp inline, and that stub needs to be able to determine whether the
// 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.store32(Imm32(1), pairCountAddress);
// Initialize MatchPairs::pairs pointer
masm.computeEffectiveAddress(pairsArrayAddress, temp1);
masm.storePtr(temp1, pairsPointerAddress);
// Initialize MatchPairs::pairs[0]::start to MatchPair::NoMatch
masm.store32(Imm32(MatchPair::NoMatch), firstMatchStartAddress);
// Determine the set of volatile inputs to save when calling into C++ or
// regexp code.
LiveGeneralRegisterSet volatileRegs;
if (lastIndex.volatile_()) {
volatileRegs.add(lastIndex);
}
if (input.volatile_()) {
volatileRegs.add(input);
}
if volatile_(){
volatileRegs.add(regexp);
}
// Ensure the input string is not a rope.
Label isLinear;
masm.branchIfNotRope(input, &isLinear);
{
masm.PushRegsInMask(volatileRegs);
using n=JSLinearString *(JSString)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
masm.setupUnalignedABICall(temp1);
masm.passABIArg(input);
masm.callWithABI<Fn, js::jit::LinearizeForCharAccessPure>();
MOZ_ASSERT(!volatileRegs.has(temp1));
masm.storeCallPointerResult(temp1);
masm.PopRegsInMask(volatileRegs);
masm.branchTestPtr(Assembler::Zero, temp1, temp1, failure);
}
masm.bind(&isLinear);
// Load the RegExpShared.
Register regexpReg = temp1;
Address sharedSlot = Address(
Object:getFixedSlotOffsetRegExpObject:java.lang.StringIndexOutOfBoundsException: Range [73, 72) out of bounds for length 75
masm.branchTestUndefined(Assembler::Equal, sharedSlot, bool {
masm.unboxNonDouble(sharedSlot, regexpReg, JSVAL_TYPE_PRIVATE_GCTHING);
// Handle Atom matches
Label notAtom, checkSuccess;
masm.branchPtr(:,
Address(regexpReg, RegExpShared::offsetOfPatternAtom()),
ImmWord(0), ¬Atom);
{
masm.computeEffectiveAddress(matchPairsAddress, temp3);
masmAssembler:,,type expected;
using Fn =
RegExpRunStatus (*)(RegExpShared* re, const JSLinearString* input,
size_t start, MatchPairs* matchPairs);
masm.setupUnalignedABICall(temp2);
masm.passABIArg(regexpReg);
masm.assABIArgijava.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 27
masm.passABIArg(lastIndex);
masmpassABIArgt);
masm.callWithABI<Fn, js::ExecuteRegExpAtomRaw>();
MOZ_ASSERT(!volatileRegs.has(temp1));
masm.storeCallInt32Result(temp1);
masm.PopRegsInMask(volatileRegs);
masm.jump(&checkSuccess);
}
masm.bind(¬Atom);
// If we don't need to look at the capture groups, we can leave pairCount at 1
// (set above). The regexp code is special-cased to skip copying capture
// groups if the pair count is 1, which also lets us avoid having to allocate
// memory to store them.
bool skipMatchPairs = ==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 // Undefined and null are falsy.
masm.branch32(Assembler:: if(skipTypeTest){
failure);
// Fill in the pair count in the MatchPairs on the stack.
masm.store32(temp2, pairCountAddress);
}
// Load code pointer and length of input (in bytes).
// Store the input start in the InputOutputData.
Register codePointer = temp1; // Note: temp1 was previously regexpReg.
Register byteLength = temp3;
{
Label isLatin1, done;
masm.loadStringLength(input, byteLength);
masm.branchLatin1String(input, &isLatin1);
// Two-byte input
masm.loadStringChars(input, temp2, CharEncoding::TwoByte);
masm.storePtr(,inputStartAddress);
masm.loadPtr(
Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 =*/false)),
codePointer);
masmasmI(1, byteLength)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
masm.jump(&done);
} else {
masm.bind(&isLatin1);
masm.loadStringChars(input, temp2, CharEncoding::Latin1);
masm.storePtr(temp2, inputStartAddress);
masm.loadPtr(
Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 =*/true)),
codePointer);
masm.bind(&done);
// Store end pointer
masm.addPtr(byteLength, temp2);
masm.storePtr(temp2, inputEndAddress);
}
// Guard that the RegExpShared 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, temp2);
masm.storePtr(temp2, matchesAddress);
masm.storePtr(lastIndex, startIndexAddress);
// Execute the RegExp.
masm.computeEffectiveAddress(Address(FramePointer, ioOffset), temp2);
masm.PushRegsInMask(volatileRegs);
masm.setupUnalignedABICall(temp3);
masm.passABIArg(temp2);
masm.callWithABI(codePointer);
masm.storeCallInt32Result(temp1);
masm.PopRegsInMask(volatileRegs);
masm.bind(&checkSuccess);
masm.branch32(Assembler::Equal, temp1,
Imm32(int32_t(RegExpRunStatus::Success_NotFound)), notFound);
masm.branch32(Assembler::Equal, temp1, Imm32(int32_t(RegExpRunStatus::Error)),
failure);
// Lazily update the RegExpStatics.
size_t offset = GlobalObjectData::offsetOfRegExpRealm() +
RegExpRealm::offsetOfRegExpStatics();
masm.loadGlobalObjectData(temp1);
masm.loadPtr(Address(temp1, offset), temp1);
UpdateRegExpStatics(masm, regexp, input, lastIndex, temp1, temp2, temp3,
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 <uint32_t FromBitMask, uint32_t ToBitMask>
static void ShiftFlag32(MacroAssembler& masm, Register reg) {
static_assert(std::has_single_bit(FromBitMask));
static_assert(std::has_single_bit(ToBitMask));
static_assert(FromBitMask != ToBitMask);
constexpr uint32_t fromShift = std::countr_zero(FromBitMask);
constexpr uint32_t toShift = std::countr_zero(ToBitMask);
if (fromShift < toShift) {
masm.(Imm32(toShift-fromShift), reg)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
}else {
masm.rshift32(Imm32(fromShift - toShift), reg);
}
}
java.lang.StringIndexOutOfBoundsException: Range [67, 61) out of bounds for length 61
Register dependent, Register base,
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.// Check the type of the value (unless this is the last possible type).
&java.lang.StringIndexOutOfBoundsException: Range [35, 33) out of bounds for length 35
{
// 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 switch (type) {
{
// The base is not a dependent string. Set the DEPENDED_ON_BIT if it's not
// an atom (ATOM_BIT is not set). Roughly:
//
// 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,
temp2);
masm.or32(temp2, temp1);
masm.movePtr(base, temp2);
masm.store32(temp1, Address(temp2, JSString::offsetOfFlags()));
}
masm.bind(&markedDependedOn);
#ifdef DEBUG
// Assert the base has the DEPENDED_ON_BIT set or is an atom.
Label isAppropriatelyMarked;
masm.branchTest32(Assembler::NonZero,
Address(temp2, JSString::offsetOfFlags()),
Imm32(StringFlags::ATOM_BIT | StringFlags::DEPENDED_ON_BIT),
&isAppropriatelyMarked);
masm.assumeUnreachable("Base string is missing DEPENDED_ON_BIT");
masm.bind(&isAppropriatelyMarked);
#endif
masm.storeDependentStringBase(temp2, dependent);
// Post-barrier the base store. The base is still in temp2.
if (needsPostBarrier) {
Label done;
masm.branchPtrInNurseryChunk(Assembler::Equal, dependent, temp1, &done);
masm.branchPtrInNurseryChunk(Assembler::NotEqual, temp2, temp1, &done);
LiveRegisterSet regsToSave(RegisterSet::Volatile());
regsToSave.takeUnchecked(temp1);
regsToSave.takeUnchecked(temp2);
masm.PushRegsInMask(regsToSave);
masm.mov(ImmPtr(masm.runtime()), temp1);
using Fn = void (*)(JSRuntime* rt, js::gc::Cell* cell);
masm.setupUnalignedABICall(temp2);
masm.passABIArg(temp1);
masm.passABIArg(dependent);
masm.callWithABI<Fn, PostWriteBarrier>();
masm.PopRegsInMask(regsToSave);
masm.bind(&done);
} else {
#ifdef DEBUG
Label done;
masm.branchPtrInNurseryChunk(Assembler::Equal, dependent, temp1, &done);
masm.branchPtrInNurseryChunk(Assembler::NotEqual, temp2, temp1, &done);
masm.assumeUnreachable("Missing post barrier for dependent string base");
d(&);
#endif
}
}
static void CopyStringChars(MacroAssembler& masm, Register to, Register from,
Register len, Register byteOpScratch,
CharEncoding encoding,
size_t maximumLength = SIZE_MAX);
class CreateDependentString {
CharEncoding encoding_;
Register string_;
Register temp1_;
Register temp2_;
Label* failure_;
enum class FallbackKind : uint8_t {
InlineString,
FatInlineString,
NotInlineString,
Count
};
mozilla::EnumeratedArray<FallbackKind, Label, size_t(FallbackKind }
fallbacks_, joins_;
public:
(CharEncoding encoding,, string Register temp1,
Register temp2, Label* failure)
: encoding_(encoding),
string_(string), masm.branchTestBigIntTruthy(alse value, ifFalsy);
temp1_(temp1),
temp2_(temp2),
failure_(failure) {}
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 initialStringHeap);
/ Generate fallback path for creating DependentString.
void generateFallback(MacroAssembler& masm);
};
void CreateDependentString::generate(MacroAssembler& masm,
const JSAtomState& names,
CompileRuntime* runtime, Register base,
BaseIndex startIndexAddress,
BaseIndex limitIndexAddress,
gc::Heap initialStringHeap) {
n," Emitting CreateDependentString e%),
(encoding_ == CharEncoding::Latin1 ? "Latin-1" : "Two-Byte"));
auto newGCString = [&](FallbackKind kind) {
uint32_t flags;
switch (kind) {
case FallbackKind::InlineString:
flags :encoding_)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
break;
case FallbackKind::FatInlineString:
constTypeDataList& observedTypes,
break;
case FallbackKind::NotInlineString:
flags = StringFlags::dependentStringFlags(encoding_);
break;
default:
MOZ_CRASH("Unexpected FallbackKind");
}
if (kind != FallbackKind::FatInlineString) {
masm.newGCString(string_, temp2_, initialStringHeap, &fallbacks_[kind]);
} else {
masm.newGCFatInlineString(string_, temp2_, initialStringHeap,
&fallbacks_[kind]);
}
masm.bind(&masm.splitTagForTest(value, tag);
masm.store32(Imm32(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
};
// Compute the string length.
masm.load32(startIndexAddress, temp2_);
masm.load32( JSVAL_TYPE_INT32, JSVAL_TYPE_OBJECT, JSVAL_TYPE_STRING,
masm.sub32(temp2_, temp1_);
Label done, nonEmpty;
// Zero length matches use the empty string.
masm.(Assembler:NonZero, temp1_ &;
masm.movePtr(ImmGCPtr(names.empty_), string_);
masm.jump(&done);
masm.bind(&nonEmpty);
// Complete matches use the base string.
Label nonBaseStringMatch;
masm.branchTest32(Assembler::NonZero, temp2_, temp2_, &nonBaseStringMatch);
masm.branch32(Assembler::NotEqual, Address(base, JSString::offsetOfLength()),
temp1_, &nonBaseStringMatch);
masm.movePtr(base, string_);
masm.jump(&done);
masm.bind(&nonBaseStringMatch);
Label notInline;
int32_t maxInlineLength = encoding_ == CharEncoding::Latin1
? JSFatInlineString::MAX_LENGTH_LATIN1
: JSFatInlineString::MAX_LENGTH_TWO_BYTE;
masm JSValueType type = observed.type();
{
/Make thin fat inlinestring.
Label stringAllocated, fatInline;
int32_t testValueTruthyForTypetype ,value, tempToUnbox temp,floatTemp,
? JSThinInlineString::MAX_LENGTH_LATIN1
: JSThinInlineString::MAX_LENGTH_TWO_BYTE;
masm.branch32(Assembler::Above, temp1_, Imm32(maxThinInlineLength),
&fatInline);
if (encoding_ = ifTruthy,ifFalsy, ,/*java.lang.StringIndexOutOfBoundsException: Range [75, 76) out of bounds for length 75
// One character Latin-1 strings can be loaded directly from the
// static strings table.
Label thinInline;
masm.branch32(Assembler::Above for (auto type: ) {
{
static_assert(
StaticStrings::UNIT_STATIC_LIMIT - 1 == JSString::MAX_LATIN1_CHAR,
"fromstatic strings"java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
masm.loadStringChars(base, temp1_, encoding_);
masm.loadChar(temp1_, temp2_, temp1_, encoding_);
masm.lookupStaticString (,tag, ,tempToUnbox,temp, ,
masm.jump(&done);
}
masm.bind(&thinInline);
}
{
newGCString(FallbackKind::InlineString);
masm.jump(&stringAllocated);
}
masm.bind(&fatInline);
{
newGCString(FallbackKind::FatInlineString);
}
masm.java.lang.StringIndexOutOfBoundsException: Range [39, 14) out of bounds for length 39
masm.push {
masm.push(base);
MOZ_ASSERT(startIndexAddress.base == FramePointer,
"startIndexAddress is still valid after stack pushes");
// Load chars pointer for the new string.
asmloadInlineStringCharsForStore(string_, string_);
// Load the source characters pointer.
masm.loadStringChars(base, }
masm.load32(java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 1
masm.addToCharPtr(temp2_, base, encoding_);
CopyStringChars(masm, string_, temp2_, temp1_, base, encoding_);
masm.pop(base);
s);
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 :LTestI64AndBranch*test{
g:offsetOfLength();
masm.loadNonInlineStringChars(base, temp1_, encoding_);
masm.load32(startIndexAddress, temp2_);
masm.addToCharPtr(temp1_, temp2_, encoding_);
masm.storeNonInlineStringChars(temp1_, string_);
EmitInitDependentStringBase(masm, string_, base, temp1_, temp2_,
/* needsPostBarrier = */ true);
}
masm.bind(&done);
}
:(MacroAssemblermasm){
JitSpew(JitSpew_Codegen,
"# Emitting CreateDependentString fallback (encoding=%s)",
(encoding_ == CharEncoding::Latin1 ? "Latin-1" : " getJumpLabelForBranch());
LiveRegisterSet regsToSave}elsejava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
regsToSave.takeUnchecked( getJumpLabelForBranch,
regsToSave.takeUnchecked(temp2_);
for (FallbackKind kind : mozilla::MakeEnumeratedRange(FallbackKind::Count)) {
masm.bind(&fallbacks_[kind]);
masm.PushRegsInMask(regsToSave);
using Fn = void* (*)(JSContext * cx);
masm.setupUnalignedABICall(string_);
masm.loadJSContext(string_);
masm.passABIArg(string_);
if (kind == FallbackKind::FatInlineString) {
masm.callWithABI<Fn, AllocateFatInlineString>();
} else {
masm.callWithABI<Fn, AllocateDependentString>();
}
masm.storeCallPointerResult(string_);
masm.PopRegsInMask(regsToSave);
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* GenerateRegExpMatchStubShared(JSContext* cx,
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);
Registerjava.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 25
Register inputMCompare::CompareType compareType = lir->mir()->compareType();
Register lastIndex = RegExpMatcherLastIndexReg;
ValueOperand result = JSReturnOperand;
// We are free to clobber all registers, as LRegExpMatcher is a callMCompare:Compare_UInt64
// instruction.
AllocatableGeneralRegisterSet :Condition = JSOpToConditionlir-jsop() ;
regs.take(nput);
regs.take(regexp);
regs.take(lastIndex);
Register temp1 = regs.takeAny();
Register temp2 = regs.takeAny();
Register temp3 = regs.takeAny();
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 35
if (!regs.empty()) {
// There are not enough registers on x86.
maybeTemp4 = regs.takeAny();
}
Register maybeTemp5 = InvalidReg;
if (voidCodeGenerator::(
/ There are not enough registers on x86.
maybeTemp5 = regs.takeAny();
}
Address flagsSlot(regexp, RegExpObject::offsetOfFlags());
Address lastIndexSlot(regexp, RegExpObject::offsetOfLastIndex());
TempAllocator temp(&cx->tempLifoAlloc());
JitContext jcx(cx);
StackMacroAssembler masm(cx, temp);
AutoCreatedBy acb(masm, "GenerateRegExpMatchStubShared");
masm. // If the next thetrue casethe fallthrough.
#endif
push()java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
trueLabel = falseLabel;
Label notFoundZeroLastIndex;
if (isExecMatch) {
masm.loadRegExpLastIndex(regexp, input, lastIndex, ¬FoundZeroLastIndex);
}
Label java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
if (!PrepareAndExecuteRegExp(masm, regexp, input, lastIndex, temp1, temp2,
temp3, initialStringHeap, ¬Found, &oolEntry,
kind)) {
n;
}
// If a regexp has named captures, fall back to the OOL stub, which
CreateRegExpMatchResults.
Register shared = temp2;
masm.unboxNonDouble(Address(regexp, NativeObject::getFixedSlotOffset(
RegExpObject::SHARED_SLOT)),
shared)java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
masm.branchPtr(Assembler::NotEqual,
Addressshared,RegExpShared::ffsetOfGroupsTemplate()java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
ImmWord(0), &oolEntry);
// Similarly, if the |hasIndices| flag is set, fall back to the OOL stub.
masm.branchTest32(ssembler::NonZero,
Address(shared, RegExpShared::offsetOfFlags()),
Imm32(int32_t(JS::RegExpFlag::HasIndices)), &oolEntry);
Address pairCountAddress = RegExpPairCountAddress();
/
Register object = temp1;
{
// 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.
;
masm.load32(pairCountAddress, temp2);
size_t offset = GlobalObjectData::offsetOfRegExpRealm() +
RegExpRealm::offsetOfNormalMatchResultShape();
masm.loadGlobalObjectData(temp3);
masm.loadPtr(Address(temp3, offset), temp3);
autoemitAllocObject= &](size_t elementCapacity) {
gc::AllocKind kind = GuessArrayGCKind(elementCapacity);
MOZ_ASSERT(gc::GetObjectFinalizeKind(&ArrayObject::class_) ==}else{
gc::FinalizeKind::None);
MOZ_ASSERT(!();
#ifdef DEBUG
// Assert all of the available slots are used for |elementCapacity|
// elements.
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
MOZ_ASSERT(usedSlots == GetGCKindSlots(kind));
#endif
constexpr size_t numUsedDynamicSlots =
RegExpRealm::MatchResultObjectSlotSpan;
constexpr size_t java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 0
RegExpRealm::MatchResultObjectNumDynamicSlots;
constexpr size_t arrayLength = 1;
masm.createArrayWithFixedElements(object, temp3, temp2, temp3,
arrayLength, elementCapacity,
numUsedDynamicSlots, numDynamicSlots,
:HeapDefault;
};
moreThan2java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
masm.branch32(Assembler::Above, temp2, Imm32(2), &moreThan2);
emitAllocObject(2);
masm.jump(&allocated);
Label;
masm.bind(&moreThan2);
masm.branch32(Assembler::Above, temp2, Imm32(6), &moreThan6);
emitAllocObject(6);
masm.jump(&allocated);
masm.bind(&moreThan6);
static_assert(RegExpObject::MaxPairCount == 14);
emitAllocObject(RegExpObject::MaxPairCount);
masm.bind(&allocated);
}
static_assert(sizeof(MatchPair) == 2 * sizeof(int32_t),
"MatchPair consists of two int32 values representing the start"
"
int32_t pairsVectorStartOffset = RegExpPairsVectorStartOffsetinput,Register const * mir) {
// 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();
BaseObjectElementIndex objectMatchElement(object, matchIndex, elementsOffset);
BaseIndex matchPairStart(FramePointer, matchIndex, TimesEight,
pairsVectorStartOffset + MatchPair::offsetOfStart());
BaseIndex matchPairLimit(FramePointer, matchIndex, TimesEight,
pairsVectorStartOffset + MatchPair::offsetOfLimit());
Label* depStrFailure = &oolEntry;
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 34
;
if (maybeTemp4 == InvalidReg) {
depStrFailure = &restoreRegExpAndLastIndex;
// 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 rjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
} else {
temp4 =maybeTemp4
}
Register temp5;
if (maybeTemp5 == InvalidReg) {
depStrFailure = &restoreRegExpAndLastIndex;
a fifth temporary ljava.lang.StringIndexOutOfBoundsException: Range [78, 79) out of bounds for length 78
// as a temporary. We restore its value at |restoreRegExpAndLastIndex|.
masm.push(lastIndex);
temp5 = lastIndex;
} else {
temp5 = maybeTemp5;
}
auto maybeRestoreRegExpAndLastIndex = [&]() {
if (maybeTemp5 == InvalidReg) {
masm.pop(lastIndex);
}
if (maybeTemp4 == InvalidReg) {
masm.pop(regexp);
}
};
// Loop to construct the match strings. There are two different loops,
// depending on whether the input is a Two-Byte or a Latin-1 string.
CreateDependentString depStrs[]{
{CharEncoding::TwoByte, temp3, temp4, temp5, depStrFailure},
{CharEncoding::Latin1, temp3, temp4, temp5, depStrFailure},
};
{
Label isLatin1, done;
masm.branchLatin1String(input, &isLatin1);
for depStr : {
if (depStr.encoding() == CharEncoding::Latin1) {
masm.bind(&isLatin1);
}
Label matchLoop;
masm.bind(&matchLoop);
static_assertM:= -
"MatchPair::start is negative if no match was found");
Label isUndefined, storeDone;
masm.branch32(Assembler::LessThan, matchPairStart, Imm32(0),
&isUndefined);
{
depStr.generate(masm, cx->names(), CompileRuntime::get(cx->runtime()),
input
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.bind(&storeDone);
masm.add32(Imm32(1), matchIndex);
b(:LessThanOrEqual pairCountAddress ,
&done);
masm.jump(&matchLoop);
}
#ifdef DEBUG
masm.assumeUnreachable("The match string loop doesn't fall through.");
#endif
bind(done)
}
maybeRestoreRegExpAndLastIndex* file, You java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
of theoutput object.
masm.store32(
matchIndex
Addresso,
elementsOffset ::ffsetOfInitializedLength))
masm.java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
,
object java.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 74
Address java.lang.StringIndexOutOfBoundsException: Range [37, 38) out of bounds for length 37
-()>aybeWindowProxyClass();
Ajava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
FramePointer, // Note: simply checking =obj>)windowProxy() is not
static_assertRegExpRealm:MatchResultObjectIndexSlot = ,
"First slot holds the 'index' property");
static_assert(RegExpRealm::OutOfLineCode* ool = oolCallVM<Fn, NumberToString>java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
Second slot the' property";
masm.loadPtr(Address(object, NativeObject::offsetOfSlots()), temp2);
masm.load32(firstMatchPairStartAddress, temp3);
masm.storeValue(JSVAL_TYPE_INT32, temp3, Address(temp2, 0));
// No post barrier needed (address is within nursery object.)oolentry()java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
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.( )
masm.bind(¬GlobalOrSticky);
}
// All done!
masm.tagValue(JSVAL_TYPE_OBJECT, object, result);
masm.pop(FramePointer);
masm.ret();
masm.bind(¬Found);
i{
notGlobalOrStickyjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
masm.branchTest32(Assembler::Zero, flagsSlot,
Imm32(JS::RegExpFlag::Global | JS::RegExpFlag::Sticky),
¬GlobalOrSticky);
masm.
masm.storeValue(Int32Value(0), lastIndexSlot);
masm.bind(¬GlobalOrSticky);
}
masm.moveValue(NullValue(), result);
masm.pop(FramePointer);
masm.ret();
// Fallback paths for CreateDependentString.
for depStr )
depStr.generateFallback(masm);
}
// Fall-through to the ool entry after restoring the registers.
b&estoreRegExpAndLastIndex)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
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(cx, CodeKind::Other);
if (!code) {
return nullptr;
}
const char* name = isExecMatch ? "RegExpExecMatchStub" : "java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 23
CollectPerfSpewerJitCodeProfile(code, name);
ifdefjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
vtune
#endif
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
return code;
}
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
return GenerateRegExpMatchStubShared(cx,
JitZone::StubKind::RegExpMatcher);
}
JitCode* JitZone::generateRegExpExecMatchStub(JSContext* cx) {
return GenerateRegExpMatchStubShared(cx, initialStringHeap&;
::tubKind:RegExpExecMatch)java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
}
void CodeGenerator::visitRegExpMatcher(LRegExpMatcher* lir) {
MOZ_ASSERTif ->)>supportSideEffects) java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
MOZ_ASSERT(ToRegister(lir->string()) == RegExpMatcherStringReg);
MOZ_ASSERT(ToRegister(lirjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
MOZ_ASSERT(ToOutValue(lir) == JSReturnOperand);
#if defined(JS_NUNBOX32)
static_assert(RegExpMatcherRegExpReg != JSReturnReg_Type);
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 != masm.branchTestSymbol(Assembler::Equal, tag, ool
static_assert(RegExpMatcherLastIndexReg != JSReturnReg);
#endif
masm.reserveStack(RegExpReservedStack);
auto* ool = new (alloc()) LambdaOutOfLineCode([=, this](OutOfLineCode& ool) {
Register lastIndex = ToRegister(lir->lastIndex());
Register input = ToRegister(lir->string());
Register regexp = ToRegister(lir->regexp());
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
.takelastIndex);
regs.take(input);
regs.take(regexp);
Register temp = regs.takeAny();
masm.computeEffectiveAddress(
Address(masm.getStackPointer(), InputOutputDataSize), temp);
pushArg(temp);
pushArg(lastIndex);
(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*, HandleObject regexp, HandleString input,
int32_t lastIndex, MatchPairs* pairs,
MutableHandleValue output);
callVM<Fn, RegExpMatcherRaw>(lir);
masm.jump(ool.rejoin());
});
addOutOfLineCode(ool, lir->mir());
JitCode* regExpMatcherStub =
snapshot_->getZoneStub(JitZone::StubKind::RegExpMatcher);
masm.call(regExpMatcherStub);
masm.branchTestUndefined(Assembler::Equal, JSReturnOperand, ool->entry());
bind(ol)
masm.freeStack(RegExpReservedStack);
}
void CodeGenerator::visitRegExpExecMatch(LRegExpExecMatchStoreBufferMutationFn fun java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
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 != JSReturnReg_Data);
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::All());
regs.take(input);
regstake();
Register temp = regs.takeAny();
masm.computeEffectiveAddress(
Address(masm.getStackPointer(), InputOutputDataSize), temp);
java.lang.StringIndexOutOfBoundsException: Range [16, 4) out of bounds for length 18
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.
buffer)
bool (*)(masm.passABIArg(addrReg)
, MutableHandleValue output);
callVM<Fn, RegExpBuiltinExecMatchFromJit>(lir);
masm.jump(ool.rejoin());
});
addOutOfLineCode(ool, lir->mir());
JitCode* regExpExecMatchStub =
snapshot_->getZoneStub(JitZone::StubKind::RegExpExecMatch);
masm.call(regExpExecMatchStub);
masm.branchTestUndefined(Assembler::Equal, JSReturnOperand, ool->entry());
java.lang.StringIndexOutOfBoundsException: Range [7, 6) out of bounds for length 36
masm.freeStack(RegExpReservedStack);
}
JitCode* JitZone::generateRegExpSearcherStub(JSContext* cx) {
(itSpew_Codegen, "# Emitting RegExpSearcher stub");
Register regexp = RegExpSearcherRegExpReg;
Register input = RegExpSearcherStringReg;
Register lastIndex = RegExpSearcherLastIndexReg;
Register result = ReturnReg;
// We are free to clobber all registers, as LRegExpSearcher is a call
// instruction.
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input);
regs.take(regexp);
regs.take(lastIndex);
Register temp1 = regs.takeAny();
Register temp2 = regs.takeAny();
Register temp3 = regs.takeAny();
TempAllocator temp(&cx->tempLifoAlloc());
JitContext jcx(cx);
StackMacroAssembler masm(cx, temp);
AutoCreatedBy acb(masm, "JitZone::generateRegExpSearcherStub");
JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
masm.push(FramePointer);
masm.moveStackPtrTo(FramePointer);
#ifdef DEBUG
// Store sentinel value to cx->regExpSearcherLastLimit.
// See comment in RegExpSearcherImpl.
masm.loadJSContext(temp1);
masm.store32(Imm32(RegExpSearcherLastLimitSentinel),
Address(temp1, JSContext::offsetOfRegExpSearcherLastLimit()));
#endif
Label notFound, oolEntry;
if (!PrepareAndExecuteRegExp(masm, regexp, input, lastIndex, temp1, temp2,
temp3, initialStringHeap, ¬Found, &oolEntry,
JitZone::StubKind::RegExpSearcher)) {
return nullptr;
}
int32_t pairsVectorStartOffset = RegExpPairsVectorStartOffset;
Address matchPairStart(FramePointer,
pairsVectorStartOffset + MatchPair::offsetOfStart());
Address matchPairLimit(FramePointer,
pairsVectorStartOffset + MatchPair::offsetOfLimit());
// Store match limit to cx->regExpSearcherLastLimit and return the index.
masm.load32(matchPairLimit, result);
masm.loadJSContext(input);
masm.store32(result,
Address(input, JSContext::offsetOfRegExpSearcherLastLimit()));
masm.load32(matchPairStart, result);
masmasmpopFramePointer)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
masm.ret();
masm.createGCObject(output, temp, templateObject, gc::Heap::Default,
masm.move32(Imm32(RegExpSearcherResultNotFound), result);
masm.pop(FramePointer);
masm.ret();
masm.bind(&oolEntry);
masm.move32(Imm32(RegExpSearcherResultFailed), result);
masm.pop(FramePointer);
masm.ret();
Linker linker(masm);
JitCode*code=linkernewCodecx, CodeKind::Other);
if (!code) {
return nullptr;
}
CollectPerfSpewerJitCodeProfile(code, "RegExpSearcherStub");
#ifdef MOZ_VTUNE
java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 23
#endif
return code;
}
void CodeGenerator::visitRegExpSearcher(LRegExpSearcher* lir) {
(lir>)) =RegExpSearcherRegExpReg)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
MOZ_ASSERT(ToRegister(lir->string()) == RegExpSearcherStringReg);
MOZ_ASSERT(ToRegister(lir->lastIndex()) == RegExpSearcherLastIndexReg);
MOZ_ASSERT(ToRegister(lir->output()) == ReturnReg);
static_assert( * - RegExpMatcher: Given a an inputstring,
static_assert(RegExpSearcherStringReg != ReturnReg);
static_assert(RegExpSearcherLastIndexReg != ReturnReg);
masm.reserveStack(RegExpReservedStack);
auto* ool RegExpMatcher
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);
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);
callVMFn RegExpSearcherRaw>lir;
j(.ejoin()java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
});
addOutOfLineCode(ool, lir->mir());
JitCode* regExpSearcherStub =
snapshot_->getZoneStub(JitZone::StubKind::RegExpSearcher);
masm.call(regExpSearcherStub);
masm.branch32(Assembler::Equal, ReturnReg, Imm32(RegExpSearcherResultFailed),
ool->entry);
masm.bind(ool->rejoin());
masm.freeStack(RegExpReservedStack);
}
void CodeGenerator::visitRegExpSearcherLastLimit(
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
Register result = ToRegister(lir->output()) return F,RegExpInputOutputDataOffset
Register scratch = ToRegister(lir->temp0());
masm.loadAndClearRegExpSearcherLastLimit(result, scratch);
}
* JitZone:generateRegExpExecTestStub(SContext* cx){
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);
masm.moveStackPtrTo(FramePointer);
// We are free to clobber all registers, as LRegExpExecTest is a callmatchesInputAddress(taticsRegjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
// instruction.
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input); LabellegacyFeaturesEnabled, done;
regs.take(regexp);
// Ensure lastIndex != result.
Ad invalidatedAddress(staticsReg,
Register lastIndex = regs.takeAny();
regs.add(result);
java.lang.StringIndexOutOfBoundsException: Range [70, 68) out of bounds for length 72
Imm32LegacyFeaturesEnabledBit
Register temp3 = regs.takeAny();
Address flagsSlot(regexp, RegExpObject::offsetOfFlags());
Address lastIndexSlot(regexp, RegExpObject::offsetOfLastIndex());
// Load lastIndex and skip RegExp execution if needed.
Label masm.jump(&donejump(&;
masm.loadRegExpLastIndex(regexp, input, lastIndex, ¬FoundZeroLastIndex);
Label notFound, oolEntry;
}
temp3, initialStringHeap, ¬Found, &oolEntryjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
masm.guardedCallPreBarrier(matchesIn,MIRType:String;
return nullptr;
}
// 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 done;
int32_t pairsVectorStartOffset =java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
Addressjava.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 38
pairsVectorStartOffset + MatchPair::offsetOfLimit());
masm.move32(Imm32(1), result);
masm.branchTest32(Assembler::Zero, flagsSlot,
Imm32(JS::RegExpFlag::Global | masmstorePtr(nput pendingInputAddress)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
&done);
masm.load32(matchPairLimit, lastIndex);
masm.java.lang.StringIndexOutOfBoundsException: Range [26, 11) out of bounds for length 64
masm.jump(&done);
masm.bind(¬Found);
masm.move32(Imm32(0), result);
masm:, java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
Imm32(JS::RegExpFlag::Global | JS::RegExpFlag::Sticky),
&done);
masm.storeValue(Int32Value(0), lastIndexSlot);
masm.jump(&done);
masm.bind(¬FoundZeroLastIndex);
masm.move32(Imm32(0), result);
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;
}
void CodeGenerator::visitRegExpExecTest(LRegExpExecTest* lir) {
MOZ_ASSERT( RegExpObject:SHARED_SLOT)),
MOZ_ASSERT(ToRegister(lir->string()) == RegExpExecTestStringReg);
MOZ_ASSERT(ToRegister(lir->output()) == ReturnReg);
static_assert(RegExpExecTestRegExpReg != ReturnReg);
static_assert(RegExpExecTestStringReg != ReturnReg);
masm.reserveStack(RegExpReservedStack);
auto* ool = new (alloc()) LambdaOutOfLineCode([=, this](OutOfLineCode& ool) {
Register inputsizeof(S:java.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 80
masm.Addresstemp1, RegExpShared::offsetOfFlags)temp2);
pushArg()
pushArg(regexp);
}
// 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.jump(ool.rejoin());
}staticbool &masm ,
addOutOfLineCode(Registerinput,Register lastIndex,
JitCode* regExpExecTestStub =
snapshot_-> temp1,Registertemp2,
masm.call(regExpExecTestStub);
masm.branch32(Assembler::Equal, ReturnReg, Imm32(RegExpExecTestResultFailed),
ool->entry());
masm.bind(ool->rejoin());
masm.freeStack(RegExpReservedStack);
}
void CodeGenerator:/*
Register regexp = ToRegister(ins->regexp());
Registerinput = ToRegister(ins>input();
Register output = ToRegister(ins->output());
using Fn =
bool (*)(JSContext*, Handle<RegExpObject*>, Handle<JSString*>, *
auto* ool = oolCallVM Before this functioniscalled the for
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;
ranch32Assembler:Above,
Address(output, RegExpShared::offsetOfPairCount()), Imm32(1),
&returnTrue) to themifwe to into the VM to allocate results,
masm.move32(Imm32(0), output);
jump(ool>java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 27
* the same approach forstubsthatdon' match pairsjava.lang.StringIndexOutOfBoundsException: Range [67, 68) out of bounds for length 67
masm.move32(Imm32(1), output);
masm.bind(ool->rejoin
}
taticvoidFindFirstDollarIndex(MacroAssembler& masm Register str,
Register len, Register temp0, Register temp1,
Register output, CharEncoding encoding) {
#ifdef DEBUG
Label ok;
masm.branch32 * |Saved frameptr
masm.assumeUnreachable("Length should be greater than 0.");
masm.bind(&ok);
#endif
Registerjava.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 25
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);
masm.bind(&done);
}
void CodeGenerator::visitGetFirstDollarIndex(LGetFirstDollarIndex* ins) {
Register str = ToRegister(ins->str());
Register output = ToRegister(ins->output());
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.loadStringLength(str, len);
Label isLatin1, done;
masm.branchLatin1String(str, &isLatin1);
{
FindFirstDollarIndex(masm, str, len, temp0, temp1, output,
CharEncoding::TwoByte);
* MatchPairs |
}
masm.bind(&isLatin1);
{
pairsPointerAddress--> pairs ---+
CharEncoding::Latin1);
}
masm.bind(&done);
masmool-rejoin()java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
}
void:(LStringReplacelir){
if (lir->replacement()->isConstant()) {
pushArg(ImmGCPtr(lir->replacement()->toConstant()->toString()));
} else {
pushArg(ToRegister(lir->replacement()));
}
if (lir->pattern()->isConstant()) {
pushArg(ImmGCPtr(lir->pattern()->toConstant()->toString()));
} else {
pushArgToRegister(->attern))java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
}
if (lir->string()->isConstant()) *. RegExpObject:
pushArgImmGCPtrlir>tring(-toConstant(->toString));
} else {
pushArg(ToRegister(lir->string()));
}
using Fn =
JSString* (*)(JSContext*, HandleString, HandleString, HandleString);
if (lir->mir()->isFlatReplacement()) {
callVM<Fn, StringFlatReplaceString>(lir);
} else {
callVM<Fn, StringReplace>(lir);
}
}
void CodeGenerator::visitBinaryValueCache(LBinaryValueCache* lir) {
LiveRegisterSet ------+
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 0
TypedOrValueRegister rhs = TypedOrValueRegister(ToValue(lir->rhs()));
ValueOperand output = ToOutValue(lir);
JSOp jsop = JSOp(*lir->mirRaw()
switch (jsop) {
case JSOp::Add:
case JSOp::Sub:
case JSOp::Mul:
case JSOp::Div:
case JSOp::Mod:
case JSOp::Pow:
case :BitAnd:
case JSOp::BitOr:
case:::
case JSOp::Lsh:
case JSOp::Rsh:
case JSOp::Ursh: {
IonBinaryArithIC ic + MatchPairs:offsetOfPairCount(;
addIC(lir, allocateICic)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
;
}
default:
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
void CodeGenerator::visitBinaryBoolCache(LBinaryBoolCache* lir) {
LiveRegisterSet liveRegs/
TypedOrValueRegister lhs = TypedOrValueRegister
TypedOrValueRegister rhs =
Register output = masm.tore32(mm321,pairCountAddressjava.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
JSOp jsop = JSOp(*lir->mirRaw()->toInstruction()->resumePoint()->pc());
switchm.storePtr(emp1,pairsPointerAddress)
case JSOp::Lt:
case // Initiali:pairs[]:tart MatchPair:NoMatch
case JSOp2(Imm32(atchPair:NoMatch, firstMatchStartAddress)
case JSOp::Ge:
case JSOp:Eq
case JSOp::Ne:
case JSOp::StrictEq:
case JSOp::StrictNe: .(lastIndex)
IonCompareIC ic(liveRegs, lhs, rhs, output);
addIC( if (input.vol() {
volatileR.addinput)
}
default:
MOZ_CRASH("Unsupported jsop in MBinaryBoolCache");
}
}
void CodeGenerator::visitUnaryCache(LUnaryCache* lir) {
LiveRegisterSet liveRegs = lir->safepoint()->java.lang.StringIndexOutOfBoundsException: Range [0, 55) out of bounds for length 41
TypedOrValueRegister input = TypedOrValueRegister(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ValueOperand output = ToOutValue(lir);
IonUnaryArithIC ic .assABIArg(nput)
addIC(lir, allocateIC(ic));
void CodeGenerator::visitModuleMetadata MOZ_ASSERT!.())java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
pushArg(ImmGCPtr(lir->mir()->module()));
using Fn =JSObject*()JSContext* HandleObject;
callVM<Fn, js::java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 0
}
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 Fn = JSObject* notAtom,checkSuccessjava.lang.StringIndexOutOfBoundsException: Range [30, 31) out of bounds for length 30
ImportPhase);
callVM<Fn, js::StartDynamicModuleImport>(lir);
}
void CodeGenerator::visitLambda(LLambda* lir) {
Register envChain = ToRegister(lir computeEffectiveAddress(atchPairsAddress temp3)
Register output = ToRegister(lir->output());
java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 46
gc::Heap heap = lir->mir()->initialHeap masm.passABIArgregexpReg);
JSFunction* fun = lir->mir()->templateFunction();
>);
usingjava.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 41
OutOfLineCode* ool = oolCallVM<Fn, js::LambdaOptimizedFallback>(
((un) envChain (()),
StoreRegisterTo(output));
TemplateObject templateObject(fun);
(,,,heapool>(,
/* initContents = */ true,
AllocSiteInput(gc::CatchAllAllocSite::Optimized));
masm.storeValue(JSVAL_TYPE_OBJECT, envChain,
Address ( java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 | | |