mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!4209 Remove Load/StoreElement elementsLength check
Merge pull request !4209 from 孙哲/master
This commit is contained in:
commit
b2d545c02a
@ -219,7 +219,7 @@ DECLARE_BUILTINS(IndexOf)
|
||||
auto env = GetEnvironment();
|
||||
DEFVARIABLE(res, VariableType::JS_ANY(), IntToTaggedPtr(Int32(-1)));
|
||||
DEFVARIABLE(pos, VariableType::INT32(), Int32(0));
|
||||
|
||||
|
||||
Label objNotUndefinedAndNull(env);
|
||||
Label isString(env);
|
||||
Label isSearchString(env);
|
||||
@ -569,7 +569,7 @@ DECLARE_BUILTINS(VectorForEach)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::VECTOR_FOREACH);
|
||||
@ -590,7 +590,7 @@ DECLARE_BUILTINS(VectorReplaceAllElements)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::VECTOR_REPLACEALLELEMENTS);
|
||||
@ -611,7 +611,7 @@ DECLARE_BUILTINS(StackForEach)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::STACK_FOREACH);
|
||||
@ -632,7 +632,7 @@ DECLARE_BUILTINS(PlainArrayForEach)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::PLAINARRAY_FOREACH);
|
||||
@ -653,7 +653,7 @@ DECLARE_BUILTINS(QueueForEach)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.QueueCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::QUEUE_FOREACH);
|
||||
@ -674,7 +674,7 @@ DECLARE_BUILTINS(DequeForEach)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.DequeCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::DEQUE_FOREACH);
|
||||
@ -821,7 +821,7 @@ DECLARE_BUILTINS(ArrayListForEach)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::ARRAYLIST_FOREACH);
|
||||
@ -842,7 +842,7 @@ DECLARE_BUILTINS(ArrayListReplaceAllElements)
|
||||
|
||||
Label exit(env);
|
||||
Label slowPath(env);
|
||||
|
||||
|
||||
ContainersStubBuilder containersBuilder(this);
|
||||
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
|
||||
&slowPath, ContainersType::ARRAYLIST_REPLACEALLELEMENTS);
|
||||
@ -942,7 +942,7 @@ DECLARE_BUILTINS(FunctionPrototypeApply)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bind(&slowPath);
|
||||
{
|
||||
res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget);
|
||||
@ -1157,12 +1157,13 @@ DECLARE_BUILTINS(ArrayConstructor)
|
||||
}
|
||||
Bind(&arrayCreate);
|
||||
{
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetParameters(glue, 0);
|
||||
Label afterNew(env);
|
||||
newBuilder.NewJSObject(&res, &afterNew, intialHClass);
|
||||
Bind(&afterNew);
|
||||
Label lengthValid(env);
|
||||
Branch(Int64GreaterThan(*arrayLength, Int64(JSObject::MAX_GAP)), &slowPath, &lengthValid);
|
||||
Bind(&lengthValid);
|
||||
{
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetParameters(glue, 0);
|
||||
res = newBuilder.NewJSArrayWithSize(intialHClass, *arrayLength);
|
||||
GateRef lengthOffset = IntPtr(JSArray::LENGTH_OFFSET);
|
||||
Store(VariableType::JS_ANY(), glue, *res, lengthOffset, Int64ToTaggedInt(*arrayLength));
|
||||
GateRef accessor = GetGlobalConstantValue(VariableType::JS_ANY(), glue,
|
||||
|
@ -880,21 +880,21 @@ GateRef CircuitBuilder::TypedConditionJump(GateRef x, GateType xType)
|
||||
}
|
||||
|
||||
template <TypedLoadOp Op>
|
||||
GateRef CircuitBuilder::LoadElement(GateRef receiver, GateRef index, GateRef length)
|
||||
GateRef CircuitBuilder::LoadElement(GateRef receiver, GateRef index)
|
||||
{
|
||||
auto opIdx = static_cast<uint64_t>(Op);
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto ret = GetCircuit()->NewGate(GetCircuit()->LoadElement(opIdx), MachineType::I64,
|
||||
{currentControl, currentDepend, receiver, index, length}, GateType::AnyType());
|
||||
{currentControl, currentDepend, receiver, index}, GateType::AnyType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <TypedStoreOp Op>
|
||||
GateRef CircuitBuilder::StoreElement(GateRef receiver, GateRef index, GateRef value, GateRef length)
|
||||
GateRef CircuitBuilder::StoreElement(GateRef receiver, GateRef index, GateRef value)
|
||||
{
|
||||
auto opIdx = static_cast<uint64_t>(Op);
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
@ -902,7 +902,7 @@ GateRef CircuitBuilder::StoreElement(GateRef receiver, GateRef index, GateRef va
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto ret =
|
||||
GetCircuit()->NewGate(GetCircuit()->StoreElement(opIdx), MachineType::NOVALUE,
|
||||
{currentControl, currentDepend, receiver, index, value, length}, GateType::AnyType());
|
||||
{currentControl, currentDepend, receiver, index, value}, GateType::AnyType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
|
@ -501,9 +501,9 @@ public:
|
||||
// middle ir: object operations
|
||||
GateRef ToLength(GateRef receiver);
|
||||
template<TypedLoadOp Op>
|
||||
GateRef LoadElement(GateRef receiver, GateRef index, GateRef length);
|
||||
GateRef LoadElement(GateRef receiver, GateRef index);
|
||||
template<TypedStoreOp Op>
|
||||
GateRef StoreElement(GateRef receiver, GateRef index, GateRef value, GateRef length);
|
||||
GateRef StoreElement(GateRef receiver, GateRef index, GateRef value);
|
||||
GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction);
|
||||
GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value);
|
||||
GateRef LoadArrayLength(GateRef array);
|
||||
|
@ -300,8 +300,8 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
V(HeapAlloc, HEAP_ALLOC, GateFlags::NONE_FLAG, 1, 1, 1) \
|
||||
V(LoadConstOffset, LOAD_CONST_OFFSET, GateFlags::NO_WRITE, 0, 1, 1) \
|
||||
V(StoreConstOffset, STORE_CONST_OFFSET, GateFlags::NONE_FLAG, 1, 1, 2) \
|
||||
V(LoadElement, LOAD_ELEMENT, GateFlags::NO_WRITE, 1, 1, 3) \
|
||||
V(StoreElement, STORE_ELEMENT, GateFlags::NONE_FLAG, 1, 1, 4) \
|
||||
V(LoadElement, LOAD_ELEMENT, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(StoreElement, STORE_ELEMENT, GateFlags::NONE_FLAG, 1, 1, 3) \
|
||||
V(RestoreRegister, RESTORE_REGISTER, GateFlags::NONE_FLAG, 0, 1, 0) \
|
||||
V(Constant, CONSTANT, GateFlags::NONE_FLAG, 0, 0, 0) \
|
||||
V(RelocatableData, RELOCATABLE_DATA, GateFlags::NONE_FLAG, 0, 0, 0) \
|
||||
|
@ -59,6 +59,23 @@ void NewObjectStubBuilder::NewLexicalEnv(Variable *result, Label *exit, GateRef
|
||||
}
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::NewJSArrayWithSize(GateRef hclass, GateRef size)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
Label exit(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
|
||||
GateRef result = NewJSObject(glue_, hclass);
|
||||
DEFVARIABLE(array, VariableType::JS_ANY(), Undefined());
|
||||
NewTaggedArrayChecked(&array, TruncInt64ToInt32(size), &exit);
|
||||
Bind(&exit);
|
||||
auto arrayRet = *array;
|
||||
env->SubCfgExit();
|
||||
SetElementsArray(VariableType::JS_POINTER(), glue_, result, arrayRet);
|
||||
return result;
|
||||
}
|
||||
|
||||
void NewObjectStubBuilder::NewJSObject(Variable *result, Label *exit, GateRef hclass)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
@ -122,6 +139,29 @@ GateRef NewObjectStubBuilder::NewJSObject(GateRef glue, GateRef hclass)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NewObjectStubBuilder::NewTaggedArrayChecked(Variable *result, GateRef len, Label *exit)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
size_ = ComputeTaggedArraySize(ZExtInt32ToPtr(len));
|
||||
Label afterAllocate(env);
|
||||
// Be careful. NO GC is allowed when initization is not complete.
|
||||
AllocateInYoung(result, &afterAllocate);
|
||||
Bind(&afterAllocate);
|
||||
Label noException(env);
|
||||
Branch(TaggedIsException(result->ReadVariable()), exit, &noException);
|
||||
Bind(&noException);
|
||||
{
|
||||
auto hclass = GetGlobalConstantValue(
|
||||
VariableType::JS_POINTER(), glue_, ConstantIndex::ARRAY_CLASS_INDEX);
|
||||
StoreHClass(glue_, result->ReadVariable(), hclass);
|
||||
Label afterInitialize(env);
|
||||
InitializeTaggedArrayWithSpeicalValue(&afterInitialize,
|
||||
result->ReadVariable(), Hole(), Int32(0), len);
|
||||
Bind(&afterInitialize);
|
||||
Jump(exit);
|
||||
}
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::NewTaggedArray(GateRef glue, GateRef len)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
@ -147,29 +187,7 @@ GateRef NewObjectStubBuilder::NewTaggedArray(GateRef glue, GateRef len)
|
||||
Branch(Int32LessThan(len, Int32(MAX_TAGGED_ARRAY_LENGTH)), &next, &slowPath);
|
||||
Bind(&next);
|
||||
{
|
||||
size_ = ComputeTaggedArraySize(ZExtInt32ToPtr(len));
|
||||
Label afterAllocate(env);
|
||||
// Be careful. NO GC is allowed when initization is not complete.
|
||||
AllocateInYoung(&result, &afterAllocate);
|
||||
Bind(&afterAllocate);
|
||||
Label hasPendingException(env);
|
||||
Label noException(env);
|
||||
Branch(TaggedIsException(*result), &hasPendingException, &noException);
|
||||
Bind(&noException);
|
||||
{
|
||||
auto hclass = GetGlobalConstantValue(
|
||||
VariableType::JS_POINTER(), glue_, ConstantIndex::ARRAY_CLASS_INDEX);
|
||||
StoreHClass(glue_, *result, hclass);
|
||||
Label afterInitialize(env);
|
||||
InitializeTaggedArrayWithSpeicalValue(&afterInitialize,
|
||||
*result, Hole(), Int32(0), len);
|
||||
Bind(&afterInitialize);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&hasPendingException);
|
||||
{
|
||||
Jump(&exit);
|
||||
}
|
||||
NewTaggedArrayChecked(&result, len, &exit);
|
||||
}
|
||||
Bind(&slowPath);
|
||||
{
|
||||
|
@ -44,7 +44,9 @@ public:
|
||||
void NewLexicalEnv(Variable *result, Label *exit, GateRef numSlots, GateRef parent);
|
||||
void NewJSObject(Variable *result, Label *exit, GateRef hclass);
|
||||
GateRef NewJSObject(GateRef glue, GateRef hclass);
|
||||
GateRef NewJSArray(GateRef glue, GateRef hclass);
|
||||
GateRef NewTaggedArray(GateRef glue, GateRef len);
|
||||
GateRef NewJSArrayWithSize(GateRef hclass, GateRef size);
|
||||
void NewArgumentsList(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs);
|
||||
void NewArgumentsObj(Variable *result, Label *exit, GateRef argumentsList, GateRef numArgs);
|
||||
void AllocLineStringObject(Variable *result, Label *exit, GateRef length, bool compressed);
|
||||
@ -56,6 +58,7 @@ public:
|
||||
GateRef NewThisObjectChecked(GateRef glue, GateRef ctor);
|
||||
GateRef CreateEmptyArray(GateRef glue);
|
||||
GateRef CreateArrayWithBuffer(GateRef glue, GateRef index, GateRef jsFunc);
|
||||
void NewTaggedArrayChecked(Variable *result, GateRef len, Label *exit);
|
||||
|
||||
private:
|
||||
static constexpr int MAX_TAGGED_ARRAY_LENGTH = 50;
|
||||
|
@ -2471,8 +2471,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
|
||||
Branch(IsJsCOWArray(*holder), &isJsCOWArray, &isNotJsCOWArray);
|
||||
Bind(&isJsCOWArray);
|
||||
{
|
||||
CallRuntime(glue, RTSTUB_ID(CheckAndCopyArray), {*holder});
|
||||
GateRef newElements = GetElementsArray(*holder);
|
||||
GateRef newElements = CallRuntime(glue, RTSTUB_ID(CheckAndCopyArray), {*holder});
|
||||
SetValueToTaggedArray(VariableType::JS_ANY(), glue, newElements, index, value);
|
||||
returnValue = Undefined();
|
||||
Jump(&exit);
|
||||
|
@ -669,7 +669,7 @@ void TSHCRLowering::LowerTypedLdObjByIndex(GateRef gate)
|
||||
|
||||
GateRef result = Circuit::NullGate();
|
||||
if (tsManager_->IsFloat32ArrayType(receiverType)) {
|
||||
result = builder_.LoadElement<TypedLoadOp::FLOAT32ARRAY_LOAD_ELEMENT>(receiver, index, builder_.Undefined());
|
||||
result = builder_.LoadElement<TypedLoadOp::FLOAT32ARRAY_LOAD_ELEMENT>(receiver, index);
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
@ -705,7 +705,7 @@ void TSHCRLowering::LowerTypedStObjByIndex(GateRef gate)
|
||||
builder_.IndexCheck(receiverType, receiver, index);
|
||||
|
||||
if (tsManager_->IsFloat32ArrayType(receiverType)) {
|
||||
builder_.StoreElement<TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(receiver, index, value, builder_.Undefined());
|
||||
builder_.StoreElement<TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(receiver, index, value);
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
@ -741,7 +741,7 @@ void TSHCRLowering::LowerTypedLdObjByValue(GateRef gate, bool isThis)
|
||||
builder_.StableArrayCheck(receiver);
|
||||
GateRef length = builder_.LoadArrayLength(receiver);
|
||||
propKey = builder_.IndexCheck(receiverType, length, propKey);
|
||||
GateRef result = builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_ELEMENT>(receiver, propKey, length);
|
||||
GateRef result = builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_ELEMENT>(receiver, propKey);
|
||||
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result);
|
||||
}
|
||||
@ -763,7 +763,7 @@ void TSHCRLowering::LowerTypedStObjByValue(GateRef gate)
|
||||
builder_.StableArrayCheck(receiver);
|
||||
GateRef length = builder_.LoadArrayLength(receiver);
|
||||
builder_.IndexCheck(receiverType, length, propKey);
|
||||
builder_.StoreElement<TypedStoreOp::ARRAY_STORE_ELEMENT>(receiver, propKey, value, length);
|
||||
builder_.StoreElement<TypedStoreOp::ARRAY_STORE_ELEMENT>(receiver, propKey, value);
|
||||
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
@ -537,23 +537,10 @@ void TypeMCRLowering::LowerArrayLoadElement(GateRef gate)
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef length = acc_.GetValueIn(gate, 2); // length
|
||||
ASSERT(!acc_.IsConstantUndefined(length));
|
||||
GateRef element = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
|
||||
GateRef arrayLength = builder_.GetLengthFromTaggedArray(element);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.UndefineConstant());
|
||||
Label accessValue(&builder_);
|
||||
Label exit(&builder_);
|
||||
GateRef hasEntityValue = builder_.Int32LessThanOrEqual(length, arrayLength);
|
||||
builder_.Branch(hasEntityValue, &accessValue, &exit);
|
||||
builder_.Bind(&accessValue);
|
||||
{
|
||||
result = builder_.GetValueFromTaggedArray(element, index);
|
||||
result = builder_.ConvertHoleAsUndefined(*result);
|
||||
builder_.Jump(&exit);
|
||||
};
|
||||
builder_.Bind(&exit);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
GateRef result = builder_.GetValueFromTaggedArray(element, index);
|
||||
result = builder_.ConvertHoleAsUndefined(result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
// for Float32Array
|
||||
@ -619,15 +606,6 @@ void TypeMCRLowering::LowerArrayStoreElement(GateRef gate, GateRef glue)
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0); // 0: receiver
|
||||
GateRef index = acc_.GetValueIn(gate, 1); // 1: index
|
||||
GateRef value = acc_.GetValueIn(gate, 2); // 2: value
|
||||
GateRef length = acc_.GetValueIn(gate, 3); // 3: length
|
||||
ASSERT(!acc_.IsConstantUndefined(length));
|
||||
GateRef currentDepend = builder_.GetDepend();
|
||||
GateRef element = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
|
||||
GateRef arrayLength = builder_.GetLengthFromTaggedArray(element);
|
||||
GateRef hasEntityValue = builder_.Int32LessThanOrEqual(length, arrayLength);
|
||||
|
||||
GateRef frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
builder_.DeoptCheck(hasEntityValue, frameState, DeoptType::NOTSARRAY);
|
||||
|
||||
Label storeWithCOWArray(&builder_);
|
||||
Label storeDirectly(&builder_);
|
||||
@ -635,13 +613,13 @@ void TypeMCRLowering::LowerArrayStoreElement(GateRef gate, GateRef glue)
|
||||
builder_.Branch(builder_.IsJsCOWArray(receiver), &storeWithCOWArray, &storeDirectly);
|
||||
builder_.Bind(&storeWithCOWArray);
|
||||
{
|
||||
LowerCallRuntime(glue, gate, RTSTUB_ID(CheckAndCopyArray), {receiver}, true);
|
||||
GateRef newElement = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
|
||||
GateRef newElement = LowerCallRuntime(glue, gate, RTSTUB_ID(CheckAndCopyArray), {receiver}, true);
|
||||
builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue, newElement, index, value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&storeDirectly);
|
||||
{
|
||||
GateRef element = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
|
||||
builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue, element, index, value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ JSHandle<JSTaggedValue> JSArray::ArrayCreate(JSThread *thread, JSTaggedNumber le
|
||||
|
||||
// 10. Perform OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Value]]: length, [[Writable]]:
|
||||
// true, [[Enumerable]]: false, [[Configurable]]: false}).
|
||||
JSArray::Cast(*obj)->SetArrayLength(thread, normalArrayLength);
|
||||
JSArray::SetCapacity(thread, obj, 0, normalArrayLength);
|
||||
|
||||
return JSHandle<JSTaggedValue>(obj);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ DEF_RUNTIME_STUBS(CheckAndCopyArray)
|
||||
JSTaggedType argReceiver = GetTArg(argv, argc, 0); // 0: means the zeroth parameter
|
||||
JSHandle<JSArray> receiverHandle(thread, reinterpret_cast<JSArray *>(argReceiver));
|
||||
JSArray::CheckAndCopyArray(thread, receiverHandle);
|
||||
return JSTaggedValue::Hole().GetRawData();
|
||||
return receiverHandle->GetElements().GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(NewEcmaHClass)
|
||||
|
@ -13,3 +13,4 @@
|
||||
|
||||
true
|
||||
true
|
||||
true
|
||||
|
@ -16,18 +16,25 @@
|
||||
declare function print(arg:any):string;
|
||||
|
||||
class A{}
|
||||
let array:A[] = [undefined];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
print(array[i]===undefined);
|
||||
}
|
||||
|
||||
class ParticleSystemCPU {
|
||||
private _arrayTest: number[];
|
||||
|
||||
constructor() {
|
||||
this._arrayTest = new Array(10);
|
||||
print(this._arrayTest[9] === undefined);
|
||||
function testLiteralArray() {
|
||||
let array:A[] = [undefined];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
print(array[i]===undefined);
|
||||
}
|
||||
}
|
||||
|
||||
var system: ParticleSystemCPU[] = [new ParticleSystemCPU()];
|
||||
testLiteralArray();
|
||||
|
||||
function testLargeHolyArray() {
|
||||
let arrayTest = new Array(10000);
|
||||
print(arrayTest[9] === undefined);
|
||||
}
|
||||
|
||||
testLargeHolyArray();
|
||||
|
||||
function testHolyArray() {
|
||||
let arrayTest = new Array(10);
|
||||
print(arrayTest[9] === undefined);
|
||||
}
|
||||
testHolyArray();
|
||||
|
Loading…
Reference in New Issue
Block a user