| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 05eae28 commit 6d14279
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1360,37 +1360,93 @@ void FastSwap64(Local<Value> receiver, | |||
| 1360 | 1360 | ||
| 1361 | 1361 | static CFunction fast_swap64(CFunction::Make(FastSwap64)); | |
| 1362 | 1362 | ||
| 1363 | + struct ValidationResult { | ||
| 1364 | + bool is_valid; | ||
| 1365 | + bool was_detached; | ||
| 1366 | + }; | ||
| 1367 | + | ||
| 1368 | + static ValidationResult ValidateUtf8(Local<Value> value) { | ||
| 1369 | + ArrayBufferViewContents<char> abv(value); | ||
| 1370 | + bool was_detached = abv.WasDetached(); | ||
| 1371 | + return {!was_detached && simdutf::validate_utf8(abv.data(), abv.length()), | ||
| 1372 | + was_detached}; | ||
| 1373 | + } | ||
| 1374 | + | ||
| 1363 | 1375 | static void IsUtf8(const FunctionCallbackInfo<Value>& args) { | |
| 1364 | 1376 | Environment* env = Environment::GetCurrent(args); | |
| 1365 | 1377 | CHECK_EQ(args.Length(), 1); | |
| 1366 | 1378 | CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() || | |
| 1367 | 1379 | args[0]->IsSharedArrayBuffer()); | |
| 1368 | - ArrayBufferViewContents<char> abv(args[0]); | ||
| 1369 | 1380 | ||
| 1370 | - if (abv.WasDetached()) { | ||
| 1381 | + const ValidationResult result = ValidateUtf8(args[0]); | ||
| 1382 | + if (result.was_detached) { | ||
| 1371 | 1383 | return node::THROW_ERR_INVALID_STATE( | |
| 1372 | 1384 | env, "Cannot validate on a detached buffer"); | |
| 1373 | 1385 | } | |
| 1374 | 1386 | ||
| 1375 | - args.GetReturnValue().Set(simdutf::validate_utf8(abv.data(), abv.length())); | ||
| 1387 | + args.GetReturnValue().Set(result.is_valid); | ||
| 1388 | + } | ||
| 1389 | + | ||
| 1390 | + static bool FastIsUtf8(Local<Value> receiver, | ||
| 1391 | + Local<Value> value, | ||
| 1392 | + // NOLINTNEXTLINE(runtime/references) | ||
| 1393 | + FastApiCallbackOptions& options) { | ||
| 1394 | + TRACK_V8_FAST_API_CALL("buffer.isUtf8"); | ||
| 1395 | + HandleScope scope(options.isolate); | ||
| 1396 | + | ||
| 1397 | + const ValidationResult result = ValidateUtf8(value); | ||
| 1398 | + if (result.was_detached) { | ||
| 1399 | + node::THROW_ERR_INVALID_STATE(options.isolate, | ||
| 1400 | + "Cannot validate on a detached buffer"); | ||
| 1401 | + return false; | ||
| 1402 | + } | ||
| 1403 | + return result.is_valid; | ||
| 1404 | + } | ||
| 1405 | + | ||
| 1406 | + static CFunction fast_is_utf8(CFunction::Make(FastIsUtf8)); | ||
| 1407 | + | ||
| 1408 | + static ValidationResult ValidateAscii(Local<Value> value) { | ||
| 1409 | + ArrayBufferViewContents<char> abv(value); | ||
| 1410 | + bool was_detached = abv.WasDetached(); | ||
| 1411 | + return { | ||
| 1412 | + !was_detached && | ||
| 1413 | + !simdutf::validate_ascii_with_errors(abv.data(), abv.length()).error, | ||
| 1414 | + was_detached}; | ||
| 1376 | 1415 | } | |
| 1377 | 1416 | ||
| 1378 | 1417 | static void IsAscii(const FunctionCallbackInfo<Value>& args) { | |
| 1379 | 1418 | Environment* env = Environment::GetCurrent(args); | |
| 1380 | 1419 | CHECK_EQ(args.Length(), 1); | |
| 1381 | 1420 | CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() || | |
| 1382 | 1421 | args[0]->IsSharedArrayBuffer()); | |
| 1383 | - ArrayBufferViewContents<char> abv(args[0]); | ||
| 1384 | 1422 | ||
| 1385 | - if (abv.WasDetached()) { | ||
| 1423 | + const ValidationResult result = ValidateAscii(args[0]); | ||
| 1424 | + if (result.was_detached) { | ||
| 1386 | 1425 | return node::THROW_ERR_INVALID_STATE( | |
| 1387 | 1426 | env, "Cannot validate on a detached buffer"); | |
| 1388 | 1427 | } | |
| 1389 | 1428 | ||
| 1390 | - args.GetReturnValue().Set( | ||
| 1391 | - !simdutf::validate_ascii_with_errors(abv.data(), abv.length()).error); | ||
| 1429 | + args.GetReturnValue().Set(result.is_valid); | ||
| 1392 | 1430 | } | |
| 1393 | 1431 | ||
| 1432 | + static bool FastIsAscii(Local<Value> receiver, | ||
| 1433 | + Local<Value> value, | ||
| 1434 | + // NOLINTNEXTLINE(runtime/references) | ||
| 1435 | + FastApiCallbackOptions& options) { | ||
| 1436 | + TRACK_V8_FAST_API_CALL("buffer.isAscii"); | ||
| 1437 | + HandleScope scope(options.isolate); | ||
| 1438 | + | ||
| 1439 | + const ValidationResult result = ValidateAscii(value); | ||
| 1440 | + if (result.was_detached) { | ||
| 1441 | + node::THROW_ERR_INVALID_STATE(options.isolate, | ||
| 1442 | + "Cannot validate on a detached buffer"); | ||
| 1443 | + return false; | ||
| 1444 | + } | ||
| 1445 | + return result.is_valid; | ||
| 1446 | + } | ||
| 1447 | + | ||
| 1448 | + static CFunction fast_is_ascii(CFunction::Make(FastIsAscii)); | ||
| 1449 | + | ||
| 1394 | 1450 | void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) { | |
| 1395 | 1451 | Realm* realm = Realm::GetCurrent(args); | |
| 1396 | 1452 | ||
@@ -1762,8 +1818,9 @@ void Initialize(Local<Object> target, | |||
| 1762 | 1818 | SetFastMethod(context, target, "swap32", Swap32, &fast_swap32); | |
| 1763 | 1819 | SetFastMethod(context, target, "swap64", Swap64, &fast_swap64); | |
| 1764 | 1820 | ||
| 1765 | - SetMethodNoSideEffect(context, target, "isUtf8", IsUtf8); | ||
| 1766 | - SetMethodNoSideEffect(context, target, "isAscii", IsAscii); | ||
| 1821 | + SetFastMethodNoSideEffect(context, target, "isUtf8", IsUtf8, &fast_is_utf8); | ||
| 1822 | + SetFastMethodNoSideEffect( | ||
| 1823 | + context, target, "isAscii", IsAscii, &fast_is_ascii); | ||
| 1767 | 1824 | ||
| 1768 | 1825 | target | |
| 1769 | 1826 | ->Set(context, | |
@@ -1836,7 +1893,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |||
| 1836 | 1893 | registry->Register(fast_swap64); | |
| 1837 | 1894 | ||
| 1838 | 1895 | registry->Register(IsUtf8); | |
| 1896 | + registry->Register(fast_is_utf8); | ||
| 1839 | 1897 | registry->Register(IsAscii); | |
| 1898 | + registry->Register(fast_is_ascii); | ||
| 1840 | 1899 | ||
| 1841 | 1900 | registry->Register(StringSlice<ASCII>); | |
| 1842 | 1901 | registry->Register(StringSlice<BASE64>); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,34 @@ | |||
| 1 | + // Flags: --expose-internals --no-warnings --allow-natives-syntax | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + const { Buffer, isAscii, isUtf8 } = require('buffer'); | ||
| 7 | + | ||
| 8 | + const ascii = Buffer.from('hello'); | ||
| 9 | + const utf8 = Buffer.from('hello \xc4\x9f'); | ||
| 10 | + | ||
| 11 | + function testFastIsAscii() { | ||
| 12 | + assert.strictEqual(isAscii(ascii), true); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + function testFastIsUtf8() { | ||
| 16 | + assert.strictEqual(isUtf8(utf8), true); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + eval('%PrepareFunctionForOptimization(isAscii)'); | ||
| 20 | + testFastIsAscii(); | ||
| 21 | + eval('%OptimizeFunctionOnNextCall(isAscii)'); | ||
| 22 | + testFastIsAscii(); | ||
| 23 | + | ||
| 24 | + eval('%PrepareFunctionForOptimization(isUtf8)'); | ||
| 25 | + testFastIsUtf8(); | ||
| 26 | + eval('%OptimizeFunctionOnNextCall(isUtf8)'); | ||
| 27 | + testFastIsUtf8(); | ||
| 28 | + | ||
| 29 | + if (common.isDebug) { | ||
| 30 | + const { internalBinding } = require('internal/test/binding'); | ||
| 31 | + const { getV8FastApiCallCount } = internalBinding('debug'); | ||
| 32 | + assert.strictEqual(getV8FastApiCallCount('buffer.isAscii'), 1); | ||
| 33 | + assert.strictEqual(getV8FastApiCallCount('buffer.isUtf8'), 1); | ||
| 34 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments