mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1016379 - Implement charAt, charCodeAt, str[index] for Latin1 strings. r=luke
This commit is contained in:
parent
2929deb6c1
commit
d1f1ef3fa6
47
js/src/jit-test/tests/basic/latin1-indexing.js
Normal file
47
js/src/jit-test/tests/basic/latin1-indexing.js
Normal file
@ -0,0 +1,47 @@
|
||||
function testCharCodeAt() {
|
||||
var s = toLatin1("abcdefghijklm1234567891000");
|
||||
for (var i=0; i<10; i++)
|
||||
assertEq(s.charCodeAt(i), 97 + i);
|
||||
|
||||
var rope = s + toLatin1("blah");
|
||||
assertEq(rope.charCodeAt(s.length + 3), 104);
|
||||
|
||||
rope = s + "Foo987";
|
||||
assertEq(rope.charCodeAt(s.length + 4), 56);
|
||||
|
||||
rope = "twoByte\u0580" + s;
|
||||
assertEq(rope.charCodeAt(7), 0x580);
|
||||
assertEq(rope.charCodeAt(14), 103);
|
||||
}
|
||||
testCharCodeAt();
|
||||
|
||||
function testCharAt() {
|
||||
var s = toLatin1("abcdefghijklm100000002345");
|
||||
assertEq(s.charAt(0), "a");
|
||||
assertEq(s.charAt(s.length-1), "5");
|
||||
assertEq(s.charAt(s.length), "");
|
||||
|
||||
var rope = s + toLatin1("abcZYX");
|
||||
assertEq(rope.charAt(s.length + 3), "Z");
|
||||
|
||||
rope = s + "Foo987";
|
||||
assertEq(rope.charAt(s.length + 4), "8");
|
||||
|
||||
rope = "twoByte\u0580" + s;
|
||||
assertEq(rope.charAt(7), "\u0580");
|
||||
assertEq(rope.charAt(14), "g");
|
||||
}
|
||||
testCharAt();
|
||||
|
||||
function testIndex(s) {
|
||||
assertEq(s[0], "a");
|
||||
assertEq(s[s.length-1], "6");
|
||||
|
||||
rope = "twoByte\u0512" + s
|
||||
assertEq(rope[7], "\u0512");
|
||||
}
|
||||
|
||||
var s = toLatin1("abcdefghijklm123456");
|
||||
testIndex(s);
|
||||
testIndex(s);
|
||||
testIndex(s);
|
@ -4425,8 +4425,7 @@ ICGetElem_String::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
key, &failure);
|
||||
|
||||
// Get char code.
|
||||
masm.loadStringChars(str, scratchReg);
|
||||
masm.load16ZeroExtend(BaseIndex(scratchReg, key, TimesTwo, 0), scratchReg);
|
||||
masm.loadStringChar(str, key, scratchReg);
|
||||
|
||||
// Check if char code >= UNIT_STATIC_LIMIT.
|
||||
masm.branch32(Assembler::AboveOrEqual, scratchReg, Imm32(StaticStrings::UNIT_STATIC_LIMIT),
|
||||
|
@ -5487,9 +5487,7 @@ CodeGenerator::visitCharCodeAt(LCharCodeAt *lir)
|
||||
return false;
|
||||
|
||||
masm.branchIfRope(str, ool->entry());
|
||||
|
||||
masm.loadStringChars(str, output);
|
||||
masm.load16ZeroExtend(BaseIndex(output, index, TimesTwo, 0), output);
|
||||
masm.loadStringChar(str, index, output);
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
|
@ -881,6 +881,26 @@ MacroAssembler::loadStringChars(Register str, Register dest)
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::loadStringChar(Register str, Register index, Register output)
|
||||
{
|
||||
MOZ_ASSERT(str != output);
|
||||
MOZ_ASSERT(index != output);
|
||||
|
||||
loadStringChars(str, output);
|
||||
|
||||
Label isLatin1, done;
|
||||
branchTest32(Assembler::NonZero, Address(str, JSString::offsetOfFlags()),
|
||||
Imm32(JSString::LATIN1_CHARS_BIT), &isLatin1);
|
||||
load16ZeroExtend(BaseIndex(output, index, TimesTwo), output);
|
||||
jump(&done);
|
||||
|
||||
bind(&isLatin1);
|
||||
load8ZeroExtend(BaseIndex(output, index, TimesOne), output);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::checkInterruptFlagPar(Register tempReg, Label *fail)
|
||||
{
|
||||
|
@ -381,6 +381,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
}
|
||||
|
||||
void loadStringChars(Register str, Register dest);
|
||||
void loadStringChar(Register str, Register index, Register output);
|
||||
|
||||
void branchIfRope(Register str, Label *label) {
|
||||
Address flags(str, JSString::offsetOfFlags());
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/Rooting.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
class JSDependentString;
|
||||
@ -637,6 +638,13 @@ class JSLinearString : public JSString
|
||||
return JS::TwoByteChars(chars(), length());
|
||||
}
|
||||
|
||||
jschar latin1OrTwoByteChar(size_t index) const {
|
||||
MOZ_ASSERT(JSString::isLinear());
|
||||
MOZ_ASSERT(index < length());
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
return hasLatin1Chars() ? latin1Chars(nogc)[index] : twoByteChars(nogc)[index];
|
||||
}
|
||||
|
||||
/* Temporary, unsafe helper function for bug 998392. Don't use for anything else. */
|
||||
void debugUnsafeConvertToLatin1();
|
||||
};
|
||||
@ -1157,23 +1165,23 @@ JSString::getChar(js::ExclusiveContext *cx, size_t index, jschar *code)
|
||||
* test.charCodeAt(x + 1)
|
||||
* }
|
||||
*/
|
||||
const jschar *chars;
|
||||
JSString *str;
|
||||
if (isRope()) {
|
||||
JSRope *rope = &asRope();
|
||||
if (uint32_t(index) < rope->leftChild()->length()) {
|
||||
chars = rope->leftChild()->getChars(cx);
|
||||
str = rope->leftChild();
|
||||
} else {
|
||||
chars = rope->rightChild()->getChars(cx);
|
||||
str = rope->rightChild();
|
||||
index -= rope->leftChild()->length();
|
||||
}
|
||||
} else {
|
||||
chars = getChars(cx);
|
||||
str = this;
|
||||
}
|
||||
|
||||
if (!chars)
|
||||
if (!str->ensureLinear(cx))
|
||||
return false;
|
||||
|
||||
*code = chars[index];
|
||||
*code = str->asLinear().latin1OrTwoByteChar(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user