| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d3073a7 commit 081c41e
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1261,37 +1261,93 @@ void FastSwap64(Local<Value> receiver, | |||
| 1261 | 1261 | ||
| 1262 | 1262 | static CFunction fast_swap64(CFunction::Make(FastSwap64)); | |
| 1263 | 1263 | ||
| 1264 | + struct ValidationResult { | ||
| 1265 | + bool is_valid; | ||
| 1266 | + bool was_detached; | ||
| 1267 | + }; | ||
| 1268 | + | ||
| 1269 | + static ValidationResult ValidateUtf8(Local<Value> value) { | ||
| 1270 | + ArrayBufferViewContents<char> abv(value); | ||
| 1271 | + bool was_detached = abv.WasDetached(); | ||
| 1272 | + return {!was_detached && simdutf::validate_utf8(abv.data(), abv.length()), | ||
| 1273 | + was_detached}; | ||
| 1274 | + } | ||
| 1275 | + | ||
| 1264 | 1276 | static void IsUtf8(const FunctionCallbackInfo<Value>& args) { | |
| 1265 | 1277 | Environment* env = Environment::GetCurrent(args); | |
| 1266 | 1278 | CHECK_EQ(args.Length(), 1); | |
| 1267 | 1279 | CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() || | |
| 1268 | 1280 | args[0]->IsSharedArrayBuffer()); | |
| 1269 | - ArrayBufferViewContents<char> abv(args[0]); | ||
| 1270 | 1281 | ||
| 1271 | - if (abv.WasDetached()) { | ||
| 1282 | + const ValidationResult result = ValidateUtf8(args[0]); | ||
| 1283 | + if (result.was_detached) { | ||
| 1272 | 1284 | return node::THROW_ERR_INVALID_STATE( | |
| 1273 | 1285 | env, "Cannot validate on a detached buffer"); | |
| 1274 | 1286 | } | |
| 1275 | 1287 | ||
| 1276 | - args.GetReturnValue().Set(simdutf::validate_utf8(abv.data(), abv.length())); | ||
| 1288 | + args.GetReturnValue().Set(result.is_valid); | ||
| 1289 | + } | ||
| 1290 | + | ||
| 1291 | + static bool FastIsUtf8(Local<Value> receiver, | ||
| 1292 | + Local<Value> value, | ||
| 1293 | + // NOLINTNEXTLINE(runtime/references) | ||
| 1294 | + FastApiCallbackOptions& options) { | ||
| 1295 | + TRACK_V8_FAST_API_CALL("buffer.isUtf8"); | ||
| 1296 | + HandleScope scope(options.isolate); | ||
| 1297 | + | ||
| 1298 | + const ValidationResult result = ValidateUtf8(value); | ||
| 1299 | + if (result.was_detached) { | ||
| 1300 | + node::THROW_ERR_INVALID_STATE(options.isolate, | ||
| 1301 | + "Cannot validate on a detached buffer"); | ||
| 1302 | + return false; | ||
| 1303 | + } | ||
| 1304 | + return result.is_valid; | ||
| 1305 | + } | ||
| 1306 | + | ||
| 1307 | + static CFunction fast_is_utf8(CFunction::Make(FastIsUtf8)); | ||
| 1308 | + | ||
| 1309 | + static ValidationResult ValidateAscii(Local<Value> value) { | ||
| 1310 | + ArrayBufferViewContents<char> abv(value); | ||
| 1311 | + bool was_detached = abv.WasDetached(); | ||
| 1312 | + return { | ||
| 1313 | + !was_detached && | ||
| 1314 | + !simdutf::validate_ascii_with_errors(abv.data(), abv.length()).error, | ||
| 1315 | + was_detached}; | ||
| 1277 | 1316 | } | |
| 1278 | 1317 | ||
| 1279 | 1318 | static void IsAscii(const FunctionCallbackInfo<Value>& args) { | |
| 1280 | 1319 | Environment* env = Environment::GetCurrent(args); | |
| 1281 | 1320 | CHECK_EQ(args.Length(), 1); | |
| 1282 | 1321 | CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() || | |
| 1283 | 1322 | args[0]->IsSharedArrayBuffer()); | |
| 1284 | - ArrayBufferViewContents<char> abv(args[0]); | ||
| 1285 | 1323 | ||
| 1286 | - if (abv.WasDetached()) { | ||
| 1324 | + const ValidationResult result = ValidateAscii(args[0]); | ||
| 1325 | + if (result.was_detached) { | ||
| 1287 | 1326 | return node::THROW_ERR_INVALID_STATE( | |
| 1288 | 1327 | env, "Cannot validate on a detached buffer"); | |
| 1289 | 1328 | } | |
| 1290 | 1329 | ||
| 1291 | - args.GetReturnValue().Set( | ||
| 1292 | - !simdutf::validate_ascii_with_errors(abv.data(), abv.length()).error); | ||
| 1330 | + args.GetReturnValue().Set(result.is_valid); | ||
| 1293 | 1331 | } | |
| 1294 | 1332 | ||
| 1333 | + static bool FastIsAscii(Local<Value> receiver, | ||
| 1334 | + Local<Value> value, | ||
| 1335 | + // NOLINTNEXTLINE(runtime/references) | ||
| 1336 | + FastApiCallbackOptions& options) { | ||
| 1337 | + TRACK_V8_FAST_API_CALL("buffer.isAscii"); | ||
| 1338 | + HandleScope scope(options.isolate); | ||
| 1339 | + | ||
| 1340 | + const ValidationResult result = ValidateAscii(value); | ||
| 1341 | + if (result.was_detached) { | ||
| 1342 | + node::THROW_ERR_INVALID_STATE(options.isolate, | ||
| 1343 | + "Cannot validate on a detached buffer"); | ||
| 1344 | + return false; | ||
| 1345 | + } | ||
| 1346 | + return result.is_valid; | ||
| 1347 | + } | ||
| 1348 | + | ||
| 1349 | + static CFunction fast_is_ascii(CFunction::Make(FastIsAscii)); | ||
| 1350 | + | ||
| 1295 | 1351 | void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) { | |
| 1296 | 1352 | Realm* realm = Realm::GetCurrent(args); | |
| 1297 | 1353 | ||
@@ -1663,8 +1719,9 @@ void Initialize(Local<Object> target, | |||
| 1663 | 1719 | SetFastMethod(context, target, "swap32", Swap32, &fast_swap32); | |
| 1664 | 1720 | SetFastMethod(context, target, "swap64", Swap64, &fast_swap64); | |
| 1665 | 1721 | ||
| 1666 | - SetMethodNoSideEffect(context, target, "isUtf8", IsUtf8); | ||
| 1667 | - SetMethodNoSideEffect(context, target, "isAscii", IsAscii); | ||
| 1722 | + SetFastMethodNoSideEffect(context, target, "isUtf8", IsUtf8, &fast_is_utf8); | ||
| 1723 | + SetFastMethodNoSideEffect( | ||
| 1724 | + context, target, "isAscii", IsAscii, &fast_is_ascii); | ||
| 1668 | 1725 | ||
| 1669 | 1726 | target | |
| 1670 | 1727 | ->Set(context, | |
@@ -1737,7 +1794,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |||
| 1737 | 1794 | registry->Register(fast_swap64); | |
| 1738 | 1795 | ||
| 1739 | 1796 | registry->Register(IsUtf8); | |
| 1797 | + registry->Register(fast_is_utf8); | ||
| 1740 | 1798 | registry->Register(IsAscii); | |
| 1799 | + registry->Register(fast_is_ascii); | ||
| 1741 | 1800 | ||
| 1742 | 1801 | registry->Register(StringSlice<ASCII>); | |
| 1743 | 1802 | 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