mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 12:10:47 +00:00
!9598 [ets_runtime] Realise the FastCreateDataProperty for Array.from
Merge pull request !9598 from xingshunxiang/addFastCreateDataProperty
This commit is contained in:
commit
0d6411ecca
@ -259,7 +259,7 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv)
|
||||
} else {
|
||||
mapValue.Update(kValue.GetTaggedValue());
|
||||
}
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapValue);
|
||||
JSArray::TryFastCreateDataProperty(thread, newArrayHandle, k, mapValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
len = ArrayHelper::GetArrayLength(thread, arrayLike);
|
||||
@ -308,8 +308,11 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv)
|
||||
// ix. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue).
|
||||
// x. If defineStatus is an abrupt completion, return IteratorClose(iterator, defineStatus).
|
||||
// xi. Increase k by 1.
|
||||
JSHandle<JSTaggedValue> defineStatus(
|
||||
thread, JSTaggedValue(JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, key, mapValue)));
|
||||
bool createRes = newArrayHandle->IsJSArray() ?
|
||||
JSArray::TryFastCreateDataProperty(thread, newArrayHandle, k, mapValue) :
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, key, mapValue);
|
||||
|
||||
JSHandle<JSTaggedValue> defineStatus(thread, JSTaggedValue(createRes));
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread,
|
||||
JSIterator::IteratorClose(thread, iterator, defineStatus).GetTaggedValue());
|
||||
k++;
|
||||
@ -373,7 +376,7 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv)
|
||||
} else {
|
||||
mapValue.Update(kValue.GetTaggedValue());
|
||||
}
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapValue);
|
||||
JSArray::TryFastCreateDataProperty(thread, newArrayHandle, k, mapValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
thread->CheckSafepointIfSuspended();
|
||||
|
@ -475,6 +475,41 @@ bool JSArray::FastSetPropertyByValue(JSThread *thread, const JSHandle<JSTaggedVa
|
||||
value.GetTaggedValue());
|
||||
}
|
||||
|
||||
bool JSArray::TryFastCreateDataProperty(JSThread *thread, const JSHandle<JSObject> &obj, uint32_t index,
|
||||
const JSHandle<JSTaggedValue> &value, SCheckMode sCheckMode)
|
||||
{
|
||||
JSHandle<JSTaggedValue> objVal(obj);
|
||||
if (!objVal->IsStableJSArray(thread)) {
|
||||
// if JSArray is DictionaryMode goto slowPath
|
||||
return JSObject::CreateDataPropertyOrThrow(thread, obj, index, value, sCheckMode);
|
||||
}
|
||||
|
||||
uint32_t capacity = TaggedArray::Cast(obj->GetElements())->GetLength();
|
||||
ElementsKind kind = obj->GetJSHClass()->GetElementsKind();
|
||||
uint32_t len = JSHandle<JSArray>::Cast(obj)->GetArrayLength();
|
||||
if (index > len || kind != ElementsKind::HOLE_TAGGED) {
|
||||
// goto slowPath
|
||||
return JSObject::CreateDataPropertyOrThrow(thread, obj, index, value, sCheckMode);
|
||||
}
|
||||
|
||||
if (index == len) {
|
||||
// append situation
|
||||
if (!IsArrayLengthWritable(thread, obj)) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "UnWritable ArrayLength", false);
|
||||
}
|
||||
|
||||
uint32_t newLen = index + 1;
|
||||
if (newLen > capacity) {
|
||||
// needs to expand the capacity
|
||||
return JSObject::CreateDataPropertyOrThrow(thread, obj, index, value, sCheckMode);
|
||||
}
|
||||
JSHandle<JSArray>::Cast(obj)->SetArrayLength(thread, newLen);
|
||||
}
|
||||
|
||||
TaggedArray::Cast(obj->GetElements())->Set(thread, index, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ecma2024 23.1.3.20 Array.prototype.sort(comparefn)
|
||||
JSTaggedValue JSArray::Sort(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &fn)
|
||||
{
|
||||
|
@ -104,6 +104,10 @@ public:
|
||||
static bool FastSetPropertyByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value);
|
||||
|
||||
static bool TryFastCreateDataProperty(JSThread *thread, const JSHandle<JSObject> &obj, uint32_t index,
|
||||
const JSHandle<JSTaggedValue> &value,
|
||||
SCheckMode sCheckMode = SCheckMode::CHECK);
|
||||
|
||||
static JSTaggedValue Sort(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &fn);
|
||||
static bool IncludeInSortedValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
|
@ -1176,7 +1176,7 @@ JSTaggedValue ObjectFastOperator::AddPropertyByIndex(JSThread *thread, JSTaggedV
|
||||
INTERPRETER_TRACE(thread, AddPropertyByIndex);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// fixme(hzzhouzebin) this makes SharedArray's frozen no sense.
|
||||
if (UNLIKELY(!JSObject::Cast(receiver)->IsExtensible()) && !receiver.IsJSSharedArray()) {
|
||||
if (UNLIKELY(!JSObject::Cast(receiver)->IsExtensible()) && !receiver.IsJSSharedArray()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(SetPropertyWhenNotExtensible),
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
|
@ -53,6 +53,6 @@ print(cpu.add(b));
|
||||
//this is a case from a fuzz test
|
||||
let v0 = 2 >= 1;
|
||||
let v1 = "hello"
|
||||
let v2 = v1.substring(1, v1);
|
||||
let v2 = v1.substring(v0, v1);
|
||||
print(v2)
|
||||
|
||||
|
@ -203,3 +203,179 @@ print(Array.from(v1.keys()))
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
// array.from by arrayLike with mapFunc
|
||||
{
|
||||
let res = Array.from({length : 3}, () => {});
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let res = Array.from({length : 3}, () => ({}));
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let res = Array.from({length : 3}, () => []);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let res = Array.from({length : 3}, () => [1,2,3]);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let res = Array.from({length : 3}, () => 0);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let num = 1;
|
||||
let len = 1025;
|
||||
let res = Array.from({length : len}, () => num);
|
||||
print(res.length == len);
|
||||
let flag = true;
|
||||
for (let i = 0; i < res.length; ++i) {
|
||||
if (res[i] != num) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
print("get JSArray from arrayLike Success");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
function example() {
|
||||
let res = Array.from(arguments);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
example(1, 2, 3);
|
||||
}
|
||||
|
||||
{
|
||||
let arrayLike = {0:1.1, 1:12, 2:'ss', length: 3}
|
||||
let res = Array.from(arrayLike, x => x + x);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let res = Array.from({length : 3}, (_, index) => [index * 2]);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
const nonConstructor = {}
|
||||
let res = Array.from.call(nonConstructor, {length : 3}, (_, index) => [index * 2]);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
//array.from by JSArray
|
||||
{
|
||||
const nonConstructor = {}
|
||||
let num = 1
|
||||
let len = 1025 // may transfer to dictionary elements type
|
||||
let myArray = new Array(1025).fill(num)
|
||||
let res = Array.from.call(nonConstructor, myArray);
|
||||
print(res.length == len);
|
||||
let flag = true;
|
||||
for (let i = 0; i < res.length; ++i) {
|
||||
if (res[i] != num || res.at(i) != num) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
print("get JSArray from JSArray Success!")
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const nonConstructor = {}
|
||||
let myArray = new Array(1,2,3,4,5)
|
||||
let res = Array.from.call(nonConstructor, myArray);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let res = Array.from([1,2,3,4,5]);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
// test for String with mapFunc
|
||||
{
|
||||
let str = 'a'.repeat(10)
|
||||
let res = Array.from(str, x => x + 's');
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let len = 1025
|
||||
const head = 'h'
|
||||
const tail = '_tail'
|
||||
let str = head.repeat(len)
|
||||
let res = Array.from(str, x => x + tail);
|
||||
let flag = true;
|
||||
for (let i = 0; i < res.length; ++i) {
|
||||
if (res[i] != head + tail) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (res.length == len && flag) {
|
||||
print("result check successfully");
|
||||
} else {
|
||||
print("result check failed");
|
||||
}
|
||||
}
|
||||
|
||||
// test for Set with mapFunc
|
||||
{
|
||||
let set = new Set(['test', 'for', 'array', 'from', 'set'])
|
||||
let res = Array.from(set, x => x);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
// test for Map with mapFunc
|
||||
{
|
||||
let map = new Map([[1, 'test'], [2, 'for'], [3, 'array'], [4, 'from'], [5, 'map']]);
|
||||
let res = Array.from(map, x => x);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
// test for TypedArray with mapFunc
|
||||
{
|
||||
let mapFunc = x => x + x;
|
||||
let uint8Array = new Uint8Array([1, 2, 3, 4, 5, 6]);
|
||||
let res = Array.from(uint8Array, mapFunc);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let mapFunc = x => x + x;
|
||||
let uint16Array = new Uint16Array([1, 2, 3, 4, 5, 6]);
|
||||
let res = Array.from(uint16Array, mapFunc);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let mapFunc = x => x + x;
|
||||
let uint32Array = new Uint32Array([1, 2, 3, 4, 5, 6]);
|
||||
let res = Array.from(uint32Array, mapFunc);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let mapFunc = x => x + x;
|
||||
let float32Array = new Float32Array([1, 2, 3, 4, 5, 6]);
|
||||
let res = Array.from(float32Array, mapFunc);
|
||||
print(JSON.stringify(res));
|
||||
}
|
||||
|
||||
{
|
||||
let mapFunc = x => x + x;
|
||||
let float64Array = new Float64Array([1, 2, 3, 4, 5, 6]);
|
||||
let res = Array.from(float64Array, mapFunc);
|
||||
print(JSON.stringify(res));
|
||||
}
|
@ -87,3 +87,27 @@ get length
|
||||
get length
|
||||
[0,1,2,null,null,null,null,null,null,null]
|
||||
[1,2,3]
|
||||
[null,null,null]
|
||||
[{},{},{}]
|
||||
[[],[],[]]
|
||||
[[1,2,3],[1,2,3],[1,2,3]]
|
||||
[0,0,0]
|
||||
true
|
||||
get JSArray from arrayLike Success
|
||||
[1,2,3]
|
||||
[2.2,24,"ssss"]
|
||||
[[0],[2],[4]]
|
||||
[[0],[2],[4]]
|
||||
true
|
||||
get JSArray from JSArray Success!
|
||||
[1,2,3,4,5]
|
||||
[1,2,3,4,5]
|
||||
["as","as","as","as","as","as","as","as","as","as"]
|
||||
result check successfully
|
||||
["test","for","array","from","set"]
|
||||
[[1,"test"],[2,"for"],[3,"array"],[4,"from"],[5,"map"]]
|
||||
[2,4,6,8,10,12]
|
||||
[2,4,6,8,10,12]
|
||||
[2,4,6,8,10,12]
|
||||
[2,4,6,8,10,12]
|
||||
[2,4,6,8,10,12]
|
||||
|
Loading…
Reference in New Issue
Block a user