14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_dataview.h" 174514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_arraybuffer.h" 184514f5e3Sopenharmony_ci#include "ecmascript/js_arraybuffer.h" 194514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value-inl.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins { 224514f5e3Sopenharmony_ci// 24.2.2.1 234514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::DataViewConstructor(EcmaRuntimeCallInfo *argv) 244514f5e3Sopenharmony_ci{ 254514f5e3Sopenharmony_ci ASSERT(argv); 264514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 274514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, Constructor); 284514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 294514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> ctor = GetConstructor(argv); 304514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv); 314514f5e3Sopenharmony_ci // 1. If NewTarget is undefined, throw a TypeError exception. 324514f5e3Sopenharmony_ci if (newTarget->IsUndefined()) { 334514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "newtarget is undefined", JSTaggedValue::Exception()); 344514f5e3Sopenharmony_ci } 354514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> bufferHandle = GetCallArg(argv, 0); 364514f5e3Sopenharmony_ci // 2. If Type(buffer) is not Object, throw a TypeError exception. 374514f5e3Sopenharmony_ci if (!bufferHandle->IsECMAObject()) { 384514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "buffer is not Object", JSTaggedValue::Exception()); 394514f5e3Sopenharmony_ci } 404514f5e3Sopenharmony_ci // 3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception. 414514f5e3Sopenharmony_ci if (!bufferHandle->IsArrayBuffer() && !bufferHandle->IsSharedArrayBuffer()) { 424514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "buffer is not ArrayBuffer", JSTaggedValue::Exception()); 434514f5e3Sopenharmony_ci } 444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> offsetHandle = GetCallArg(argv, 1); 454514f5e3Sopenharmony_ci // 4. Let numberOffset be ToNumber(byteOffset). 464514f5e3Sopenharmony_ci JSTaggedNumber offsetNumber = JSTaggedValue::ToNumber(thread, offsetHandle); 474514f5e3Sopenharmony_ci // 6. ReturnIfAbrupt(offset). 484514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 494514f5e3Sopenharmony_ci int32_t offsetInt = base::NumberHelper::DoubleInRangeInt32(offsetNumber.GetNumber()); 504514f5e3Sopenharmony_ci // 7. If numberOffset ≠ offset or offset < 0, throw a RangeError exception. 514514f5e3Sopenharmony_ci if (offsetInt < 0) { 524514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "Offset out of range", JSTaggedValue::Exception()); 534514f5e3Sopenharmony_ci } 544514f5e3Sopenharmony_ci uint32_t offset = static_cast<uint32_t>(offsetInt); 554514f5e3Sopenharmony_ci // 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 564514f5e3Sopenharmony_ci if (BuiltinsArrayBuffer::IsDetachedBuffer(bufferHandle.GetTaggedValue())) { 574514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "buffer is Detached Buffer", JSTaggedValue::Exception()); 584514f5e3Sopenharmony_ci } 594514f5e3Sopenharmony_ci // 9. Let bufferByteLength be the value of buffer’s [[ArrayBufferByteLength]] internal slot. 604514f5e3Sopenharmony_ci JSHandle<JSArrayBuffer> arrBufHandle(bufferHandle); 614514f5e3Sopenharmony_ci uint32_t bufByteLen = arrBufHandle->GetArrayBufferByteLength(); 624514f5e3Sopenharmony_ci // 10. If offset > bufferByteLength, throw a RangeError exception. 634514f5e3Sopenharmony_ci if (offset > bufByteLen) { 644514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "offset > bufferByteLength", JSTaggedValue::Exception()); 654514f5e3Sopenharmony_ci } 664514f5e3Sopenharmony_ci uint32_t viewByteLen = 0; 674514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> byteLenHandle = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD); 684514f5e3Sopenharmony_ci // 11. If byteLength is undefined, then Let viewByteLength be bufferByteLength – offset. 694514f5e3Sopenharmony_ci if (byteLenHandle->IsUndefined()) { 704514f5e3Sopenharmony_ci viewByteLen = bufByteLen - offset; 714514f5e3Sopenharmony_ci } else { 724514f5e3Sopenharmony_ci // Let viewByteLength be ToIndex(byteLength). 734514f5e3Sopenharmony_ci JSTaggedNumber byteLen = JSTaggedValue::ToIndex(thread, byteLenHandle); 744514f5e3Sopenharmony_ci // ReturnIfAbrupt(viewByteLength). 754514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 764514f5e3Sopenharmony_ci viewByteLen = static_cast<uint32_t>(byteLen.ToInt32()); 774514f5e3Sopenharmony_ci // If offset+viewByteLength > bufferByteLength, throw a RangeError exception. 784514f5e3Sopenharmony_ci if (offset + viewByteLen > bufByteLen) { 794514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "offset + viewByteLen > bufByteLen", JSTaggedValue::Exception()); 804514f5e3Sopenharmony_ci } 814514f5e3Sopenharmony_ci } 824514f5e3Sopenharmony_ci // 13. Let O be OrdinaryCreateFromConstructor OrdinaryCreateFromConstructor(NewTarget, "%DataViewPrototype%", 834514f5e3Sopenharmony_ci // «[[DataView]],[[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]]» ). 844514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 854514f5e3Sopenharmony_ci JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), newTarget); 864514f5e3Sopenharmony_ci // 14. ReturnIfAbrupt(O). 874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 884514f5e3Sopenharmony_ci JSHandle<JSDataView> dataView(obj); 894514f5e3Sopenharmony_ci // 15. Set O’s [[DataView]] internal slot to true. 904514f5e3Sopenharmony_ci dataView->SetDataView(thread, JSTaggedValue::True()); 914514f5e3Sopenharmony_ci // 16. Set O’s [[ViewedArrayBuffer]] internal slot to buffer. 924514f5e3Sopenharmony_ci dataView->SetViewedArrayBuffer(thread, bufferHandle.GetTaggedValue()); 934514f5e3Sopenharmony_ci // 17. Set O’s [[ByteLength]] internal slot to viewByteLength. 944514f5e3Sopenharmony_ci dataView->SetByteLength(viewByteLen); 954514f5e3Sopenharmony_ci // 18. Set O’s [[ByteOffset]] internal slot to offset. 964514f5e3Sopenharmony_ci dataView->SetByteOffset(offset); 974514f5e3Sopenharmony_ci // 19. Return O. 984514f5e3Sopenharmony_ci return JSTaggedValue(dataView.GetTaggedValue()); 994514f5e3Sopenharmony_ci} 1004514f5e3Sopenharmony_ci 1014514f5e3Sopenharmony_ci// 24.2.4.1 1024514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetBuffer(EcmaRuntimeCallInfo *argv) 1034514f5e3Sopenharmony_ci{ 1044514f5e3Sopenharmony_ci ASSERT(argv); 1054514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 1064514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, GetBuffer); 1074514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 1084514f5e3Sopenharmony_ci // 1. Let O be the this value. 1094514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 1104514f5e3Sopenharmony_ci // 2. f Type(O) is not Object, throw a TypeError exception. 1114514f5e3Sopenharmony_ci if (!thisHandle->IsECMAObject()) { 1124514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 1134514f5e3Sopenharmony_ci } 1144514f5e3Sopenharmony_ci // 3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception. 1154514f5e3Sopenharmony_ci if (!thisHandle->IsDataView()) { 1164514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "O does not have a [[ViewedArrayBuffer]]", JSTaggedValue::Exception()); 1174514f5e3Sopenharmony_ci } 1184514f5e3Sopenharmony_ci JSHandle<JSDataView> dataView(thisHandle); 1194514f5e3Sopenharmony_ci // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. 1204514f5e3Sopenharmony_ci JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 1214514f5e3Sopenharmony_ci // 5. Return buffer. 1224514f5e3Sopenharmony_ci return JSTaggedValue(buffer); 1234514f5e3Sopenharmony_ci} 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci// 24.2.4.2 1264514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetByteLength(EcmaRuntimeCallInfo *argv) 1274514f5e3Sopenharmony_ci{ 1284514f5e3Sopenharmony_ci ASSERT(argv); 1294514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 1304514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, GetByteLength); 1314514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 1324514f5e3Sopenharmony_ci // 1. Let O be the this value. 1334514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 1344514f5e3Sopenharmony_ci // 2. If Type(O) is not Object, throw a TypeError exception. 1354514f5e3Sopenharmony_ci if (!thisHandle->IsECMAObject()) { 1364514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 1374514f5e3Sopenharmony_ci } 1384514f5e3Sopenharmony_ci // 3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception. 1394514f5e3Sopenharmony_ci if (!thisHandle->IsDataView()) { 1404514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "O does not have a [[ViewedArrayBuffer]]", JSTaggedValue::Exception()); 1414514f5e3Sopenharmony_ci } 1424514f5e3Sopenharmony_ci JSHandle<JSDataView> dataView(thisHandle); 1434514f5e3Sopenharmony_ci // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. 1444514f5e3Sopenharmony_ci JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 1454514f5e3Sopenharmony_ci // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 1464514f5e3Sopenharmony_ci if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 1474514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 1484514f5e3Sopenharmony_ci } 1494514f5e3Sopenharmony_ci // 6. Let size be the value of O’s [[ByteLength]] internal slot. 1504514f5e3Sopenharmony_ci uint32_t size = dataView->GetByteLength(); 1514514f5e3Sopenharmony_ci // 7. Return size. 1524514f5e3Sopenharmony_ci return JSTaggedValue(size); 1534514f5e3Sopenharmony_ci} 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_ci// 24.2.4.3 1564514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetOffset(EcmaRuntimeCallInfo *argv) 1574514f5e3Sopenharmony_ci{ 1584514f5e3Sopenharmony_ci ASSERT(argv); 1594514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 1604514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, GetOffset); 1614514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 1624514f5e3Sopenharmony_ci // 1. Let O be the this value. 1634514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 1644514f5e3Sopenharmony_ci // 2. If Type(O) is not Object, throw a TypeError exception. 1654514f5e3Sopenharmony_ci if (!thisHandle->IsECMAObject()) { 1664514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 1674514f5e3Sopenharmony_ci } 1684514f5e3Sopenharmony_ci // 3. If O does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError exception. 1694514f5e3Sopenharmony_ci if (!thisHandle->IsDataView()) { 1704514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "O does not have a [[ViewedArrayBuffer]]", JSTaggedValue::Exception()); 1714514f5e3Sopenharmony_ci } 1724514f5e3Sopenharmony_ci JSHandle<JSDataView> dataView(thisHandle); 1734514f5e3Sopenharmony_ci // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. 1744514f5e3Sopenharmony_ci JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 1754514f5e3Sopenharmony_ci // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 1764514f5e3Sopenharmony_ci if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 1774514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 1784514f5e3Sopenharmony_ci } 1794514f5e3Sopenharmony_ci // 6. Let offset be the value of O’s [[ByteOffset]] internal slot. 1804514f5e3Sopenharmony_ci uint32_t offset = dataView->GetByteOffset(); 1814514f5e3Sopenharmony_ci // 7. Return offset. 1824514f5e3Sopenharmony_ci return JSTaggedValue(offset); 1834514f5e3Sopenharmony_ci} 1844514f5e3Sopenharmony_ci 1854514f5e3Sopenharmony_ci// 24.2.4.5 1864514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetFloat32(EcmaRuntimeCallInfo *argv) 1874514f5e3Sopenharmony_ci{ 1884514f5e3Sopenharmony_ci ASSERT(argv); 1894514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetFloat32); 1904514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::FLOAT32); 1914514f5e3Sopenharmony_ci} 1924514f5e3Sopenharmony_ci 1934514f5e3Sopenharmony_ci// 24.2.4.6 1944514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetFloat64(EcmaRuntimeCallInfo *argv) 1954514f5e3Sopenharmony_ci{ 1964514f5e3Sopenharmony_ci ASSERT(argv); 1974514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetFloat64); 1984514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::FLOAT64); 1994514f5e3Sopenharmony_ci} 2004514f5e3Sopenharmony_ci 2014514f5e3Sopenharmony_ci// 24.2.4.7 2024514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetInt8(EcmaRuntimeCallInfo *argv) 2034514f5e3Sopenharmony_ci{ 2044514f5e3Sopenharmony_ci ASSERT(argv); 2054514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetInt8); 2064514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::INT8); 2074514f5e3Sopenharmony_ci} 2084514f5e3Sopenharmony_ci 2094514f5e3Sopenharmony_ci// 24.2.4.8 2104514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetInt16(EcmaRuntimeCallInfo *argv) 2114514f5e3Sopenharmony_ci{ 2124514f5e3Sopenharmony_ci ASSERT(argv); 2134514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetInt16); 2144514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::INT16); 2154514f5e3Sopenharmony_ci} 2164514f5e3Sopenharmony_ci 2174514f5e3Sopenharmony_ci// 24.2.4.9 2184514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetInt32(EcmaRuntimeCallInfo *argv) 2194514f5e3Sopenharmony_ci{ 2204514f5e3Sopenharmony_ci ASSERT(argv); 2214514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetInt32); 2224514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::INT32); 2234514f5e3Sopenharmony_ci} 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_ci// 24.2.4.10 2264514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetUint8(EcmaRuntimeCallInfo *argv) 2274514f5e3Sopenharmony_ci{ 2284514f5e3Sopenharmony_ci ASSERT(argv); 2294514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetUint8); 2304514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::UINT8); 2314514f5e3Sopenharmony_ci} 2324514f5e3Sopenharmony_ci 2334514f5e3Sopenharmony_ci// 24.2.4.11 2344514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetUint16(EcmaRuntimeCallInfo *argv) 2354514f5e3Sopenharmony_ci{ 2364514f5e3Sopenharmony_ci ASSERT(argv); 2374514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetUint16); 2384514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::UINT16); 2394514f5e3Sopenharmony_ci} 2404514f5e3Sopenharmony_ci 2414514f5e3Sopenharmony_ci// 24.2.4.12 2424514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetUint32(EcmaRuntimeCallInfo *argv) 2434514f5e3Sopenharmony_ci{ 2444514f5e3Sopenharmony_ci ASSERT(argv); 2454514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetUint32); 2464514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::UINT32); 2474514f5e3Sopenharmony_ci} 2484514f5e3Sopenharmony_ci// 25.3.4.5 2494514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetBigInt64(EcmaRuntimeCallInfo *argv) 2504514f5e3Sopenharmony_ci{ 2514514f5e3Sopenharmony_ci ASSERT(argv); 2524514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetBigInt64); 2534514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::BIGINT64); 2544514f5e3Sopenharmony_ci} 2554514f5e3Sopenharmony_ci// 25.3.4.6 2564514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetBigUint64(EcmaRuntimeCallInfo *argv) 2574514f5e3Sopenharmony_ci{ 2584514f5e3Sopenharmony_ci ASSERT(argv); 2594514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, GetBigUint64); 2604514f5e3Sopenharmony_ci return GetTypedValue(argv, DataViewType::BIGUINT64); 2614514f5e3Sopenharmony_ci} 2624514f5e3Sopenharmony_ci// 24.2.4.13 2634514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetFloat32(EcmaRuntimeCallInfo *argv) 2644514f5e3Sopenharmony_ci{ 2654514f5e3Sopenharmony_ci ASSERT(argv); 2664514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetFloat32); 2674514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::FLOAT32); 2684514f5e3Sopenharmony_ci} 2694514f5e3Sopenharmony_ci 2704514f5e3Sopenharmony_ci// 24.2.4.14 2714514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetFloat64(EcmaRuntimeCallInfo *argv) 2724514f5e3Sopenharmony_ci{ 2734514f5e3Sopenharmony_ci ASSERT(argv); 2744514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetFloat64); 2754514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::FLOAT64); 2764514f5e3Sopenharmony_ci} 2774514f5e3Sopenharmony_ci 2784514f5e3Sopenharmony_ci// 24.2.4.15 2794514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetInt8(EcmaRuntimeCallInfo *argv) 2804514f5e3Sopenharmony_ci{ 2814514f5e3Sopenharmony_ci ASSERT(argv); 2824514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetInt8); 2834514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::INT8); 2844514f5e3Sopenharmony_ci} 2854514f5e3Sopenharmony_ci 2864514f5e3Sopenharmony_ci// 24.2.4.16 2874514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetInt16(EcmaRuntimeCallInfo *argv) 2884514f5e3Sopenharmony_ci{ 2894514f5e3Sopenharmony_ci ASSERT(argv); 2904514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetInt16); 2914514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::INT16); 2924514f5e3Sopenharmony_ci} 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ci// 24.2.4.17 2954514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetInt32(EcmaRuntimeCallInfo *argv) 2964514f5e3Sopenharmony_ci{ 2974514f5e3Sopenharmony_ci ASSERT(argv); 2984514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetInt32); 2994514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::INT32); 3004514f5e3Sopenharmony_ci} 3014514f5e3Sopenharmony_ci 3024514f5e3Sopenharmony_ci// 24.2.4.18 3034514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetUint8(EcmaRuntimeCallInfo *argv) 3044514f5e3Sopenharmony_ci{ 3054514f5e3Sopenharmony_ci ASSERT(argv); 3064514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetUint8); 3074514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::UINT8); 3084514f5e3Sopenharmony_ci} 3094514f5e3Sopenharmony_ci 3104514f5e3Sopenharmony_ci// 24.2.4.19 3114514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetUint16(EcmaRuntimeCallInfo *argv) 3124514f5e3Sopenharmony_ci{ 3134514f5e3Sopenharmony_ci ASSERT(argv); 3144514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetUint16); 3154514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::UINT16); 3164514f5e3Sopenharmony_ci} 3174514f5e3Sopenharmony_ci 3184514f5e3Sopenharmony_ci// 24.2.4.20 3194514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetUint32(EcmaRuntimeCallInfo *argv) 3204514f5e3Sopenharmony_ci{ 3214514f5e3Sopenharmony_ci ASSERT(argv); 3224514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetUint32); 3234514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::UINT32); 3244514f5e3Sopenharmony_ci} 3254514f5e3Sopenharmony_ci 3264514f5e3Sopenharmony_ci// 25.3.4.15 3274514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetBigInt64(EcmaRuntimeCallInfo *argv) 3284514f5e3Sopenharmony_ci{ 3294514f5e3Sopenharmony_ci ASSERT(argv); 3304514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetBigInt64); 3314514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::BIGINT64); 3324514f5e3Sopenharmony_ci} 3334514f5e3Sopenharmony_ci 3344514f5e3Sopenharmony_ci// 25.3.4.16 3354514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetBigUint64(EcmaRuntimeCallInfo *argv) 3364514f5e3Sopenharmony_ci{ 3374514f5e3Sopenharmony_ci ASSERT(argv); 3384514f5e3Sopenharmony_ci BUILTINS_API_TRACE(argv->GetThread(), DataView, SetBigUint64); 3394514f5e3Sopenharmony_ci return SetTypedValue(argv, DataViewType::BIGUINT64); 3404514f5e3Sopenharmony_ci} 3414514f5e3Sopenharmony_ci 3424514f5e3Sopenharmony_ci// 24.2.1.1 3434514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetViewValue(JSThread *thread, const JSHandle<JSTaggedValue> &view, 3444514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &requestIndex, 3454514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &littleEndian, 3464514f5e3Sopenharmony_ci DataViewType type) 3474514f5e3Sopenharmony_ci{ 3484514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, GetViewValue); 3494514f5e3Sopenharmony_ci // 1. If Type(view) is not Object, throw a TypeError exception. 3504514f5e3Sopenharmony_ci if (!view->IsECMAObject()) { 3514514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 3524514f5e3Sopenharmony_ci } 3534514f5e3Sopenharmony_ci // 2. If view does not have a [[DataView]] internal slot, throw a TypeError exception. 3544514f5e3Sopenharmony_ci if (!view->IsDataView()) { 3554514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "view is not dataview", JSTaggedValue::Exception()); 3564514f5e3Sopenharmony_ci } 3574514f5e3Sopenharmony_ci 3584514f5e3Sopenharmony_ci int32_t indexInt = 0; 3594514f5e3Sopenharmony_ci if (requestIndex->IsInt()) { 3604514f5e3Sopenharmony_ci // fast get index if requestIndex is int 3614514f5e3Sopenharmony_ci indexInt = requestIndex->GetInt(); 3624514f5e3Sopenharmony_ci } else { 3634514f5e3Sopenharmony_ci // 3. Let numberIndex be ToNumber(requestIndex). 3644514f5e3Sopenharmony_ci JSTaggedNumber numberIndex = JSTaggedValue::ToNumber(thread, requestIndex); 3654514f5e3Sopenharmony_ci // 5. ReturnIfAbrupt(getIndex). 3664514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3674514f5e3Sopenharmony_ci indexInt = base::NumberHelper::DoubleInRangeInt32(numberIndex.GetNumber()); 3684514f5e3Sopenharmony_ci } 3694514f5e3Sopenharmony_ci // 6. If numberIndex ≠ getIndex or getIndex < 0, throw a RangeError exception. 3704514f5e3Sopenharmony_ci if (indexInt < 0) { 3714514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex < 0", JSTaggedValue::Exception()); 3724514f5e3Sopenharmony_ci } 3734514f5e3Sopenharmony_ci uint32_t index = static_cast<uint32_t>(indexInt); 3744514f5e3Sopenharmony_ci // 7. Let isLittleEndian be ToBoolean(isLittleEndian). 3754514f5e3Sopenharmony_ci bool isLittleEndian = false; 3764514f5e3Sopenharmony_ci if (littleEndian->IsUndefined()) { 3774514f5e3Sopenharmony_ci isLittleEndian = false; 3784514f5e3Sopenharmony_ci } else { 3794514f5e3Sopenharmony_ci isLittleEndian = littleEndian->ToBoolean(); 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci // 8. Let buffer be the value of view’s [[ViewedArrayBuffer]] internal slot. 3824514f5e3Sopenharmony_ci JSHandle<JSDataView> dataView(view); 3834514f5e3Sopenharmony_ci JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 3844514f5e3Sopenharmony_ci // 9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 3854514f5e3Sopenharmony_ci if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 3864514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 3874514f5e3Sopenharmony_ci } 3884514f5e3Sopenharmony_ci // 10. Let viewOffset be the value of view’s [[ByteOffset]] internal slot. 3894514f5e3Sopenharmony_ci uint32_t offset = dataView->GetByteOffset(); 3904514f5e3Sopenharmony_ci // 11. Let viewSize be the value of view’s [[ByteLength]] internal slot. 3914514f5e3Sopenharmony_ci uint32_t size = dataView->GetByteLength(); 3924514f5e3Sopenharmony_ci // 12. Let elementSize be the Number value of the Element Size value specified in Table 49 for Element Type type. 3934514f5e3Sopenharmony_ci uint32_t elementSize = JSDataView::GetElementSize(type); 3944514f5e3Sopenharmony_ci // 13. If getIndex +elementSize > viewSize, throw a RangeError exception. 3954514f5e3Sopenharmony_ci if (index + elementSize > size) { 3964514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex +elementSize > viewSize", JSTaggedValue::Exception()); 3974514f5e3Sopenharmony_ci } 3984514f5e3Sopenharmony_ci // 14. Let bufferIndex be getIndex + viewOffset. 3994514f5e3Sopenharmony_ci uint32_t bufferIndex = index + offset; 4004514f5e3Sopenharmony_ci // 15. Return GetValueFromBuffer(buffer, bufferIndex, type, isLittleEndian). 4014514f5e3Sopenharmony_ci return BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, bufferIndex, type, isLittleEndian); 4024514f5e3Sopenharmony_ci} 4034514f5e3Sopenharmony_ci 4044514f5e3Sopenharmony_ci// 24.2.1.2 4054514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetViewValue(JSThread *thread, const JSHandle<JSTaggedValue> &view, 4064514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &requestIndex, 4074514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &littleEndian, 4084514f5e3Sopenharmony_ci DataViewType type, const JSHandle<JSTaggedValue> &value) 4094514f5e3Sopenharmony_ci{ 4104514f5e3Sopenharmony_ci // 1. If Type(view) is not Object, throw a TypeError exception. 4114514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, SetViewValue); 4124514f5e3Sopenharmony_ci if (!view->IsECMAObject()) { 4134514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Type(O) is not Object", JSTaggedValue::Exception()); 4144514f5e3Sopenharmony_ci } 4154514f5e3Sopenharmony_ci // 2. If view does not have a [[DataView]] internal slot, throw a TypeError exception. 4164514f5e3Sopenharmony_ci if (!view->IsDataView()) { 4174514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "view is not dataview", JSTaggedValue::Exception()); 4184514f5e3Sopenharmony_ci } 4194514f5e3Sopenharmony_ci int64_t index = 0; 4204514f5e3Sopenharmony_ci if (requestIndex->IsInt()) { 4214514f5e3Sopenharmony_ci // fast get index if requestIndex is int 4224514f5e3Sopenharmony_ci index = requestIndex->GetInt(); 4234514f5e3Sopenharmony_ci } else { 4244514f5e3Sopenharmony_ci // 3. Let numberIndex be ToNumber(requestIndex). 4254514f5e3Sopenharmony_ci JSTaggedNumber numberIndex = JSTaggedValue::ToIndex(thread, requestIndex); 4264514f5e3Sopenharmony_ci // 5. ReturnIfAbrupt(getIndex). 4274514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4284514f5e3Sopenharmony_ci index = base::NumberHelper::DoubleInRangeInt32(numberIndex.GetNumber()); 4294514f5e3Sopenharmony_ci } 4304514f5e3Sopenharmony_ci // 6. If numberIndex ≠ getIndex or getIndex < 0, throw a RangeError exception. 4314514f5e3Sopenharmony_ci if (index < 0) { 4324514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex < 0", JSTaggedValue::Exception()); 4334514f5e3Sopenharmony_ci } 4344514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> numValueHandle = JSMutableHandle<JSTaggedValue>(thread, value); 4354514f5e3Sopenharmony_ci if (!value->IsNumber()) { 4364514f5e3Sopenharmony_ci numValueHandle.Update(JSTaggedValue::ToNumeric(thread, value)); 4374514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4384514f5e3Sopenharmony_ci } 4394514f5e3Sopenharmony_ci // 7. Let isLittleEndian be ToBoolean(isLittleEndian). 4404514f5e3Sopenharmony_ci bool isLittleEndian = false; 4414514f5e3Sopenharmony_ci if (littleEndian->IsUndefined()) { 4424514f5e3Sopenharmony_ci isLittleEndian = false; 4434514f5e3Sopenharmony_ci } else { 4444514f5e3Sopenharmony_ci isLittleEndian = littleEndian->ToBoolean(); 4454514f5e3Sopenharmony_ci } 4464514f5e3Sopenharmony_ci // 8. Let buffer be the value of view’s [[ViewedArrayBuffer]] internal slot. 4474514f5e3Sopenharmony_ci JSHandle<JSDataView> dataView(view); 4484514f5e3Sopenharmony_ci JSTaggedValue buffer = dataView->GetViewedArrayBuffer(); 4494514f5e3Sopenharmony_ci // 9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. 4504514f5e3Sopenharmony_ci if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { 4514514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", JSTaggedValue::Exception()); 4524514f5e3Sopenharmony_ci } 4534514f5e3Sopenharmony_ci // 10. Let viewOffset be the value of view’s [[ByteOffset]] internal slot. 4544514f5e3Sopenharmony_ci uint32_t offset = dataView->GetByteOffset(); 4554514f5e3Sopenharmony_ci // 11. Let viewSize be the value of view’s [[ByteLength]] internal slot. 4564514f5e3Sopenharmony_ci uint32_t size = dataView->GetByteLength(); 4574514f5e3Sopenharmony_ci // 12. Let elementSize be the Number value of the Element Size value specified in Table 49 for Element Type type. 4584514f5e3Sopenharmony_ci uint32_t elementSize = JSDataView::GetElementSize(type); 4594514f5e3Sopenharmony_ci // 13. If getIndex +elementSize > viewSize, throw a RangeError exception. 4604514f5e3Sopenharmony_ci if (static_cast<uint32_t>(index) + elementSize > size) { 4614514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex +elementSize > viewSize", JSTaggedValue::Exception()); 4624514f5e3Sopenharmony_ci } 4634514f5e3Sopenharmony_ci // 14. Let bufferIndex be getIndex + viewOffset. 4644514f5e3Sopenharmony_ci uint32_t bufferIndex = static_cast<uint32_t>(index) + offset; 4654514f5e3Sopenharmony_ci // 15. Return SetValueFromBuffer(buffer, bufferIndex, type, value, isLittleEndian). 4664514f5e3Sopenharmony_ci return BuiltinsArrayBuffer::SetValueInBuffer(thread, buffer, bufferIndex, type, numValueHandle, isLittleEndian); 4674514f5e3Sopenharmony_ci} 4684514f5e3Sopenharmony_ci 4694514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::GetTypedValue(EcmaRuntimeCallInfo *argv, DataViewType type) 4704514f5e3Sopenharmony_ci{ 4714514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 4724514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, GetTypedValue); 4734514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 4744514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 4754514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> offsetHandle = GetCallArg(argv, 0); 4764514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> trueHandle(thread, JSTaggedValue::True()); 4774514f5e3Sopenharmony_ci if (type == DataViewType::UINT8 || type == DataViewType::INT8) { 4784514f5e3Sopenharmony_ci return GetViewValue(thread, thisHandle, offsetHandle, trueHandle, type); 4794514f5e3Sopenharmony_ci } 4804514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> littleEndianHandle = GetCallArg(argv, 1); 4814514f5e3Sopenharmony_ci return GetViewValue(thread, thisHandle, offsetHandle, littleEndianHandle, type); 4824514f5e3Sopenharmony_ci} 4834514f5e3Sopenharmony_ci 4844514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDataView::SetTypedValue(EcmaRuntimeCallInfo *argv, DataViewType type) 4854514f5e3Sopenharmony_ci{ 4864514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 4874514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DataView, SetTypedValue); 4884514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 4894514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisHandle = GetThis(argv); 4904514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> offsetHandle = GetCallArg(argv, 0); 4914514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = GetCallArg(argv, 1); 4924514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> trueHandle(thread, JSTaggedValue::True()); 4934514f5e3Sopenharmony_ci if (type == DataViewType::UINT8 || type == DataViewType::INT8) { 4944514f5e3Sopenharmony_ci return SetViewValue(thread, thisHandle, offsetHandle, trueHandle, type, value); 4954514f5e3Sopenharmony_ci } 4964514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> littleEndianHandle = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD); 4974514f5e3Sopenharmony_ci return SetViewValue(thread, thisHandle, offsetHandle, littleEndianHandle, type, value); 4984514f5e3Sopenharmony_ci} 4994514f5e3Sopenharmony_ci} // namespace panda::ecmascript::builtins 500