1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ark_native_object.h"
17
18 #include "ark_headers.h"
19 #include "ark_native_array.h"
20 #include "ark_native_external.h"
21 #include "ark_native_function.h"
22 #include "ark_native_reference.h"
23 #include "ark_native_string.h"
24
25 #include "native_engine/native_property.h"
26
27 #include "utils/log.h"
28
29 using panda::ObjectRef;
30 using panda::StringRef;
31 using panda::NativePointerRef;
32 using panda::ArrayRef;
33 using panda::PropertyAttribute;
34
ArkNativeObject(ArkNativeEngine * engine)35 ArkNativeObject::ArkNativeObject(ArkNativeEngine* engine)
36 : ArkNativeObject(engine, JSValueRef::Undefined(engine->GetEcmaVm()))
37 {
38 auto vm = engine->GetEcmaVm();
39 LocalScope scope(vm);
40 Local<ObjectRef> object = ObjectRef::New(vm);
41 value_ = Global<ObjectRef>(vm, object);
42 }
43
ArkNativeObject(ArkNativeEngine * engine,Local<JSValueRef> value)44 ArkNativeObject::ArkNativeObject(ArkNativeEngine* engine, Local<JSValueRef> value) : ArkNativeValue(engine, value) {}
45
DetachFuncCallback(void * engine,void * object,void * hint,void * detachData)46 void* ArkNativeObject::DetachFuncCallback(void* engine, void* object, void* hint, void* detachData)
47 {
48 if (detachData == nullptr || (engine == nullptr || object ==nullptr)) {
49 HILOG_ERROR("DetachFuncCallback params has nullptr");
50 return nullptr;
51 }
52 DetachCallback detach = reinterpret_cast<DetachCallback>(detachData);
53 void* detachVal = detach(reinterpret_cast<NativeEngine*>(engine), object, hint);
54 return detachVal;
55 }
56
AttachFuncCallback(void * engine,void * buffer,void * hint,void * attachData)57 Local<JSValueRef> ArkNativeObject::AttachFuncCallback(void* engine, void* buffer, void* hint, void* attachData)
58 {
59 panda::EscapeLocalScope scope(reinterpret_cast<ArkNativeEngine*>(engine)->GetEcmaVm());
60 if (attachData == nullptr || (engine == nullptr || buffer ==nullptr)) {
61 HILOG_ERROR("AttachFuncCallback params has nullptr");
62 }
63 AttachCallback attach = reinterpret_cast<AttachCallback>(attachData);
64 NativeValue* attachVal = attach(reinterpret_cast<NativeEngine*>(engine), buffer, hint);
65 Global<JSValueRef> result = *attachVal;
66 return scope.Escape(result.ToLocal(reinterpret_cast<ArkNativeEngine*>(engine)->GetEcmaVm()));
67 }
68
~ArkNativeObject()69 ArkNativeObject::~ArkNativeObject() {}
70
ConvertToNativeBindingObject(void * engine,DetachCallback detachData,AttachCallback attachData,void * object,void * hint)71 bool ArkNativeObject::ConvertToNativeBindingObject(
72 void* engine, DetachCallback detachData, AttachCallback attachData, void *object, void *hint)
73 {
74 if (detachData == nullptr || (attachData == nullptr || object == nullptr)) {
75 HILOG_ERROR("ConvertToNativeBindingObject params has nullptr");
76 return false;
77 }
78 auto vm = reinterpret_cast<ArkNativeEngine*>(engine)->GetEcmaVm();
79 Global<ObjectRef> obj = value_;
80 bool res = obj->Set(vm, reinterpret_cast<void*>(DetachFuncCallback), reinterpret_cast<void*>(AttachFuncCallback));
81 this->SetNativeBindingPointer(
82 engine, object, hint, reinterpret_cast<void *>(detachData), reinterpret_cast<void *>(attachData));
83 return res;
84 }
85
GetInterface(int interfaceId)86 void* ArkNativeObject::GetInterface(int interfaceId)
87 {
88 return (NativeObject::INTERFACE_ID == interfaceId) ? (NativeObject*)this : nullptr;
89 }
90
SetNativePointer(void * pointer,NativeFinalize cb,void * hint,NativeReference ** reference,size_t nativeBindingSize)91 void ArkNativeObject::SetNativePointer(void* pointer, NativeFinalize cb, void* hint,
92 NativeReference** reference, size_t nativeBindingSize)
93 {
94 auto vm = engine_->GetEcmaVm();
95 LocalScope scope(vm);
96 Global<ObjectRef> value = value_;
97
98 Local<StringRef> key = StringRef::GetNapiWrapperString(vm);
99 if (pointer == nullptr && value->Has(vm, key)) {
100 Local<ObjectRef> wrapper = value->Get(vm, key);
101 auto ref = reinterpret_cast<ArkNativeReference*>(wrapper->GetNativePointerField(0));
102 // Try to remove native pointer from ArrayDataList
103 ASSERT(nativeBindingSize == 0);
104 wrapper->SetNativePointerField(0, nullptr, nullptr, nullptr, nativeBindingSize);
105 value->Delete(vm, key);
106 delete ref;
107 } else {
108 Local<ObjectRef> object = ObjectRef::New(vm);
109 ArkNativeReference* ref = nullptr;
110 if (reference != nullptr) {
111 ref = new ArkNativeReference(engine_, this, 1, false, cb, pointer, hint);
112 *reference = ref;
113 } else {
114 ref = new ArkNativeReference(engine_, this, 0, true, cb, pointer, hint);
115 }
116 object->SetNativePointerFieldCount(1);
117 object->SetNativePointerField(0, ref, nullptr, nullptr, nativeBindingSize);
118 PropertyAttribute attr(object, true, false, true);
119 value->DefineProperty(vm, key, attr);
120 }
121 }
122
GetNativePointer()123 void* ArkNativeObject::GetNativePointer()
124 {
125 auto vm = engine_->GetEcmaVm();
126 LocalScope scope(vm);
127 Global<ObjectRef> value = value_;
128 Local<StringRef> key = StringRef::GetNapiWrapperString(vm);
129 Local<JSValueRef> val = value->Get(vm, key);
130 void* result = nullptr;
131 if (val->IsObject()) {
132 Local<ObjectRef> ext(val);
133 auto ref = reinterpret_cast<ArkNativeReference*>(ext->GetNativePointerField(0));
134 result = ref != nullptr ? ref->GetData() : nullptr;
135 }
136 return result;
137 }
138
SetNativeBindingPointer(void * enginePointer,void * objPointer,void * hint,void * detachData,void * attachData)139 void ArkNativeObject::SetNativeBindingPointer(
140 void *enginePointer, void *objPointer, void *hint, void *detachData, void *attachData)
141 {
142 auto vm = engine_->GetEcmaVm();
143 LocalScope scope(vm);
144 Global<ObjectRef> value = value_;
145
146 Local<ObjectRef> object = Local<ObjectRef>(value.ToLocal(vm));
147 object->SetNativePointerFieldCount(5); // 5 : NativeEngine, NativeObject, hint, detachData, attachData
148 object->SetNativePointerField(0, enginePointer, nullptr, nullptr);
149 object->SetNativePointerField(1, objPointer, nullptr, nullptr);
150 object->SetNativePointerField(2, hint, nullptr, nullptr); // 2 : hint
151 object->SetNativePointerField(3, detachData, nullptr, nullptr); // 3 : detachData
152 object->SetNativePointerField(4, attachData, nullptr, nullptr); // 4 : attachData
153 }
154
GetNativeBindingPointer(uint32_t index)155 void* ArkNativeObject::GetNativeBindingPointer(uint32_t index)
156 {
157 auto vm = engine_->GetEcmaVm();
158 LocalScope scope(vm);
159 Global<ObjectRef> value = value_;
160 uint32_t paramCount = static_cast<uint32_t>(value->GetNativePointerFieldCount());
161 if (index >= paramCount) {
162 HILOG_ERROR("index more than nativebindingpointer count");
163 return nullptr;
164 }
165 return value->GetNativePointerField(index);
166 }
167
GetPropertyNames()168 NativeValue* ArkNativeObject::GetPropertyNames()
169 {
170 auto vm = engine_->GetEcmaVm();
171 LocalScope scope(vm);
172 Global<ObjectRef> val = value_;
173 Local<ArrayRef> arrayVal = val->GetOwnPropertyNames(vm);
174 NativeChunk& chunk = engine_->GetNativeChunk();
175 return chunk.New<ArkNativeArray>(engine_, arrayVal);
176 }
177
GetEnumerablePropertyNames()178 NativeValue* ArkNativeObject::GetEnumerablePropertyNames()
179 {
180 auto vm = engine_->GetEcmaVm();
181 LocalScope scope(vm);
182 Global<ObjectRef> val = value_;
183 Local<ArrayRef> arrayVal = val->GetOwnEnumerablePropertyNames(vm);
184 NativeChunk& chunk = engine_->GetNativeChunk();
185 return chunk.New<ArkNativeArray>(engine_, arrayVal);
186 }
187
GetPrototype()188 NativeValue* ArkNativeObject::GetPrototype()
189 {
190 auto vm = engine_->GetEcmaVm();
191 LocalScope scope(vm);
192 Global<ObjectRef> obj = value_;
193 Local<JSValueRef> val = obj->GetPrototype(vm);
194
195 return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
196 }
197
DefineProperty(NativePropertyDescriptor propertyDescriptor)198 bool ArkNativeObject::DefineProperty(NativePropertyDescriptor propertyDescriptor)
199 {
200 auto vm = engine_->GetEcmaVm();
201 LocalScope scope(vm);
202 Global<ObjectRef> obj = value_;
203 bool result = false;
204 Local<StringRef> propertyName = StringRef::NewFromUtf8(vm, propertyDescriptor.utf8name);
205
206 bool writable = (propertyDescriptor.attributes & NATIVE_WRITABLE) != 0;
207 bool enumable = (propertyDescriptor.attributes & NATIVE_ENUMERABLE) != 0;
208 bool configable = (propertyDescriptor.attributes & NATIVE_CONFIGURABLE) != 0;
209
210 NativeScopeManager* scopeManager = engine_->GetScopeManager();
211 if (scopeManager == nullptr) {
212 HILOG_ERROR("scope manager is null");
213 return false;
214 }
215 NativeScope* nativeScope = scopeManager->Open();
216 std::string fullName("");
217 #ifdef ENABLE_HITRACE
218 fullName += GetModuleName();
219 #endif
220 NativeChunk& chunk = engine_->GetNativeChunk();
221 if (propertyDescriptor.getter != nullptr || propertyDescriptor.setter != nullptr) {
222 Local<JSValueRef> localGetter = JSValueRef::Undefined(vm);
223 Local<JSValueRef> localSetter = JSValueRef::Undefined(vm);
224
225 if (propertyDescriptor.getter != nullptr) {
226 fullName += "getter";
227 NativeValue* getter = chunk.New<ArkNativeFunction>(
228 engine_, fullName.c_str(), 0, propertyDescriptor.getter, propertyDescriptor.data);
229 Global<JSValueRef> globalGetter = *getter;
230 localGetter = globalGetter.ToLocal(vm);
231 }
232 if (propertyDescriptor.setter != nullptr) {
233 fullName += "setter";
234 NativeValue* setter = chunk.New<ArkNativeFunction>(
235 engine_, fullName.c_str(), 0, propertyDescriptor.setter, propertyDescriptor.data);
236 Global<JSValueRef> globalSetter = *setter;
237 localSetter = globalSetter.ToLocal(vm);
238 }
239
240 PropertyAttribute attr(JSValueRef::Undefined(engine_->GetEcmaVm()), false, enumable, configable);
241 result = obj->SetAccessorProperty(vm, propertyName, localGetter, localSetter, attr);
242 } else if (propertyDescriptor.method != nullptr) {
243 fullName += propertyDescriptor.utf8name;
244 NativeValue* cb = chunk.New<ArkNativeFunction>(engine_, fullName.c_str(), 0, propertyDescriptor.method,
245 propertyDescriptor.data);
246 Global<JSValueRef> globalCb = *cb;
247 PropertyAttribute attr(globalCb.ToLocal(vm), writable, enumable, configable);
248 result = obj->DefineProperty(vm, propertyName, attr);
249 } else {
250 Global<JSValueRef> value = *(propertyDescriptor.value);
251
252 PropertyAttribute attr(value.ToLocal(vm), writable, enumable, configable);
253 result = obj->DefineProperty(vm, propertyName, attr);
254 }
255 Local<ObjectRef> excep = panda::JSNApi::GetUncaughtException(vm);
256 if (!excep.IsNull()) {
257 HILOG_ERROR("ArkNativeObject::DefineProperty occur Exception");
258 panda::JSNApi::GetAndClearUncaughtException(vm);
259 }
260 scopeManager->Close(nativeScope);
261 return result;
262 }
263
SetProperty(NativeValue * key,NativeValue * value)264 bool ArkNativeObject::SetProperty(NativeValue* key, NativeValue* value)
265 {
266 auto vm = engine_->GetEcmaVm();
267 LocalScope scope(vm);
268 Global<ObjectRef> obj = value_;
269 Global<JSValueRef> k = *key;
270 Global<JSValueRef> val = *value;
271
272 return obj->Set(vm, k.ToLocal(vm), val.ToLocal(vm));
273 }
274
GetProperty(NativeValue * key)275 NativeValue* ArkNativeObject::GetProperty(NativeValue* key)
276 {
277 auto vm = engine_->GetEcmaVm();
278 LocalScope scope(vm);
279 Global<JSValueRef> k = *key;
280 Global<ObjectRef> obj = value_;
281
282 Local<JSValueRef> val = obj->Get(vm, k.ToLocal(vm));
283 return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
284 }
285
HasProperty(NativeValue * key)286 bool ArkNativeObject::HasProperty(NativeValue* key)
287 {
288 auto vm = engine_->GetEcmaVm();
289 LocalScope scope(vm);
290 Global<ObjectRef> obj = value_;
291 Global<JSValueRef> k = *key;
292
293 return obj->Has(vm, k.ToLocal(vm));
294 }
295
DeleteProperty(NativeValue * key)296 bool ArkNativeObject::DeleteProperty(NativeValue* key)
297 {
298 auto vm = engine_->GetEcmaVm();
299 LocalScope scope(vm);
300 Global<JSValueRef> k = *key;
301 Global<ObjectRef> obj = value_;
302
303 return obj->Delete(vm, k.ToLocal(vm));
304 }
305
SetProperty(const char * name,NativeValue * value)306 bool ArkNativeObject::SetProperty(const char* name, NativeValue* value)
307 {
308 auto vm = engine_->GetEcmaVm();
309 LocalScope scope(vm);
310
311 Global<ObjectRef> obj = value_;
312 Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
313 Global<JSValueRef> val = *value;
314
315 return obj->Set(vm, key, val.ToLocal(vm));
316 }
317
GetProperty(const char * name)318 NativeValue* ArkNativeObject::GetProperty(const char* name)
319 {
320 auto vm = engine_->GetEcmaVm();
321 LocalScope scope(vm);
322
323 Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
324 Global<ObjectRef> obj = value_;
325 Local<JSValueRef> val = obj->Get(vm, key);
326 return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
327 }
328
GetOwnProperty(const char * name)329 NativeValue* ArkNativeObject::GetOwnProperty(const char* name)
330 {
331 auto vm = engine_->GetEcmaVm();
332 LocalScope scope(vm);
333
334 Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
335 Global<ObjectRef> obj = value_;
336 PropertyAttribute property;
337 obj->GetOwnProperty(vm, key, property);
338 return ArkNativeEngine::ArkValueToNativeValue(engine_, property.GetValue(vm));
339 }
340
HasProperty(const char * name)341 bool ArkNativeObject::HasProperty(const char* name)
342 {
343 auto vm = engine_->GetEcmaVm();
344 LocalScope scope(vm);
345
346 Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
347 Global<ObjectRef> obj = value_;
348
349 return obj->Has(vm, key);
350 }
351
DeleteProperty(const char * name)352 bool ArkNativeObject::DeleteProperty(const char* name)
353 {
354 auto vm = engine_->GetEcmaVm();
355 LocalScope scope(vm);
356
357 Local<StringRef> key = StringRef::NewFromUtf8(vm, name);
358 Global<ObjectRef> obj = value_;
359
360 return obj->Delete(vm, key);
361 }
362
SetPrivateProperty(const char * name,NativeValue * value)363 bool ArkNativeObject::SetPrivateProperty(const char* name, NativeValue* value)
364 {
365 return false;
366 }
367
GetPrivateProperty(const char * name)368 NativeValue* ArkNativeObject::GetPrivateProperty(const char* name)
369 {
370 return nullptr;
371 }
372
HasPrivateProperty(const char * name)373 bool ArkNativeObject::HasPrivateProperty(const char* name)
374 {
375 return false;
376 }
377
DeletePrivateProperty(const char * name)378 bool ArkNativeObject::DeletePrivateProperty(const char* name)
379 {
380 return false;
381 }
382
GetAllPropertyNames(napi_key_collection_mode keyMode,napi_key_filter keyFilter,napi_key_conversion keyConversion)383 NativeValue* ArkNativeObject::GetAllPropertyNames(
384 napi_key_collection_mode keyMode, napi_key_filter keyFilter, napi_key_conversion keyConversion)
385 {
386 uint32_t filter = NATIVE_DEFAULT;
387 if (keyFilter & napi_key_writable) {
388 filter = static_cast<uint32_t>(filter | NATIVE_WRITABLE);
389 }
390 if (keyFilter & napi_key_enumerable) {
391 filter = static_cast<uint32_t>(filter | NATIVE_ENUMERABLE);
392 }
393 if (keyFilter & napi_key_configurable) {
394 filter = static_cast<uint32_t>(filter | NATIVE_CONFIGURABLE);
395 }
396 if (keyFilter & napi_key_skip_strings) {
397 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_STRINGS);
398 }
399 if (keyFilter & napi_key_skip_symbols) {
400 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_SYMBOLS);
401 }
402
403 switch (keyMode) {
404 case napi_key_include_prototypes:
405 filter = static_cast<uint32_t>(filter | NATIVE_KEY_INCLUDE_PROTOTYPES);
406 break;
407 case napi_key_own_only:
408 filter = static_cast<uint32_t>(filter | NATIVE_KEY_OWN_ONLY);
409 break;
410 default:
411 return nullptr;
412 }
413
414 switch (keyConversion) {
415 case napi_key_keep_numbers:
416 filter = static_cast<uint32_t>(filter | NATIVE_KEY_KEEP_NUMBERS);
417 break;
418 case napi_key_numbers_to_strings:
419 filter = static_cast<uint32_t>(filter | NATIVE_KEY_NUMBERS_TO_STRINGS);
420 break;
421 default:
422 return nullptr;
423 }
424
425 auto vm = engine_->GetEcmaVm();
426 LocalScope scope(vm);
427 Global<ObjectRef> val = value_;
428 Local<ArrayRef> arrayVal = val->GetAllPropertyNames(vm, filter);
429 NativeChunk& chunk = engine_->GetNativeChunk();
430 return chunk.New<ArkNativeArray>(engine_, arrayVal);
431 }
432
AssociateTypeTag(NapiTypeTag * typeTag)433 bool ArkNativeObject::AssociateTypeTag(NapiTypeTag* typeTag)
434 {
435 const char name[] = "ACENAPI_TYPETAG";
436 bool result = false;
437 bool hasPribate = false;
438 hasPribate = HasProperty(name);
439 if (!hasPribate) {
440 auto resultValue = engine_->CreateBigWords(
441 0, 2, reinterpret_cast<const uint64_t*>(typeTag)); // 2: Indicates that the number of elements is 2
442 result = this->SetProperty(name, resultValue);
443 }
444 return result;
445 }
446
CheckTypeTag(NapiTypeTag * typeTag)447 bool ArkNativeObject::CheckTypeTag(NapiTypeTag* typeTag)
448 {
449 const char name[] = "ACENAPI_TYPETAG";
450 bool result = false;
451 result = this->HasProperty(name);
452 if (result) {
453 auto resultValue = this->GetProperty(name);
454 Global<JSValueRef> object = *resultValue;
455 if (object->IsBigInt()) {
456 int sign;
457 size_t size = 2; // 2: Indicates that the number of elements is 2
458 NapiTypeTag tag;
459 auto nativeBigint = reinterpret_cast<NativeBigint*>(resultValue->GetInterface(NativeBigint::INTERFACE_ID));
460 nativeBigint->GetWordsArray(&sign, &size, reinterpret_cast<uint64_t*>(&tag));
461 if (sign == 0 && ((size == 1) || (size == 2))) { // 2: Indicates that the number of elements is 2
462 result = (tag.lower == typeTag->lower && tag.upper == typeTag->upper);
463 }
464 }
465 }
466 return result;
467 }
468
SetModuleName(std::string moduleName)469 void ArkNativeObject::SetModuleName(std::string moduleName)
470 {
471 NativeChunk& chunk = engine_->GetNativeChunk();
472 NativeValue* moduleValue = chunk.New<ArkNativeString>(engine_, moduleName.c_str(),
473 moduleName.size());
474 this->SetProperty(ArkNativeObject::PANDA_MODULE_NAME, moduleValue);
475 }
476
GetModuleName()477 std::string ArkNativeObject::GetModuleName()
478 {
479 std::string moduleName("");
480 auto nativeModuleName = this->GetProperty(ArkNativeObject::PANDA_MODULE_NAME);
481 if (nativeModuleName != nullptr && nativeModuleName->TypeOf() == NATIVE_STRING) {
482 auto nativeString = reinterpret_cast<NativeString*>(nativeModuleName->GetInterface(NativeString::INTERFACE_ID));
483 char arrayName[PANDA_MODULE_NAME_LEN] = {0};
484 size_t len = 0;
485 nativeString->GetCString(arrayName, PANDA_MODULE_NAME_LEN, &len);
486 moduleName += arrayName;
487 moduleName += ".";
488 }
489 return moduleName;
490 }
491
AddFinalizer(void * pointer,NativeFinalize cb,void * hint)492 void ArkNativeObject::AddFinalizer(void* pointer, NativeFinalize cb, void* hint) {}
493
Freeze()494 void ArkNativeObject::Freeze()
495 {
496 auto vm = engine_->GetEcmaVm();
497 LocalScope scope(vm);
498 Global<ObjectRef> obj = value_;
499
500 obj->Freeze(vm);
501 }
502
Seal()503 void ArkNativeObject::Seal()
504 {
505 auto vm = engine_->GetEcmaVm();
506 LocalScope scope(vm);
507 Global<ObjectRef> obj = value_;
508
509 obj->Seal(vm);
510 }
511
SetElement(uint32_t index,NativeValue * value)512 bool ArkNativeObject::SetElement(uint32_t index, NativeValue* value)
513 {
514 auto vm = engine_->GetEcmaVm();
515 LocalScope scope(vm);
516 Global<ObjectRef> obj = value_;
517 Global<JSValueRef> val = *value;
518 return obj->Set(vm, index, val.ToLocal(vm));
519 }
520
GetElement(uint32_t index)521 NativeValue* ArkNativeObject::GetElement(uint32_t index)
522 {
523 auto vm = engine_->GetEcmaVm();
524 LocalScope scope(vm);
525 Global<ObjectRef> obj = value_;
526 auto val = obj->Get(vm, index);
527 return ArkNativeEngine::ArkValueToNativeValue(engine_, val);
528 }
529
HasElement(uint32_t index)530 bool ArkNativeObject::HasElement(uint32_t index)
531 {
532 auto vm = engine_->GetEcmaVm();
533 LocalScope scope(vm);
534 Global<ObjectRef> obj = value_;
535 return obj->Has(vm, index);
536 }
537
DeleteElement(uint32_t index)538 bool ArkNativeObject::DeleteElement(uint32_t index)
539 {
540 auto vm = engine_->GetEcmaVm();
541 LocalScope scope(vm);
542 Global<ObjectRef> obj = value_;
543 return obj->Delete(vm, index);
544 }