Commit 7d96f2d4 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

Fix Smi::IsValid assert in StringCharCodeAt deferred code.

Review URL: http://codereview.chromium.org/6303013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6424 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 727aa91b
......@@ -2821,20 +2821,31 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
LStringCharCodeAt* instr_;
};
DeferredStringCharCodeAt* deferred
= new DeferredStringCharCodeAt(this, instr);
Register scratch = scratch0();
Register string = ToRegister(instr->string());
Register index = no_reg;
int const_index = -1;
if (instr->index()->IsConstantOperand()) {
const_index = ToInteger32(LConstantOperand::cast(instr->index()));
STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
if (!Smi::IsValid(const_index)) {
// Guaranteed to be out of bounds because of the assert above.
// So the bounds check that must dominate this instruction must
// have deoptimized already.
if (FLAG_debug_code) {
__ Abort("StringCharCodeAt: out of bounds index.");
}
// No code needs to be generated.
return;
}
} else {
index = ToRegister(instr->index());
}
Register result = ToRegister(instr->result());
DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr);
Label flat_string, ascii_string, done;
// Fetch the instance type of the receiver into result register.
......@@ -2918,7 +2929,8 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
__ PushSafepointRegisters();
__ push(string);
// Push the index as a smi.
// Push the index as a smi. This is safe because of the checks in
// DoStringCharCodeAt above.
if (instr->index()->IsConstantOperand()) {
int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
__ mov(scratch, Operand(Smi::FromInt(const_index)));
......
......@@ -2656,19 +2656,30 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
LStringCharCodeAt* instr_;
};
DeferredStringCharCodeAt* deferred
= new DeferredStringCharCodeAt(this, instr);
Register string = ToRegister(instr->string());
Register index = no_reg;
int const_index = -1;
if (instr->index()->IsConstantOperand()) {
const_index = ToInteger32(LConstantOperand::cast(instr->index()));
STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
if (!Smi::IsValid(const_index)) {
// Guaranteed to be out of bounds because of the assert above.
// So the bounds check that must dominate this instruction must
// have deoptimized already.
if (FLAG_debug_code) {
__ Abort("StringCharCodeAt: out of bounds index.");
}
// No code needs to be generated.
return;
}
} else {
index = ToRegister(instr->index());
}
Register result = ToRegister(instr->result());
DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr);
NearLabel flat_string, ascii_string, done;
// Fetch the instance type of the receiver into result register.
......@@ -2750,7 +2761,9 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
__ PushSafepointRegisters();
__ push(string);
// Push the index as a smi.
// Push the index as a smi. This is safe because of the checks in
// DoStringCharCodeAt above.
STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
if (instr->index()->IsConstantOperand()) {
int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
__ push(Immediate(Smi::FromInt(const_index)));
......
......@@ -153,6 +153,17 @@ TestStringType(Slice16End, true);
TestStringType(Flat16, true);
TestStringType(NotAString16, true);
function ConsNotSmiIndex() {
var str = Cons();
assertTrue(isNaN(str.charCodeAt(0x7fffffff)));
}
for (var i = 0; i < 100000; i++) {
ConsNotSmiIndex();
}
for (var i = 0; i != 10; i++) {
assertEquals(101, Cons16().charCodeAt(1.1));
assertEquals('e', Cons16().charAt(1.1));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment