зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1024587 - IonMonkey: Implement CharCodeAt Recover Instruction. r=nbp,evilpie
This commit is contained in:
Родитель
191d059f87
Коммит
e61e270893
|
@ -329,7 +329,16 @@ function rround_double(i) {
|
|||
if (uceFault_round_double(i) || uceFault_round_double(i))
|
||||
assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
var uceFault_Char_Code_At = eval(uneval(uceFault).replace('uceFault', 'uceFault_Char_Code_At'));
|
||||
function rcharCodeAt(i) {
|
||||
var s = "aaaaa";
|
||||
var x = s.charCodeAt(i % 4);
|
||||
if (uceFault_Char_Code_At(i) || uceFault_Char_Code_At(i))
|
||||
assertEq(x, 97 );
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_from_char_code = eval(uneval(uceFault).replace('uceFault', 'uceFault_from_char_code'));
|
||||
function rfrom_char_code(i) {
|
||||
|
@ -420,6 +429,7 @@ for (i = 0; i < 100; i++) {
|
|||
rfloor_object(i);
|
||||
rround_number(i);
|
||||
rround_double(i);
|
||||
rcharCodeAt(i);
|
||||
rfrom_char_code(i);
|
||||
rfrom_char_code_non_ascii(i);
|
||||
rpow_number(i);
|
||||
|
|
|
@ -4806,6 +4806,11 @@ class MCharCodeAt
|
|||
}
|
||||
|
||||
void computeRange(TempAllocator &alloc);
|
||||
|
||||
bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
bool canRecoverOnBailout() const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class MFromCharCode
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "jscntxt.h"
|
||||
#include "jsmath.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
#include "builtin/TypedObject.h"
|
||||
|
||||
|
@ -557,6 +558,31 @@ RRound::recover(JSContext *cx, SnapshotIterator &iter) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MCharCodeAt::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
MOZ_ASSERT(canRecoverOnBailout());
|
||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_CharCodeAt));
|
||||
return true;
|
||||
}
|
||||
|
||||
RCharCodeAt::RCharCodeAt(CompactBufferReader &reader)
|
||||
{}
|
||||
|
||||
bool
|
||||
RCharCodeAt::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
{
|
||||
RootedString lhs(cx, iter.read().toString());
|
||||
RootedValue rhs(cx, iter.read());
|
||||
RootedValue result(cx);
|
||||
|
||||
if (!js::str_charCodeAt_impl(cx, lhs, rhs, &result))
|
||||
return false;
|
||||
|
||||
iter.storeInstructionResult(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MFromCharCode::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace jit {
|
|||
_(Concat) \
|
||||
_(Floor) \
|
||||
_(Round) \
|
||||
_(CharCodeAt) \
|
||||
_(FromCharCode) \
|
||||
_(Pow) \
|
||||
_(PowHalf) \
|
||||
|
@ -297,6 +298,18 @@ class RRound MOZ_FINAL : public RInstruction
|
|||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RCharCodeAt MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
RINSTRUCTION_HEADER_(CharCodeAt)
|
||||
|
||||
virtual uint32_t numOperands() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RFromCharCode MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1008,41 +1008,54 @@ js_str_charAt(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::str_charCodeAt_impl(JSContext *cx, HandleString string, HandleValue index, MutableHandleValue res)
|
||||
{
|
||||
RootedString str(cx);
|
||||
size_t i;
|
||||
if (index.isInt32()) {
|
||||
i = index.toInt32();
|
||||
if (i >= string->length())
|
||||
goto out_of_range;
|
||||
} else {
|
||||
double d = 0.0;
|
||||
if (!ToInteger(cx, index, &d))
|
||||
return false;
|
||||
// check whether d is negative as size_t is unsigned
|
||||
if (d < 0 || string->length() <= d )
|
||||
goto out_of_range;
|
||||
i = size_t(d);
|
||||
}
|
||||
jschar c;
|
||||
if (!string->getChar(cx, i , &c))
|
||||
return false;
|
||||
res.setInt32(c);
|
||||
return true;
|
||||
|
||||
out_of_range:
|
||||
res.setNaN();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js_str_charCodeAt(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
RootedString str(cx);
|
||||
size_t i;
|
||||
if (args.thisv().isString() && args.length() != 0 && args[0].isInt32()) {
|
||||
RootedValue index(cx);
|
||||
if (args.thisv().isString()) {
|
||||
str = args.thisv().toString();
|
||||
i = size_t(args[0].toInt32());
|
||||
if (i >= str->length())
|
||||
goto out_of_range;
|
||||
} else {
|
||||
str = ThisToStringForStringProto(cx, args);
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
double d = 0.0;
|
||||
if (args.length() > 0 && !ToInteger(cx, args[0], &d))
|
||||
return false;
|
||||
|
||||
if (d < 0 || str->length() <= d)
|
||||
goto out_of_range;
|
||||
i = size_t(d);
|
||||
}
|
||||
if (args.length() != 0)
|
||||
index = args[0];
|
||||
else
|
||||
index.setInt32(0);
|
||||
|
||||
jschar c;
|
||||
if (!str->getChar(cx, i, &c))
|
||||
return false;
|
||||
args.rval().setInt32(c);
|
||||
return true;
|
||||
|
||||
out_of_range:
|
||||
args.rval().setNaN();
|
||||
return true;
|
||||
return js::str_charCodeAt_impl(cx, str, index, args.rval());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -326,9 +326,15 @@ js_str_toString(JSContext *cx, unsigned argc, js::Value *vp);
|
|||
extern bool
|
||||
js_str_charAt(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
namespace js {
|
||||
|
||||
extern bool
|
||||
str_charCodeAt_impl(JSContext *cx, HandleString string, HandleValue index, MutableHandleValue res);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern bool
|
||||
js_str_charCodeAt(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
/*
|
||||
* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
|
||||
* least 6 bytes long. Return the number of UTF-8 bytes of data written.
|
||||
|
|
Загрузка…
Ссылка в новой задаче