diff options
author | 2023-07-16 21:15:24 -0700 | |
---|---|---|
committer | 2023-07-16 21:15:24 -0700 | |
commit | 209dc981c0ef52de5c80eab5d24ec8a8eba765e8 (patch) | |
tree | c3d203d03d109161bcaf25558c05fda49c5e864e /src/bun.js/bindings/BunJSCModule.cpp | |
parent | 7fc392b182fa45d1fa33e654c2b4d1f1022a1ac3 (diff) | |
download | bun-209dc981c0ef52de5c80eab5d24ec8a8eba765e8.tar.gz bun-209dc981c0ef52de5c80eab5d24ec8a8eba765e8.tar.zst bun-209dc981c0ef52de5c80eab5d24ec8a8eba765e8.zip |
Implement Workers (#3645)
* copy files
* format
* options
* Introduce `Worker`, `onmessage`, `onerror`, and `postMessage` globals
* Stub `Worker.prototype.ref` & `Worker.prototype.unref`
* Update web_worker.zig
* Worker works
* Add "mini" mode
* add wakeup
* Partially fix the keep-alive issue
* clean up refer behavior
* Implement `serialize` & `deserialize` in `bun:jsc` & add polyfill for `node:v8`
* Types & docs
* Update globals.d.ts
* Add mutex
* Fixes
---------
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/bindings/BunJSCModule.cpp')
-rw-r--r-- | src/bun.js/bindings/BunJSCModule.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/bun.js/bindings/BunJSCModule.cpp b/src/bun.js/bindings/BunJSCModule.cpp index 5809a9813..a145f51c5 100644 --- a/src/bun.js/bindings/BunJSCModule.cpp +++ b/src/bun.js/bindings/BunJSCModule.cpp @@ -24,15 +24,19 @@ #include "JavaScriptCore/DeferTermination.h" #include "JavaScriptCore/SamplingProfiler.h" #include "JavaScriptCore/VMTrapsInlines.h" +#include "SerializedScriptValue.h" +#include "ExceptionOr.h" #if ENABLE(REMOTE_INSPECTOR) #include "JavaScriptCore/RemoteInspectorServer.h" #endif #include "mimalloc.h" +#include "JSDOMConvertBase.h" using namespace JSC; using namespace WTF; +using namespace WebCore; JSC_DECLARE_HOST_FUNCTION(functionStartRemoteDebugger); JSC_DEFINE_HOST_FUNCTION(functionStartRemoteDebugger, (JSGlobalObject * globalObject, CallFrame* callFrame)) @@ -525,6 +529,74 @@ JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshotForDebugging, (JSGlobalObje return JSValue::encode(JSONParse(globalObject, WTFMove(jsonString))); } +JSC_DEFINE_HOST_FUNCTION(functionSerialize, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto* globalObject = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject); + JSC::VM& vm = globalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + JSValue value = callFrame->argument(0); + JSValue optionsObject = callFrame->argument(1); + bool asNodeBuffer = false; + if (optionsObject.isObject()) { + JSC::JSObject* options = optionsObject.getObject(); + if (JSC::JSValue binaryTypeValue = options->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "binaryType"_s))) { + if (!binaryTypeValue.isString()) { + throwTypeError(globalObject, throwScope, "binaryType must be a string"_s); + return JSValue::encode(jsUndefined()); + } + + asNodeBuffer = binaryTypeValue.toWTFString(globalObject) == "nodebuffer"_s; + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + } + } + + Vector<JSC::Strong<JSC::JSObject>> transferList; + + ExceptionOr<Ref<SerializedScriptValue>> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList)); + + if (serialized.hasException()) { + WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); + return JSValue::encode(jsUndefined()); + } + + auto serializedValue = serialized.releaseReturnValue(); + auto arrayBuffer = serializedValue->toArrayBuffer(); + + if (asNodeBuffer) { + size_t byteLength = arrayBuffer->byteLength(); + JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, globalObject->JSBufferSubclassStructure(), WTFMove(arrayBuffer), 0, byteLength); + return JSValue::encode(uint8Array); + } + + if (arrayBuffer->isShared()) { + return JSValue::encode(JSArrayBuffer::create(vm, globalObject->arrayBufferStructureWithSharingMode<ArrayBufferSharingMode::Shared>(), WTFMove(arrayBuffer))); + } + + return JSValue::encode(JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(), WTFMove(arrayBuffer))); +} +JSC_DEFINE_HOST_FUNCTION(functionDeserialize, (JSGlobalObject * globalObject, CallFrame* callFrame)) +{ + JSC::VM& vm = globalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSValue value = callFrame->argument(0); + + JSValue result; + + if (auto* jsArrayBuffer = jsDynamicCast<JSArrayBuffer*>(value)) { + result = SerializedScriptValue::fromArrayBuffer(*globalObject, globalObject, jsArrayBuffer->impl(), 0, jsArrayBuffer->impl()->byteLength()); + } else if (auto* view = jsDynamicCast<JSArrayBufferView*>(value)) { + auto arrayBuffer = view->possiblySharedImpl()->possiblySharedBuffer(); + result = SerializedScriptValue::fromArrayBuffer(*globalObject, globalObject, arrayBuffer.get(), view->byteOffset(), view->byteLength()); + } else { + throwTypeError(globalObject, throwScope, "First argument must be an ArrayBuffer"_s); + return JSValue::encode(jsUndefined()); + } + + RETURN_IF_EXCEPTION(throwScope, JSValue::encode(jsUndefined())); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject) { VM& vm = globalObject->vm(); @@ -561,6 +633,8 @@ JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject) object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "generateHeapSnapshotForDebugging"_s), 0, functionGenerateHeapSnapshotForDebugging, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "profile"_s), 0, functionRunProfiler, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "setTimeZone"_s), 0, functionSetTimeZone, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); + object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "serialize"_s), 0, functionSerialize, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); + object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "deserialize"_s), 0, functionDeserialize, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); } return object; |