Handle BigInt type in CreateListFromArrayLike method

Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
This commit is contained in:
HyukWoo Park 2021-09-01 15:25:18 +09:00 committed by Patrick Kim
commit 81bae461df
4 changed files with 42 additions and 28 deletions

View file

@ -1408,48 +1408,61 @@ ArrayObject* Object::createArrayFromList(ExecutionState& state, const ValueVecto
ValueVector Object::createListFromArrayLike(ExecutionState& state, Value obj, uint8_t elementTypes)
{
// https://www.ecma-international.org/ecma-262/6.0/#sec-createlistfromarraylike
// https://tc39.es/ecma262/#sec-createlistfromarraylike
auto strings = &state.context()->staticStrings();
// 1. ReturnIfAbrupt(obj).
// 2. If elementTypes was not passed, let elementTypes be (Undefined, Null, Boolean, String, Symbol, Number, Object).
// 3. If Type(obj) is not Object, throw a TypeError exception.
// If elementTypes is not present, set elementTypes to « Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ».
// If Type(obj) is not Object, throw a TypeError exception.
if (!obj.isObject()) {
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, strings->object.string(), false, String::emptyString, "%s: obj is not Object");
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, ErrorObject::Messages::GlobalObject_FirstArgumentNotObject);
}
// 4. Let len be ToLength(Get(obj, "length")).
// 5. ReturnIfAbrupt(len).
// Let len be ? LengthOfArrayLike(obj).
Object* o = obj.asObject();
auto len = o->length(state);
// Honorate "length" property: If length>2^32-1, throw a RangeError exception.
if (len > ((1LL << 32LL) - 1LL)) {
ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, ErrorObject::Messages::GlobalObject_InvalidArrayLength);
}
// 6. Let list be an empty List.
// Let list be an empty List.
// Let index be 0.
ValueVector list;
// 7. Let index be 0.
uint64_t index = 0;
//8. Repeat while index < len
bool allTypes = (elementTypes == static_cast<uint8_t>(ElementTypes::ALL));
// Repeat while index < len
while (index < len) {
// b. Let next be Get(obj, indexName).
// c. ReturnIfAbrupt(next).
// Let next be Get(obj, indexName).
Value next = o->getIndexedProperty(state, Value(index)).value(state, o);
// d. If Type(next) is not an element of elementTypes, throw a TypeError exception.
if (!(((elementTypes & (uint8_t)ElementTypes::Undefined) && next.isUndefined()) || ((elementTypes & (uint8_t)ElementTypes::Null) && next.isNull()) || ((elementTypes & (uint8_t)ElementTypes::Boolean) && next.isBoolean()) || ((elementTypes & (uint8_t)ElementTypes::String) && next.isString()) || ((elementTypes & (uint8_t)ElementTypes::Symbol) && next.isSymbol()) || ((elementTypes & (uint8_t)ElementTypes::Number) && next.isNumber()) || ((elementTypes & (uint8_t)ElementTypes::Object) && next.isObject()))) {
// If Type(next) is not an element of elementTypes, throw a TypeError exception.
bool validType = false;
if (next.isUndefined()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Undefined));
} else if (next.isNull()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Null));
} else if (next.isBoolean()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Boolean));
} else if (next.isString()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::String));
} else if (next.isSymbol()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Symbol));
} else if (next.isNumber()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Number));
} else if (next.isBigInt()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::BigInt));
} else if (next.isObject()) {
validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Object));
}
if (UNLIKELY(!validType)) {
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, strings->object.string(), false, String::emptyString, "%s: Type(next) is not an element of elementTypes");
}
// e. Append next as the last element of list.
// Append next as the last element of list.
list.pushBack(next);
// f. Set index to index + 1.
// Set index to index + 1.
index++;
}
// 9. Return list.
// Return list.
return list;
}

View file

@ -757,8 +757,9 @@ enum class ElementTypes : uint8_t {
String = 1 << 3,
Symbol = 1 << 4,
Number = 1 << 5,
Object = 1 << 6,
ALL = Undefined | Null | Boolean | String | Symbol | Number | Object
BigInt = 1 << 6,
Object = 1 << 7,
ALL = Undefined | Null | Boolean | String | Symbol | Number | BigInt | Object
};
class Object : public PointerValue {
@ -1080,7 +1081,7 @@ public:
static void throwCannotDeleteError(ExecutionState& state, const ObjectStructurePropertyName& P);
static ArrayObject* createArrayFromList(ExecutionState& state, const uint64_t& size, const Value* buffer);
static ArrayObject* createArrayFromList(ExecutionState& state, const ValueVector& elements);
static ValueVector createListFromArrayLike(ExecutionState& state, Value obj, uint8_t types = (uint8_t)ElementTypes::ALL);
static ValueVector createListFromArrayLike(ExecutionState& state, Value obj, uint8_t types = static_cast<uint8_t>(ElementTypes::ALL));
static ValueVectorWithInlineStorage enumerableOwnProperties(ExecutionState& state, Object* object, EnumerableOwnPropertiesType kind);
// this function differ with defineOwnProperty.

View file

@ -503,7 +503,7 @@ Object::OwnPropertyKeyVector ProxyObject::ownPropertyKeys(ExecutionState& state)
Value trapResultArray;
Value arguments[] = { target };
trapResultArray = Object::call(state, trap, handler, 1, arguments);
auto trapResult = Object::createListFromArrayLike(state, trapResultArray, ((uint8_t)ElementTypes::String | (uint8_t)ElementTypes::Symbol));
auto trapResult = Object::createListFromArrayLike(state, trapResultArray, (static_cast<uint8_t>(ElementTypes::String) | static_cast<uint8_t>(ElementTypes::Symbol)));
// If trapResult contains any duplicate entries, throw a TypeError exception
for (size_t i = 0; i < trapResult.size(); i++) {

@ -1 +1 @@
Subproject commit 23fe4b0aeaa9f4f4025b90f05abb22bbca2ab45b
Subproject commit f9f1a66e2a4f40fd61cbd76430fa56e068c39172