11cb0ef41Sopenharmony_ci#include "aliased_buffer-inl.h" 21cb0ef41Sopenharmony_ci#include "node_test_fixture.h" 31cb0ef41Sopenharmony_ci#include "v8.h" 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciusing node::AliasedBufferBase; 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciclass AliasBufferTest : public NodeTestFixture {}; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_citemplate <class NativeT> 101cb0ef41Sopenharmony_civoid CreateOracleValues(std::vector<NativeT>* buf) { 111cb0ef41Sopenharmony_ci for (size_t i = 0, j = buf->size(); i < buf->size(); i++, j--) { 121cb0ef41Sopenharmony_ci (*buf)[i] = static_cast<NativeT>(j); 131cb0ef41Sopenharmony_ci } 141cb0ef41Sopenharmony_ci} 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_citemplate <class NativeT, class V8T> 171cb0ef41Sopenharmony_civoid WriteViaOperator(AliasedBufferBase<NativeT, V8T>* aliasedBuffer, 181cb0ef41Sopenharmony_ci const std::vector<NativeT>& oracle) { 191cb0ef41Sopenharmony_ci // write through the API 201cb0ef41Sopenharmony_ci for (size_t i = 0; i < oracle.size(); i++) { 211cb0ef41Sopenharmony_ci (*aliasedBuffer)[i] = oracle[i]; 221cb0ef41Sopenharmony_ci } 231cb0ef41Sopenharmony_ci} 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_citemplate <class NativeT, class V8T> 261cb0ef41Sopenharmony_civoid WriteViaSetValue(AliasedBufferBase<NativeT, V8T>* aliasedBuffer, 271cb0ef41Sopenharmony_ci const std::vector<NativeT>& oracle) { 281cb0ef41Sopenharmony_ci // write through the API 291cb0ef41Sopenharmony_ci for (size_t i = 0; i < oracle.size(); i++) { 301cb0ef41Sopenharmony_ci aliasedBuffer->SetValue(i, oracle[i]); 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci} 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_citemplate <class NativeT, class V8T> 351cb0ef41Sopenharmony_civoid ReadAndValidate(v8::Isolate* isolate, 361cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, 371cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT, V8T>* aliasedBuffer, 381cb0ef41Sopenharmony_ci const std::vector<NativeT>& oracle) { 391cb0ef41Sopenharmony_ci // read through the API 401cb0ef41Sopenharmony_ci for (size_t i = 0; i < oracle.size(); i++) { 411cb0ef41Sopenharmony_ci NativeT v1 = (*aliasedBuffer)[i]; 421cb0ef41Sopenharmony_ci NativeT v2 = aliasedBuffer->GetValue(i); 431cb0ef41Sopenharmony_ci EXPECT_TRUE(v1 == oracle[i]); 441cb0ef41Sopenharmony_ci EXPECT_TRUE(v2 == oracle[i]); 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci // validate size of JS Buffer 481cb0ef41Sopenharmony_ci EXPECT_TRUE(aliasedBuffer->GetJSArray()->Length() == oracle.size()); 491cb0ef41Sopenharmony_ci EXPECT_TRUE( 501cb0ef41Sopenharmony_ci aliasedBuffer->GetJSArray()->ByteLength() == 511cb0ef41Sopenharmony_ci (oracle.size() * sizeof(NativeT))); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci // validate operator * and GetBuffer are the same 541cb0ef41Sopenharmony_ci EXPECT_TRUE(aliasedBuffer->GetNativeBuffer() == *(*aliasedBuffer)); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci // read through the JS API 571cb0ef41Sopenharmony_ci for (size_t i = 0; i < oracle.size(); i++) { 581cb0ef41Sopenharmony_ci v8::Local<V8T> v8TypedArray = aliasedBuffer->GetJSArray(); 591cb0ef41Sopenharmony_ci v8::MaybeLocal<v8::Value> v = v8TypedArray->Get(context, i); 601cb0ef41Sopenharmony_ci EXPECT_TRUE(v.IsEmpty() == false); 611cb0ef41Sopenharmony_ci v8::Local<v8::Value> v2 = v.ToLocalChecked(); 621cb0ef41Sopenharmony_ci EXPECT_TRUE(v2->IsNumber()); 631cb0ef41Sopenharmony_ci v8::MaybeLocal<v8::Number> v3 = v2->ToNumber(context); 641cb0ef41Sopenharmony_ci v8::Local<v8::Number> v4 = v3.ToLocalChecked(); 651cb0ef41Sopenharmony_ci NativeT actualValue = static_cast<NativeT>(v4->Value()); 661cb0ef41Sopenharmony_ci EXPECT_TRUE(actualValue == oracle[i]); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci} 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_citemplate <class NativeT, class V8T> 711cb0ef41Sopenharmony_civoid ReadWriteTest(v8::Isolate* isolate) { 721cb0ef41Sopenharmony_ci v8::Isolate::Scope isolate_scope(isolate); 731cb0ef41Sopenharmony_ci v8::HandleScope handle_scope(isolate); 741cb0ef41Sopenharmony_ci v8::Local<v8::Context> context = v8::Context::New(isolate); 751cb0ef41Sopenharmony_ci v8::Context::Scope context_scope(context); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci const size_t size = 100; 781cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT, V8T> ab(isolate, size); 791cb0ef41Sopenharmony_ci std::vector<NativeT> oracle(size); 801cb0ef41Sopenharmony_ci CreateOracleValues(&oracle); 811cb0ef41Sopenharmony_ci WriteViaOperator(&ab, oracle); 821cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab, oracle); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci WriteViaSetValue(&ab, oracle); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // validate copy constructor 871cb0ef41Sopenharmony_ci { 881cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT, V8T> ab2(ab); 891cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab2, oracle); 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab, oracle); 921cb0ef41Sopenharmony_ci} 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_citemplate < 951cb0ef41Sopenharmony_ci class NativeT_A, class V8T_A, 961cb0ef41Sopenharmony_ci class NativeT_B, class V8T_B, 971cb0ef41Sopenharmony_ci class NativeT_C, class V8T_C> 981cb0ef41Sopenharmony_civoid SharedBufferTest( 991cb0ef41Sopenharmony_ci v8::Isolate* isolate, 1001cb0ef41Sopenharmony_ci size_t count_A, 1011cb0ef41Sopenharmony_ci size_t count_B, 1021cb0ef41Sopenharmony_ci size_t count_C) { 1031cb0ef41Sopenharmony_ci v8::Isolate::Scope isolate_scope(isolate); 1041cb0ef41Sopenharmony_ci v8::HandleScope handle_scope(isolate); 1051cb0ef41Sopenharmony_ci v8::Local<v8::Context> context = v8::Context::New(isolate); 1061cb0ef41Sopenharmony_ci v8::Context::Scope context_scope(context); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci size_t sizeInBytes_A = count_A * sizeof(NativeT_A); 1091cb0ef41Sopenharmony_ci size_t sizeInBytes_B = count_B * sizeof(NativeT_B); 1101cb0ef41Sopenharmony_ci size_t sizeInBytes_C = count_C * sizeof(NativeT_C); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci AliasedBufferBase<uint8_t, v8::Uint8Array> rootBuffer( 1131cb0ef41Sopenharmony_ci isolate, sizeInBytes_A + sizeInBytes_B + sizeInBytes_C); 1141cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT_A, V8T_A> ab_A(isolate, 0, count_A, rootBuffer); 1151cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT_B, V8T_B> ab_B( 1161cb0ef41Sopenharmony_ci isolate, sizeInBytes_A, count_B, rootBuffer); 1171cb0ef41Sopenharmony_ci AliasedBufferBase<NativeT_C, V8T_C> ab_C( 1181cb0ef41Sopenharmony_ci isolate, sizeInBytes_A + sizeInBytes_B, count_C, rootBuffer); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci std::vector<NativeT_A> oracle_A(count_A); 1211cb0ef41Sopenharmony_ci std::vector<NativeT_B> oracle_B(count_B); 1221cb0ef41Sopenharmony_ci std::vector<NativeT_C> oracle_C(count_C); 1231cb0ef41Sopenharmony_ci CreateOracleValues(&oracle_A); 1241cb0ef41Sopenharmony_ci CreateOracleValues(&oracle_B); 1251cb0ef41Sopenharmony_ci CreateOracleValues(&oracle_C); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci WriteViaOperator(&ab_A, oracle_A); 1281cb0ef41Sopenharmony_ci WriteViaOperator(&ab_B, oracle_B); 1291cb0ef41Sopenharmony_ci WriteViaOperator(&ab_C, oracle_C); 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab_A, oracle_A); 1321cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab_B, oracle_B); 1331cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab_C, oracle_C); 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci WriteViaSetValue(&ab_A, oracle_A); 1361cb0ef41Sopenharmony_ci WriteViaSetValue(&ab_B, oracle_B); 1371cb0ef41Sopenharmony_ci WriteViaSetValue(&ab_C, oracle_C); 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab_A, oracle_A); 1401cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab_B, oracle_B); 1411cb0ef41Sopenharmony_ci ReadAndValidate(isolate, context, &ab_C, oracle_C); 1421cb0ef41Sopenharmony_ci} 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Uint8Array) { 1451cb0ef41Sopenharmony_ci ReadWriteTest<uint8_t, v8::Uint8Array>(isolate_); 1461cb0ef41Sopenharmony_ci} 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Int8Array) { 1491cb0ef41Sopenharmony_ci ReadWriteTest<int8_t, v8::Int8Array>(isolate_); 1501cb0ef41Sopenharmony_ci} 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Uint16Array) { 1531cb0ef41Sopenharmony_ci ReadWriteTest<uint16_t, v8::Uint16Array>(isolate_); 1541cb0ef41Sopenharmony_ci} 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Int16Array) { 1571cb0ef41Sopenharmony_ci ReadWriteTest<int16_t, v8::Int16Array>(isolate_); 1581cb0ef41Sopenharmony_ci} 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Uint32Array) { 1611cb0ef41Sopenharmony_ci ReadWriteTest<uint32_t, v8::Uint32Array>(isolate_); 1621cb0ef41Sopenharmony_ci} 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Int32Array) { 1651cb0ef41Sopenharmony_ci ReadWriteTest<int32_t, v8::Int32Array>(isolate_); 1661cb0ef41Sopenharmony_ci} 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Float32Array) { 1691cb0ef41Sopenharmony_ci ReadWriteTest<float, v8::Float32Array>(isolate_); 1701cb0ef41Sopenharmony_ci} 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Float64Array) { 1731cb0ef41Sopenharmony_ci ReadWriteTest<double, v8::Float64Array>(isolate_); 1741cb0ef41Sopenharmony_ci} 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer1) { 1771cb0ef41Sopenharmony_ci SharedBufferTest< 1781cb0ef41Sopenharmony_ci uint32_t, v8::Uint32Array, 1791cb0ef41Sopenharmony_ci double, v8::Float64Array, 1801cb0ef41Sopenharmony_ci int8_t, v8::Int8Array>(isolate_, 100, 80, 8); 1811cb0ef41Sopenharmony_ci} 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer2) { 1841cb0ef41Sopenharmony_ci SharedBufferTest< 1851cb0ef41Sopenharmony_ci double, v8::Float64Array, 1861cb0ef41Sopenharmony_ci int8_t, v8::Int8Array, 1871cb0ef41Sopenharmony_ci double, v8::Float64Array>(isolate_, 100, 8, 8); 1881cb0ef41Sopenharmony_ci} 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer3) { 1911cb0ef41Sopenharmony_ci SharedBufferTest< 1921cb0ef41Sopenharmony_ci int8_t, v8::Int8Array, 1931cb0ef41Sopenharmony_ci int8_t, v8::Int8Array, 1941cb0ef41Sopenharmony_ci double, v8::Float64Array>(isolate_, 1, 7, 8); 1951cb0ef41Sopenharmony_ci} 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer4) { 1981cb0ef41Sopenharmony_ci SharedBufferTest< 1991cb0ef41Sopenharmony_ci int8_t, v8::Int8Array, 2001cb0ef41Sopenharmony_ci int8_t, v8::Int8Array, 2011cb0ef41Sopenharmony_ci int32_t, v8::Int32Array>(isolate_, 1, 3, 1); 2021cb0ef41Sopenharmony_ci} 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, OperatorOverloads) { 2051cb0ef41Sopenharmony_ci v8::Isolate::Scope isolate_scope(isolate_); 2061cb0ef41Sopenharmony_ci v8::HandleScope handle_scope(isolate_); 2071cb0ef41Sopenharmony_ci v8::Local<v8::Context> context = v8::Context::New(isolate_); 2081cb0ef41Sopenharmony_ci v8::Context::Scope context_scope(context); 2091cb0ef41Sopenharmony_ci const size_t size = 10; 2101cb0ef41Sopenharmony_ci AliasedBufferBase<uint32_t, v8::Uint32Array> ab{isolate_, size}; 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(1), ab[0] = 1); 2131cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(4), ab[0] += 3); 2141cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(2), ab[0] -= 2); 2151cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(-2), -ab[0]); 2161cb0ef41Sopenharmony_ci} 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, OperatorOverloadsRefs) { 2191cb0ef41Sopenharmony_ci v8::Isolate::Scope isolate_scope(isolate_); 2201cb0ef41Sopenharmony_ci v8::HandleScope handle_scope(isolate_); 2211cb0ef41Sopenharmony_ci v8::Local<v8::Context> context = v8::Context::New(isolate_); 2221cb0ef41Sopenharmony_ci v8::Context::Scope context_scope(context); 2231cb0ef41Sopenharmony_ci AliasedBufferBase<uint32_t, v8::Uint32Array> ab{isolate_, 2}; 2241cb0ef41Sopenharmony_ci using Reference = AliasedBufferBase<uint32_t, v8::Uint32Array>::Reference; 2251cb0ef41Sopenharmony_ci Reference ref = ab[0]; 2261cb0ef41Sopenharmony_ci Reference ref_value = ab[1] = 2; 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(2), ref = ref_value); 2291cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(4), ref += ref_value); 2301cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(2), ref -= ref_value); 2311cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<uint32_t>(-2), -ref); 2321cb0ef41Sopenharmony_ci} 233