1/* 2 * Copyright (c) 2021-2022 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 "ecmascript/builtins/builtins_dataview.h" 17#include "ecmascript/builtins/builtins_arraybuffer.h" 18#include "ecmascript/js_arraybuffer.h" 19#include "ecmascript/js_tagged_value-inl.h" 20 21namespace panda::ecmascript::builtins { 22// 24.2.2.1 23JSTaggedValue BuiltinsDataView::DataViewConstructor(EcmaRuntimeCallInfo *argv) 24{ 25 ASSERT(argv); 26 JSThread *thread = argv->GetThread(); 27 BUILTINS_API_TRACE(thread, DataView, Constructor); 28 [[maybe_unused]] EcmaHandleScope handleScope(thread); 29 JSHandle<JSTaggedValue> ctor = GetConstructor(argv); 30 JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv); 31 // 1. If NewTarget is undefined, throw a TypeError exception. 32 if (newTarget->IsUndefined()) { 33 THROW_TYPE_ERROR_AND_RETURN(thread, "newtarget is undefined", JSTaggedValue::Exception()); 34 } 35 JSHandle<JSTaggedValue> bufferHandle = GetCallArg(argv, 0); 36 // 2. If Type(buffer) is not Object, throw a TypeError exception. 37 if (!bufferHandle->IsECMAObject()) { 38 THROW_TYPE_ERROR_AND_RETURN(thread, "buffer is not Object", JSTaggedValue::Exception()); 39 } 40 // 3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception. 41 if (!bufferHandle->IsArrayBuffer() && !bufferHandle->IsSharedArrayBuffer()) { 42 THROW_TYPE_ERROR_AND_RETURN(thread, "buffer is not ArrayBuffer", JSTaggedValue::Exception()); 43 } 44 JSHandle<JSTaggedValue> offsetHandle = GetCallArg(argv, 1); 45 // 4. Let numberOffset be ToNumber(byteOffset). 46 JSTaggedNumber offsetNumber = JSTaggedValue::ToNumber(thread, offsetHandle); 47 // 6. ReturnIfAbrupt(offset). 48 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 49 int32_t offsetInt = base::NumberHelper::DoubleInRangeInt32(offsetNumber.GetNumber()); 50 // 7. If numberOffset ≠ offset or offset < 0, throw a RangeError exception. 51 if (offsetInt < 0) { 52 THROW_RANGE_ERROR_AND_RETURN(thread, "Offset out of range", JSTaggedValue::Exception()); 53 } 54 uint32_t offset = static_cast<uint32_t>(offsetInt); 55 // 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 56 if (BuiltinsArrayBuffer::IsDetachedBuffer(bufferHandle.GetTaggedValue())) { 57 THROW_TYPE_ERROR_AND_RETURN(thread, "buffer is Detached Buffer", JSTaggedValue::Exception()); 58 } 59 // 9. Let bufferByteLength be the value of buffer’s [[ArrayBufferByteLength]] internal slot. 60 JSHandle<JSArrayBuffer> arrBufHandle(bufferHandle); 61 uint32_t bufByteLen = arrBufHandle->GetArrayBufferByteLength(); 62 // 10. If offset > bufferByteLength, throw a RangeError exception. 63 if (offset > bufByteLen) { 64 THROW_RANGE_ERROR_AND_RETURN(thread, "offset > bufferByteLength", JSTaggedValue::Exception()); 65 } 66 uint32_t viewByteLen = 0; 67 JSHandle<JSTaggedValue> byteLenHandle = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD); 68 // 11. If byteLength is undefined, then Let viewByteLength be bufferByteLength – offset. 69 if (byteLenHandle->IsUndefined()) { 70 viewByteLen = bufByteLen - offset; 71 } else { 72 // Let viewByteLength be ToIndex(byteLength). 73 JSTaggedNumber byteLen = JSTaggedValue::ToIndex(thread, byteLenHandle); 74 // ReturnIfAbrupt(viewByteLength). 75 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 76 viewByteLen = static_cast<uint32_t>(byteLen.ToInt32()); 77 // If offset+viewByteLength > bufferByteLength, throw a RangeError exception. 78 if (offset + viewByteLen > bufByteLen) { 79 THROW_RANGE_ERROR_AND_RETURN(thread, "offset + viewByteLen > bufByteLen", JSTaggedValue::Exception()); 80 } 81 } 82 // 13. Let O be OrdinaryCreateFromConstructor OrdinaryCreateFromConstructor(NewTarget, "%DataViewPrototype%", 83 // «[[DataView]],[[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]]» ). 84 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 85 JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), newTarget); 86 // 14. ReturnIfAbrupt(O). 87 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 88 JSHandle<JSDataView> dataView(obj); 89 // 15. Set O’s [[DataView]] internal slot to true. 90 dataView->SetDataView(thread, JSTaggedValue::True()); 91 // 16. Set O’s [[ViewedArrayBuffer]] internal slot to buffer. 92 dataView->SetViewedArrayBuffer(thread, bufferHandle.GetTaggedValue()); 93 // 17. Set O’s [[ByteLength]] internal slot to viewByteLength. 94 dataView->SetByteLength(viewByteLen); 95 // 18. Set O’s [[ByteOffset]] internal slot to offset. 96 dataView->SetByteOffset(offset); 97 // 19. Return O. 98 return JSTaggedValue(dataView.GetTaggedValue()); 99} 100 101// 24.2.4.1 102JSTaggedValue BuiltinsDataView::GetBuffer(EcmaRuntimeCallInfo *argv) 103{ 104 ASSERT(argv); 105 JSThread *thread = argv->GetThread(); 106 BUILTINS_API_TRACE(thread, DataView, GetBuffer); 107 [[maybe_unused]] EcmaHandleScope handleScope(thread); 108 // 1. Let O be the this value. 109 JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 110 // 2. f Type(O) is not Object, throw a TypeError exception. 111 if (!thisHandle->IsECMAObject()) { 112 THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 113 } 114 // 3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception. 115 if (!thisHandle->IsDataView()) { 116 THROW_TYPE_ERROR_AND_RETURN(thread, "O does not have a [[ViewedArrayBuffer]]", JSTaggedValue::Exception()); 117 } 118 JSHandle<JSDataView> dataView(thisHandle); 119 // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. 120 JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 121 // 5. Return buffer. 122 return JSTaggedValue(buffer); 123} 124 125// 24.2.4.2 126JSTaggedValue BuiltinsDataView::GetByteLength(EcmaRuntimeCallInfo *argv) 127{ 128 ASSERT(argv); 129 JSThread *thread = argv->GetThread(); 130 BUILTINS_API_TRACE(thread, DataView, GetByteLength); 131 [[maybe_unused]] EcmaHandleScope handleScope(thread); 132 // 1. Let O be the this value. 133 JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 134 // 2. If Type(O) is not Object, throw a TypeError exception. 135 if (!thisHandle->IsECMAObject()) { 136 THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 137 } 138 // 3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception. 139 if (!thisHandle->IsDataView()) { 140 THROW_TYPE_ERROR_AND_RETURN(thread, "O does not have a [[ViewedArrayBuffer]]", JSTaggedValue::Exception()); 141 } 142 JSHandle<JSDataView> dataView(thisHandle); 143 // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. 144 JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 145 // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 146 if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 147 THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 148 } 149 // 6. Let size be the value of O’s [[ByteLength]] internal slot. 150 uint32_t size = dataView->GetByteLength(); 151 // 7. Return size. 152 return JSTaggedValue(size); 153} 154 155// 24.2.4.3 156JSTaggedValue BuiltinsDataView::GetOffset(EcmaRuntimeCallInfo *argv) 157{ 158 ASSERT(argv); 159 JSThread *thread = argv->GetThread(); 160 BUILTINS_API_TRACE(thread, DataView, GetOffset); 161 [[maybe_unused]] EcmaHandleScope handleScope(thread); 162 // 1. Let O be the this value. 163 JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 164 // 2. If Type(O) is not Object, throw a TypeError exception. 165 if (!thisHandle->IsECMAObject()) { 166 THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 167 } 168 // 3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception. 169 if (!thisHandle->IsDataView()) { 170 THROW_TYPE_ERROR_AND_RETURN(thread, "O does not have a [[ViewedArrayBuffer]]", JSTaggedValue::Exception()); 171 } 172 JSHandle<JSDataView> dataView(thisHandle); 173 // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. 174 JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 175 // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 176 if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 177 THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 178 } 179 // 6. Let offset be the value of O’s [[ByteOffset]] internal slot. 180 uint32_t offset = dataView->GetByteOffset(); 181 // 7. Return offset. 182 return JSTaggedValue(offset); 183} 184 185// 24.2.4.5 186JSTaggedValue BuiltinsDataView::GetFloat32(EcmaRuntimeCallInfo *argv) 187{ 188 ASSERT(argv); 189 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetFloat32); 190 return GetTypedValue(argv, DataViewType::FLOAT32); 191} 192 193// 24.2.4.6 194JSTaggedValue BuiltinsDataView::GetFloat64(EcmaRuntimeCallInfo *argv) 195{ 196 ASSERT(argv); 197 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetFloat64); 198 return GetTypedValue(argv, DataViewType::FLOAT64); 199} 200 201// 24.2.4.7 202JSTaggedValue BuiltinsDataView::GetInt8(EcmaRuntimeCallInfo *argv) 203{ 204 ASSERT(argv); 205 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetInt8); 206 return GetTypedValue(argv, DataViewType::INT8); 207} 208 209// 24.2.4.8 210JSTaggedValue BuiltinsDataView::GetInt16(EcmaRuntimeCallInfo *argv) 211{ 212 ASSERT(argv); 213 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetInt16); 214 return GetTypedValue(argv, DataViewType::INT16); 215} 216 217// 24.2.4.9 218JSTaggedValue BuiltinsDataView::GetInt32(EcmaRuntimeCallInfo *argv) 219{ 220 ASSERT(argv); 221 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetInt32); 222 return GetTypedValue(argv, DataViewType::INT32); 223} 224 225// 24.2.4.10 226JSTaggedValue BuiltinsDataView::GetUint8(EcmaRuntimeCallInfo *argv) 227{ 228 ASSERT(argv); 229 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetUint8); 230 return GetTypedValue(argv, DataViewType::UINT8); 231} 232 233// 24.2.4.11 234JSTaggedValue BuiltinsDataView::GetUint16(EcmaRuntimeCallInfo *argv) 235{ 236 ASSERT(argv); 237 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetUint16); 238 return GetTypedValue(argv, DataViewType::UINT16); 239} 240 241// 24.2.4.12 242JSTaggedValue BuiltinsDataView::GetUint32(EcmaRuntimeCallInfo *argv) 243{ 244 ASSERT(argv); 245 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetUint32); 246 return GetTypedValue(argv, DataViewType::UINT32); 247} 248// 25.3.4.5 249JSTaggedValue BuiltinsDataView::GetBigInt64(EcmaRuntimeCallInfo *argv) 250{ 251 ASSERT(argv); 252 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetBigInt64); 253 return GetTypedValue(argv, DataViewType::BIGINT64); 254} 255// 25.3.4.6 256JSTaggedValue BuiltinsDataView::GetBigUint64(EcmaRuntimeCallInfo *argv) 257{ 258 ASSERT(argv); 259 BUILTINS_API_TRACE(argv->GetThread(), DataView, GetBigUint64); 260 return GetTypedValue(argv, DataViewType::BIGUINT64); 261} 262// 24.2.4.13 263JSTaggedValue BuiltinsDataView::SetFloat32(EcmaRuntimeCallInfo *argv) 264{ 265 ASSERT(argv); 266 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetFloat32); 267 return SetTypedValue(argv, DataViewType::FLOAT32); 268} 269 270// 24.2.4.14 271JSTaggedValue BuiltinsDataView::SetFloat64(EcmaRuntimeCallInfo *argv) 272{ 273 ASSERT(argv); 274 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetFloat64); 275 return SetTypedValue(argv, DataViewType::FLOAT64); 276} 277 278// 24.2.4.15 279JSTaggedValue BuiltinsDataView::SetInt8(EcmaRuntimeCallInfo *argv) 280{ 281 ASSERT(argv); 282 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetInt8); 283 return SetTypedValue(argv, DataViewType::INT8); 284} 285 286// 24.2.4.16 287JSTaggedValue BuiltinsDataView::SetInt16(EcmaRuntimeCallInfo *argv) 288{ 289 ASSERT(argv); 290 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetInt16); 291 return SetTypedValue(argv, DataViewType::INT16); 292} 293 294// 24.2.4.17 295JSTaggedValue BuiltinsDataView::SetInt32(EcmaRuntimeCallInfo *argv) 296{ 297 ASSERT(argv); 298 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetInt32); 299 return SetTypedValue(argv, DataViewType::INT32); 300} 301 302// 24.2.4.18 303JSTaggedValue BuiltinsDataView::SetUint8(EcmaRuntimeCallInfo *argv) 304{ 305 ASSERT(argv); 306 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetUint8); 307 return SetTypedValue(argv, DataViewType::UINT8); 308} 309 310// 24.2.4.19 311JSTaggedValue BuiltinsDataView::SetUint16(EcmaRuntimeCallInfo *argv) 312{ 313 ASSERT(argv); 314 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetUint16); 315 return SetTypedValue(argv, DataViewType::UINT16); 316} 317 318// 24.2.4.20 319JSTaggedValue BuiltinsDataView::SetUint32(EcmaRuntimeCallInfo *argv) 320{ 321 ASSERT(argv); 322 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetUint32); 323 return SetTypedValue(argv, DataViewType::UINT32); 324} 325 326// 25.3.4.15 327JSTaggedValue BuiltinsDataView::SetBigInt64(EcmaRuntimeCallInfo *argv) 328{ 329 ASSERT(argv); 330 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetBigInt64); 331 return SetTypedValue(argv, DataViewType::BIGINT64); 332} 333 334// 25.3.4.16 335JSTaggedValue BuiltinsDataView::SetBigUint64(EcmaRuntimeCallInfo *argv) 336{ 337 ASSERT(argv); 338 BUILTINS_API_TRACE(argv->GetThread(), DataView, SetBigUint64); 339 return SetTypedValue(argv, DataViewType::BIGUINT64); 340} 341 342// 24.2.1.1 343JSTaggedValue BuiltinsDataView::GetViewValue(JSThread *thread, const JSHandle<JSTaggedValue> &view, 344 const JSHandle<JSTaggedValue> &requestIndex, 345 const JSHandle<JSTaggedValue> &littleEndian, 346 DataViewType type) 347{ 348 BUILTINS_API_TRACE(thread, DataView, GetViewValue); 349 // 1. If Type(view) is not Object, throw a TypeError exception. 350 if (!view->IsECMAObject()) { 351 THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 352 } 353 // 2. If view does not have a [[DataView]] internal slot, throw a TypeError exception. 354 if (!view->IsDataView()) { 355 THROW_TYPE_ERROR_AND_RETURN(thread, "view is not dataview", JSTaggedValue::Exception()); 356 } 357 358 int32_t indexInt = 0; 359 if (requestIndex->IsInt()) { 360 // fast get index if requestIndex is int 361 indexInt = requestIndex->GetInt(); 362 } else { 363 // 3. Let numberIndex be ToNumber(requestIndex). 364 JSTaggedNumber numberIndex = JSTaggedValue::ToNumber(thread, requestIndex); 365 // 5. ReturnIfAbrupt(getIndex). 366 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 367 indexInt = base::NumberHelper::DoubleInRangeInt32(numberIndex.GetNumber()); 368 } 369 // 6. If numberIndex ≠ getIndex or getIndex < 0, throw a RangeError exception. 370 if (indexInt < 0) { 371 THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex < 0", JSTaggedValue::Exception()); 372 } 373 uint32_t index = static_cast<uint32_t>(indexInt); 374 // 7. Let isLittleEndian be ToBoolean(isLittleEndian). 375 bool isLittleEndian = false; 376 if (littleEndian->IsUndefined()) { 377 isLittleEndian = false; 378 } else { 379 isLittleEndian = littleEndian->ToBoolean(); 380 } 381 // 8. Let buffer be the value of view’s [[ViewedArrayBuffer]] internal slot. 382 JSHandle<JSDataView> dataView(view); 383 JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 384 // 9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 385 if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 386 THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 387 } 388 // 10. Let viewOffset be the value of view’s [[ByteOffset]] internal slot. 389 uint32_t offset = dataView->GetByteOffset(); 390 // 11. Let viewSize be the value of view’s [[ByteLength]] internal slot. 391 uint32_t size = dataView->GetByteLength(); 392 // 12. Let elementSize be the Number value of the Element Size value specified in Table 49 for Element Type type. 393 uint32_t elementSize = JSDataView::GetElementSize(type); 394 // 13. If getIndex +elementSize > viewSize, throw a RangeError exception. 395 if (index + elementSize > size) { 396 THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex +elementSize > viewSize", JSTaggedValue::Exception()); 397 } 398 // 14. Let bufferIndex be getIndex + viewOffset. 399 uint32_t bufferIndex = index + offset; 400 // 15. Return GetValueFromBuffer(buffer, bufferIndex, type, isLittleEndian). 401 return BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, bufferIndex, type, isLittleEndian); 402} 403 404// 24.2.1.2 405JSTaggedValue BuiltinsDataView::SetViewValue(JSThread *thread, const JSHandle<JSTaggedValue> &view, 406 const JSHandle<JSTaggedValue> &requestIndex, 407 const JSHandle<JSTaggedValue> &littleEndian, 408 DataViewType type, const JSHandle<JSTaggedValue> &value) 409{ 410 // 1. If Type(view) is not Object, throw a TypeError exception. 411 BUILTINS_API_TRACE(thread, DataView, SetViewValue); 412 if (!view->IsECMAObject()) { 413 THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 414 } 415 // 2. If view does not have a [[DataView]] internal slot, throw a TypeError exception. 416 if (!view->IsDataView()) { 417 THROW_TYPE_ERROR_AND_RETURN(thread, "view is not dataview", JSTaggedValue::Exception()); 418 } 419 int64_t index = 0; 420 if (requestIndex->IsInt()) { 421 // fast get index if requestIndex is int 422 index = requestIndex->GetInt(); 423 } else { 424 // 3. Let numberIndex be ToNumber(requestIndex). 425 JSTaggedNumber numberIndex = JSTaggedValue::ToIndex(thread, requestIndex); 426 // 5. ReturnIfAbrupt(getIndex). 427 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 428 index = base::NumberHelper::DoubleInRangeInt32(numberIndex.GetNumber()); 429 } 430 // 6. If numberIndex ≠ getIndex or getIndex < 0, throw a RangeError exception. 431 if (index < 0) { 432 THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex < 0", JSTaggedValue::Exception()); 433 } 434 JSMutableHandle<JSTaggedValue> numValueHandle = JSMutableHandle<JSTaggedValue>(thread, value); 435 if (!value->IsNumber()) { 436 numValueHandle.Update(JSTaggedValue::ToNumeric(thread, value)); 437 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 438 } 439 // 7. Let isLittleEndian be ToBoolean(isLittleEndian). 440 bool isLittleEndian = false; 441 if (littleEndian->IsUndefined()) { 442 isLittleEndian = false; 443 } else { 444 isLittleEndian = littleEndian->ToBoolean(); 445 } 446 // 8. Let buffer be the value of view’s [[ViewedArrayBuffer]] internal slot. 447 JSHandle<JSDataView> dataView(view); 448 JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 449 // 9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 450 if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 451 THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 452 } 453 // 10. Let viewOffset be the value of view’s [[ByteOffset]] internal slot. 454 uint32_t offset = dataView->GetByteOffset(); 455 // 11. Let viewSize be the value of view’s [[ByteLength]] internal slot. 456 uint32_t size = dataView->GetByteLength(); 457 // 12. Let elementSize be the Number value of the Element Size value specified in Table 49 for Element Type type. 458 uint32_t elementSize = JSDataView::GetElementSize(type); 459 // 13. If getIndex +elementSize > viewSize, throw a RangeError exception. 460 if (static_cast<uint32_t>(index) + elementSize > size) { 461 THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex +elementSize > viewSize", JSTaggedValue::Exception()); 462 } 463 // 14. Let bufferIndex be getIndex + viewOffset. 464 uint32_t bufferIndex = static_cast<uint32_t>(index) + offset; 465 // 15. Return SetValueFromBuffer(buffer, bufferIndex, type, value, isLittleEndian). 466 return BuiltinsArrayBuffer::SetValueInBuffer(thread, buffer, bufferIndex, type, numValueHandle, isLittleEndian); 467} 468 469JSTaggedValue BuiltinsDataView::GetTypedValue(EcmaRuntimeCallInfo *argv, DataViewType type) 470{ 471 JSThread *thread = argv->GetThread(); 472 BUILTINS_API_TRACE(thread, DataView, GetTypedValue); 473 [[maybe_unused]] EcmaHandleScope handleScope(thread); 474 JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 475 JSHandle<JSTaggedValue> offsetHandle = GetCallArg(argv, 0); 476 JSHandle<JSTaggedValue> trueHandle(thread, JSTaggedValue::True()); 477 if (type == DataViewType::UINT8 || type == DataViewType::INT8) { 478 return GetViewValue(thread, thisHandle, offsetHandle, trueHandle, type); 479 } 480 JSHandle<JSTaggedValue> littleEndianHandle = GetCallArg(argv, 1); 481 return GetViewValue(thread, thisHandle, offsetHandle, littleEndianHandle, type); 482} 483 484JSTaggedValue BuiltinsDataView::SetTypedValue(EcmaRuntimeCallInfo *argv, DataViewType type) 485{ 486 JSThread *thread = argv->GetThread(); 487 BUILTINS_API_TRACE(thread, DataView, SetTypedValue); 488 [[maybe_unused]] EcmaHandleScope handleScope(thread); 489 JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 490 JSHandle<JSTaggedValue> offsetHandle = GetCallArg(argv, 0); 491 JSHandle<JSTaggedValue> value = GetCallArg(argv, 1); 492 JSHandle<JSTaggedValue> trueHandle(thread, JSTaggedValue::True()); 493 if (type == DataViewType::UINT8 || type == DataViewType::INT8) { 494 return SetViewValue(thread, thisHandle, offsetHandle, trueHandle, type, value); 495 } 496 JSHandle<JSTaggedValue> littleEndianHandle = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD); 497 return SetViewValue(thread, thisHandle, offsetHandle, littleEndianHandle, type, value); 498} 499} // namespace panda::ecmascript::builtins 500