mirror of
https://github.com/oven-sh/bun
synced 2026-02-14 21:01:52 +00:00
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
20
bench/snippets/webcrypto.mjs
Normal file
20
bench/snippets/webcrypto.mjs
Normal file
@@ -0,0 +1,20 @@
|
||||
import { group } from "mitata";
|
||||
import { bench, run } from "./runner.mjs";
|
||||
|
||||
const sizes = [
|
||||
["small (63 bytes)", 63],
|
||||
["medium (4096 bytes)", 4096],
|
||||
["large (64 MB)", 64 * 1024 * 1024],
|
||||
];
|
||||
for (let [name, size] of sizes) {
|
||||
group(name, () => {
|
||||
var buf = new Uint8Array(size);
|
||||
for (let algorithm of ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]) {
|
||||
bench(algorithm, async () => {
|
||||
await crypto.subtle.digest(algorithm, buf);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await run();
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "webcore/WebSocket.h"
|
||||
#include "libusockets.h"
|
||||
#include "_libusockets.h"
|
||||
#include "BunClientData.h"
|
||||
|
||||
extern "C" void Bun__startLoop(us_loop_t* loop);
|
||||
|
||||
@@ -58,6 +59,16 @@ us_socket_context_t* ScriptExecutionContext::webSocketContextSSL()
|
||||
|
||||
return m_ssl_client_websockets_ctx;
|
||||
}
|
||||
extern "C" void Bun__eventLoop__incrementRefConcurrently(void* bunVM, int delta);
|
||||
|
||||
void ScriptExecutionContext::refEventLoop()
|
||||
{
|
||||
Bun__eventLoop__incrementRefConcurrently(WebCore::clientData(vm())->bunVM, 1);
|
||||
}
|
||||
void ScriptExecutionContext::unrefEventLoop()
|
||||
{
|
||||
Bun__eventLoop__incrementRefConcurrently(WebCore::clientData(vm())->bunVM, -1);
|
||||
}
|
||||
|
||||
bool ScriptExecutionContext::postTaskTo(ScriptExecutionContextIdentifier identifier, Function<void(ScriptExecutionContext&)>&& task)
|
||||
{
|
||||
|
||||
@@ -107,6 +107,8 @@ public:
|
||||
}
|
||||
|
||||
static ScriptExecutionContext* getScriptExecutionContext(ScriptExecutionContextIdentifier identifier);
|
||||
void refEventLoop();
|
||||
void unrefEventLoop();
|
||||
|
||||
const WTF::URL& url() const
|
||||
{
|
||||
|
||||
@@ -95,10 +95,12 @@ ExceptionOr<size_t> CryptoAlgorithm::getKeyLength(const CryptoAlgorithmParameter
|
||||
template<typename ResultCallbackType, typename OperationType>
|
||||
static void dispatchAlgorithmOperation(WorkQueue& workQueue, ScriptExecutionContext& context, ResultCallbackType&& callback, CryptoAlgorithm::ExceptionCallback&& exceptionCallback, OperationType&& operation)
|
||||
{
|
||||
context.refEventLoop();
|
||||
workQueue.dispatch(
|
||||
[operation = WTFMove(operation), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback), contextIdentifier = context.identifier()]() mutable {
|
||||
auto result = operation();
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [result = crossThreadCopy(WTFMove(result)), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](auto&) mutable {
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [result = crossThreadCopy(WTFMove(result)), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback)](auto& context) mutable {
|
||||
context.unrefEventLoop();
|
||||
if (result.hasException()) {
|
||||
exceptionCallback(result.releaseException().code());
|
||||
return;
|
||||
|
||||
@@ -51,10 +51,23 @@ void CryptoAlgorithmSHA1::digest(Vector<uint8_t>&& message, VectorCallback&& cal
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.size() < 64) {
|
||||
auto moved = WTFMove(message);
|
||||
digest->addBytes(moved.data(), moved.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(context.identifier(), [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
callback(result);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
context.refEventLoop();
|
||||
|
||||
workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
|
||||
digest->addBytes(message.data(), message.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto& context) {
|
||||
context.unrefEventLoop();
|
||||
callback(result);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,10 +51,22 @@ void CryptoAlgorithmSHA224::digest(Vector<uint8_t>&& message, VectorCallback&& c
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.size() < 64) {
|
||||
auto moved = WTFMove(message);
|
||||
digest->addBytes(moved.data(), moved.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(context.identifier(), [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
callback(result);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
context.refEventLoop();
|
||||
workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
|
||||
digest->addBytes(message.data(), message.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto& context) {
|
||||
context.unrefEventLoop();
|
||||
callback(result);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,10 +51,21 @@ void CryptoAlgorithmSHA256::digest(Vector<uint8_t>&& message, VectorCallback&& c
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.size() < 64) {
|
||||
auto moved = WTFMove(message);
|
||||
digest->addBytes(moved.data(), moved.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(context.identifier(), [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
callback(result);
|
||||
});
|
||||
return;
|
||||
}
|
||||
context.refEventLoop();
|
||||
workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
|
||||
digest->addBytes(message.data(), message.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto& context) {
|
||||
context.unrefEventLoop();
|
||||
callback(result);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,10 +51,23 @@ void CryptoAlgorithmSHA384::digest(Vector<uint8_t>&& message, VectorCallback&& c
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.size() < 64) {
|
||||
auto moved = WTFMove(message);
|
||||
digest->addBytes(moved.data(), moved.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(context.identifier(), [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
callback(result);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
context.refEventLoop();
|
||||
|
||||
workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
|
||||
digest->addBytes(message.data(), message.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto& context) {
|
||||
context.unrefEventLoop();
|
||||
callback(result);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,10 +51,23 @@ void CryptoAlgorithmSHA512::digest(Vector<uint8_t>&& message, VectorCallback&& c
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.size() < 64) {
|
||||
auto moved = WTFMove(message);
|
||||
digest->addBytes(moved.data(), moved.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(context.identifier(), [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
callback(result);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
context.refEventLoop();
|
||||
workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), contextIdentifier = context.identifier()]() mutable {
|
||||
digest->addBytes(message.data(), message.size());
|
||||
auto result = digest->computeHash();
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto&) {
|
||||
|
||||
ScriptExecutionContext::postTaskTo(contextIdentifier, [callback = WTFMove(callback), result = WTFMove(result)](auto& context) {
|
||||
context.unrefEventLoop();
|
||||
callback(result);
|
||||
});
|
||||
});
|
||||
|
||||
12
test/js/web/crypto/keeps-alive-fixture.js
Normal file
12
test/js/web/crypto/keeps-alive-fixture.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const algorithms = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"];
|
||||
const data = [
|
||||
"Hello World!",
|
||||
"Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!",
|
||||
];
|
||||
for (let bytes of data) {
|
||||
for (const algorithm of algorithms) {
|
||||
crypto.subtle.digest(algorithm, Buffer.from(bytes)).then(data => {
|
||||
console.log(Buffer.from(data).toString("hex"));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,31 @@
|
||||
import { spawnSync } from "bun";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { bunEnv, bunExe } from "harness";
|
||||
|
||||
describe("Web Crypto", () => {
|
||||
// https://github.com/oven-sh/bun/issues/3795
|
||||
it("keeps event loop alive", () => {
|
||||
const { stdout, exitCode } = spawnSync({
|
||||
cmd: [bunExe(), import.meta.resolveSync("./keeps-alive-fixture.js")],
|
||||
env: bunEnv,
|
||||
});
|
||||
|
||||
const lines = stdout.toString().trim().split("\n").sort();
|
||||
const results = [
|
||||
"2ef7bde608ce5404e97d5f042f95f89f1c232871",
|
||||
"6b3e626d70787e3dc3f0bca509a7e1e5f6802643fde54a18d4353aa9b24ccb2fb874bbc8a70ff587df2bd6ed41471f82",
|
||||
"7dc2af5ef620a4b1c8871371526b664512b82193",
|
||||
"7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
|
||||
"861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c729743371015ead891cc3cf1c9d34b49264b510751b1ff9e537937bc46b5d6ff4ecc8",
|
||||
"bf6873609ce720ec489bb2f5ae116716058c06cda7dc9a7e1dadee90da98e71aee22519505af61adbecd5b94bbefa855c2ede623e8b383bb179b150e25861441",
|
||||
"bfd76c0ebbd006fee583410547c1887b0292be76d582d96c242d2a792723e3fd6fd061f9d5cfd13b8f961358e6adba4a",
|
||||
"e1061f7858d68c3818ec9967ea1f7bf8e3c65f5603af95004bdfcb64b9ea4148",
|
||||
];
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(lines).toStrictEqual(results);
|
||||
});
|
||||
|
||||
it("has globals", () => {
|
||||
expect(crypto.subtle !== undefined).toBe(true);
|
||||
expect(CryptoKey.name).toBe("CryptoKey");
|
||||
|
||||
Reference in New Issue
Block a user