[runtime] Add fast-paths for common conversion methods
Add inlineable fast-paths for Object::ToPropertyKey, Object::ToLength and Object::ToIndex for the most common argument types. BUG= Review-Url: https://codereview.chromium.org/2587013002 Cr-Commit-Position: refs/heads/master@{#41839}
This commit is contained in:
parent
44b70cb744
commit
d173807b9d
@ -1101,6 +1101,13 @@ MaybeHandle<Name> Object::ToName(Isolate* isolate, Handle<Object> input) {
|
|||||||
return ConvertToName(isolate, input);
|
return ConvertToName(isolate, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
MaybeHandle<Object> Object::ToPropertyKey(Isolate* isolate,
|
||||||
|
Handle<Object> value) {
|
||||||
|
if (value->IsSmi() || HeapObject::cast(*value)->IsName()) return value;
|
||||||
|
return ConvertToPropertyKey(isolate, value);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
MaybeHandle<Object> Object::ToPrimitive(Handle<Object> input,
|
MaybeHandle<Object> Object::ToPrimitive(Handle<Object> input,
|
||||||
ToPrimitiveHint hint) {
|
ToPrimitiveHint hint) {
|
||||||
@ -1138,6 +1145,22 @@ MaybeHandle<String> Object::ToString(Isolate* isolate, Handle<Object> input) {
|
|||||||
return ConvertToString(isolate, input);
|
return ConvertToString(isolate, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
MaybeHandle<Object> Object::ToLength(Isolate* isolate, Handle<Object> input) {
|
||||||
|
if (input->IsSmi()) {
|
||||||
|
int value = std::max(Smi::cast(*input)->value(), 0);
|
||||||
|
return handle(Smi::FromInt(value), isolate);
|
||||||
|
}
|
||||||
|
return ConvertToLength(isolate, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
MaybeHandle<Object> Object::ToIndex(Isolate* isolate, Handle<Object> input,
|
||||||
|
MessageTemplate::Template error_index) {
|
||||||
|
if (input->IsSmi() && Smi::cast(*input)->value() >= 0) return input;
|
||||||
|
return ConvertToIndex(isolate, input, error_index);
|
||||||
|
}
|
||||||
|
|
||||||
bool Object::HasSpecificClassOf(String* name) {
|
bool Object::HasSpecificClassOf(String* name) {
|
||||||
return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
|
return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
|
||||||
}
|
}
|
||||||
|
@ -203,6 +203,31 @@ MaybeHandle<Name> Object::ConvertToName(Isolate* isolate,
|
|||||||
return ToString(isolate, input);
|
return ToString(isolate, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ES6 7.1.14
|
||||||
|
// static
|
||||||
|
MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate,
|
||||||
|
Handle<Object> value) {
|
||||||
|
// 1. Let key be ToPrimitive(argument, hint String).
|
||||||
|
MaybeHandle<Object> maybe_key =
|
||||||
|
Object::ToPrimitive(value, ToPrimitiveHint::kString);
|
||||||
|
// 2. ReturnIfAbrupt(key).
|
||||||
|
Handle<Object> key;
|
||||||
|
if (!maybe_key.ToHandle(&key)) return key;
|
||||||
|
// 3. If Type(key) is Symbol, then return key.
|
||||||
|
if (key->IsSymbol()) return key;
|
||||||
|
// 4. Return ToString(key).
|
||||||
|
// Extending spec'ed behavior, we'd be happy to return an element index.
|
||||||
|
if (key->IsSmi()) return key;
|
||||||
|
if (key->IsHeapNumber()) {
|
||||||
|
uint32_t uint_value;
|
||||||
|
if (value->ToArrayLength(&uint_value) &&
|
||||||
|
uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
|
||||||
|
return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object::ToString(isolate, key);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
|
MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
|
||||||
Handle<Object> input) {
|
Handle<Object> input) {
|
||||||
@ -383,11 +408,16 @@ Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
MaybeHandle<Object> Object::ToLength(Isolate* isolate, Handle<Object> input) {
|
MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate,
|
||||||
|
Handle<Object> input) {
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
|
ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
|
||||||
|
if (input->IsSmi()) {
|
||||||
|
int value = std::max(Smi::cast(*input)->value(), 0);
|
||||||
|
return handle(Smi::FromInt(value), isolate);
|
||||||
|
}
|
||||||
double len = DoubleToInteger(input->Number());
|
double len = DoubleToInteger(input->Number());
|
||||||
if (len <= 0.0) {
|
if (len <= 0.0) {
|
||||||
len = 0.0;
|
return handle(Smi::kZero, isolate);
|
||||||
} else if (len >= kMaxSafeInteger) {
|
} else if (len >= kMaxSafeInteger) {
|
||||||
len = kMaxSafeInteger;
|
len = kMaxSafeInteger;
|
||||||
}
|
}
|
||||||
@ -395,10 +425,12 @@ MaybeHandle<Object> Object::ToLength(Isolate* isolate, Handle<Object> input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
MaybeHandle<Object> Object::ToIndex(Isolate* isolate, Handle<Object> input,
|
MaybeHandle<Object> Object::ConvertToIndex(
|
||||||
MessageTemplate::Template error_index) {
|
Isolate* isolate, Handle<Object> input,
|
||||||
if (input->IsUndefined(isolate)) return isolate->factory()->NewNumber(0.0);
|
MessageTemplate::Template error_index) {
|
||||||
|
if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate);
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
|
ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object);
|
||||||
|
if (input->IsSmi() && Smi::cast(*input)->value() >= 0) return input;
|
||||||
double len = DoubleToInteger(input->Number()) + 0.0;
|
double len = DoubleToInteger(input->Number()) + 0.0;
|
||||||
auto js_len = isolate->factory()->NewNumber(len);
|
auto js_len = isolate->factory()->NewNumber(len);
|
||||||
if (len < 0.0 || len > kMaxSafeInteger) {
|
if (len < 0.0 || len > kMaxSafeInteger) {
|
||||||
@ -6493,33 +6525,6 @@ Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
|
|||||||
return DeleteProperty(&it, language_mode);
|
return DeleteProperty(&it, language_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ES6 7.1.14
|
|
||||||
// static
|
|
||||||
MaybeHandle<Object> Object::ToPropertyKey(Isolate* isolate,
|
|
||||||
Handle<Object> value) {
|
|
||||||
// 1. Let key be ToPrimitive(argument, hint String).
|
|
||||||
MaybeHandle<Object> maybe_key =
|
|
||||||
Object::ToPrimitive(value, ToPrimitiveHint::kString);
|
|
||||||
// 2. ReturnIfAbrupt(key).
|
|
||||||
Handle<Object> key;
|
|
||||||
if (!maybe_key.ToHandle(&key)) return key;
|
|
||||||
// 3. If Type(key) is Symbol, then return key.
|
|
||||||
if (key->IsSymbol()) return key;
|
|
||||||
// 4. Return ToString(key).
|
|
||||||
// Extending spec'ed behavior, we'd be happy to return an element index.
|
|
||||||
if (key->IsSmi()) return key;
|
|
||||||
if (key->IsHeapNumber()) {
|
|
||||||
uint32_t uint_value;
|
|
||||||
if (value->ToArrayLength(&uint_value) &&
|
|
||||||
uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) {
|
|
||||||
return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Object::ToString(isolate, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ES6 19.1.2.4
|
// ES6 19.1.2.4
|
||||||
// static
|
// static
|
||||||
Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
|
Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
|
||||||
|
@ -1313,15 +1313,15 @@ class Object {
|
|||||||
Handle<Object> input);
|
Handle<Object> input);
|
||||||
|
|
||||||
// ES6 section 7.1.14 ToPropertyKey
|
// ES6 section 7.1.14 ToPropertyKey
|
||||||
MUST_USE_RESULT static MaybeHandle<Object> ToPropertyKey(
|
MUST_USE_RESULT static inline MaybeHandle<Object> ToPropertyKey(
|
||||||
Isolate* isolate, Handle<Object> value);
|
Isolate* isolate, Handle<Object> value);
|
||||||
|
|
||||||
// ES6 section 7.1.15 ToLength
|
// ES6 section 7.1.15 ToLength
|
||||||
MUST_USE_RESULT static MaybeHandle<Object> ToLength(Isolate* isolate,
|
MUST_USE_RESULT static inline MaybeHandle<Object> ToLength(
|
||||||
Handle<Object> input);
|
Isolate* isolate, Handle<Object> input);
|
||||||
|
|
||||||
// ES6 section 7.1.17 ToIndex
|
// ES6 section 7.1.17 ToIndex
|
||||||
MUST_USE_RESULT static MaybeHandle<Object> ToIndex(
|
MUST_USE_RESULT static inline MaybeHandle<Object> ToIndex(
|
||||||
Isolate* isolate, Handle<Object> input,
|
Isolate* isolate, Handle<Object> input,
|
||||||
MessageTemplate::Template error_index);
|
MessageTemplate::Template error_index);
|
||||||
|
|
||||||
@ -1556,6 +1556,8 @@ class Object {
|
|||||||
|
|
||||||
MUST_USE_RESULT static MaybeHandle<Name> ConvertToName(Isolate* isolate,
|
MUST_USE_RESULT static MaybeHandle<Name> ConvertToName(Isolate* isolate,
|
||||||
Handle<Object> input);
|
Handle<Object> input);
|
||||||
|
MUST_USE_RESULT static MaybeHandle<Object> ConvertToPropertyKey(
|
||||||
|
Isolate* isolate, Handle<Object> value);
|
||||||
MUST_USE_RESULT static MaybeHandle<String> ConvertToString(
|
MUST_USE_RESULT static MaybeHandle<String> ConvertToString(
|
||||||
Isolate* isolate, Handle<Object> input);
|
Isolate* isolate, Handle<Object> input);
|
||||||
MUST_USE_RESULT static MaybeHandle<Object> ConvertToNumber(
|
MUST_USE_RESULT static MaybeHandle<Object> ConvertToNumber(
|
||||||
@ -1566,6 +1568,12 @@ class Object {
|
|||||||
Isolate* isolate, Handle<Object> input);
|
Isolate* isolate, Handle<Object> input);
|
||||||
MUST_USE_RESULT static MaybeHandle<Object> ConvertToUint32(
|
MUST_USE_RESULT static MaybeHandle<Object> ConvertToUint32(
|
||||||
Isolate* isolate, Handle<Object> input);
|
Isolate* isolate, Handle<Object> input);
|
||||||
|
MUST_USE_RESULT static MaybeHandle<Object> ConvertToLength(
|
||||||
|
Isolate* isolate, Handle<Object> input);
|
||||||
|
MUST_USE_RESULT static MaybeHandle<Object> ConvertToIndex(
|
||||||
|
Isolate* isolate, Handle<Object> input,
|
||||||
|
MessageTemplate::Template error_index);
|
||||||
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,8 +174,7 @@ MaybeHandle<Object> RegExpUtils::SetAdvancedStringIndex(
|
|||||||
|
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj,
|
ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj,
|
||||||
Object::ToLength(isolate, last_index_obj), Object);
|
Object::ToLength(isolate, last_index_obj), Object);
|
||||||
|
const int last_index = PositiveNumberToUint32(*last_index_obj);
|
||||||
const int last_index = Handle<Smi>::cast(last_index_obj)->value();
|
|
||||||
const int new_last_index =
|
const int new_last_index =
|
||||||
AdvanceStringIndex(isolate, string, last_index, unicode);
|
AdvanceStringIndex(isolate, string, last_index, unicode);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user