aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/BunJSCModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/bindings/BunJSCModule.cpp')
-rw-r--r--src/bun.js/bindings/BunJSCModule.cpp74
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;