Skip to content

Commit 6114c98

Browse files
committed
Provide an API to expose Free function of ArrayBuffer
After deserialize the ArrayBuffer, the host needs to know how to free the underlying buffer. The exposed API will provide an way to tell how to free the underlying buffer.
1 parent 8bdfa5d commit 6114c98

File tree

9 files changed

+64
-5
lines changed

9 files changed

+64
-5
lines changed

bin/ch/ChakraRtInterface.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ bool ChakraRTInterface::LoadChakraDll(ArgInfo* argInfo, HINSTANCE *outLibrary)
199199
m_jsApiHooks.pfJsrtVarDeserializerFree = (JsAPIHooks::JsrtVarDeserializerFreePtr)GetChakraCoreSymbol(library, "JsVarDeserializerFree");
200200

201201
m_jsApiHooks.pfJsrtDetachArrayBuffer = (JsAPIHooks::JsrtDetachArrayBufferPtr)GetChakraCoreSymbol(library, "JsDetachArrayBuffer");
202+
m_jsApiHooks.pfJsrtGetArrayBufferFreeFunction = (JsAPIHooks::JsrtGetArrayBufferFreeFunction)GetChakraCoreSymbol(library, "JsGetArrayBufferFreeFunction");
202203

203204
#ifdef _WIN32
204205
m_jsApiHooks.pfJsrtConnectJITProcess = (JsAPIHooks::JsrtConnectJITProcess)GetChakraCoreSymbol(library, "JsConnectJITProcess");

bin/ch/ChakraRtInterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ struct JsAPIHooks
138138
typedef JsErrorCode(WINAPI *JsrtVarDeserializerFreePtr)(JsVarDeserializerHandle deserializerHandle);
139139

140140
typedef JsErrorCode(WINAPI *JsrtDetachArrayBufferPtr)(JsValueRef buffer);
141+
typedef JsErrorCode(WINAPI* JsrtGetArrayBufferFreeFunction)(JsValueRef buffer, ArrayBufferFreeFn** freeFn);
141142

142143
JsrtCreateRuntimePtr pfJsrtCreateRuntime;
143144
JsrtCreateContextPtr pfJsrtCreateContext;
@@ -268,6 +269,7 @@ struct JsAPIHooks
268269
JsrtVarDeserializerFreePtr pfJsrtVarDeserializerFree;
269270

270271
JsrtDetachArrayBufferPtr pfJsrtDetachArrayBuffer;
272+
JsrtGetArrayBufferFreeFunction pfJsrtGetArrayBufferFreeFunction;
271273
#ifdef _WIN32
272274
JsrtConnectJITProcess pfJsrtConnectJITProcess;
273275
#endif
@@ -509,6 +511,8 @@ class ChakraRTInterface
509511
#ifdef _WIN32
510512
static JsErrorCode WINAPI JsConnectJITProcess(HANDLE processHandle, void* serverSecurityDescriptor, UUID connectionId) { return HOOK_JS_API(ConnectJITProcess(processHandle, serverSecurityDescriptor, connectionId)); }
511513
#endif
514+
515+
static JsErrorCode WINAPI JsGetArrayBufferFreeFunction(JsValueRef buffer, ArrayBufferFreeFn** freeFn) { return HOOK_JS_API(GetArrayBufferFreeFunction(buffer, freeFn)); }
512516
};
513517

514518
class AutoRestoreContext

bin/ch/WScriptJsrt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ JsValueRef __stdcall WScriptJsrt::SerializeObject(JsValueRef callee, bool isCons
374374
BYTE *buffer = nullptr;
375375
uint32 bufferLength = 0;
376376
IfJsrtErrorSetGo(ChakraRTInterface::JsGetArrayBufferStorage(arrayBuffer, &buffer, &bufferLength));
377+
ArrayBufferFreeFn* freeFn = nullptr;
378+
IfJsrtErrorSetGo(ChakraRTInterface::JsGetArrayBufferFreeFunction(arrayBuffer, &freeFn));
379+
377380
blob->transferableArrays.push_back(std::make_pair((void*)buffer, bufferLength));
378381
IfJsrtErrorSetGo(ChakraRTInterface::JsDetachArrayBuffer(arrayBuffer));
379382
}

lib/Jsrt/ChakraCore.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,6 +1887,22 @@ CHAKRA_API
18871887
JsDetachArrayBuffer(
18881888
_In_ JsValueRef arrayBuffer);
18891889

1890+
typedef void __cdecl ArrayBufferFreeFn(void* ptr);
1891+
1892+
/// <summary>
1893+
/// Returns the function which free the underlying buffer of ArrayBuffer
1894+
/// </summary>
1895+
/// <param name="arrayBuffer">An ArrayBuffer for which Free function to be returned </param>
1896+
/// <param name="freeFn">Free function will be returned</param>
1897+
/// <returns>
1898+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code
1899+
/// otherwise.
1900+
/// </returns>
1901+
CHAKRA_API
1902+
JsGetArrayBufferFreeFunction(
1903+
_In_ JsValueRef arrayBuffer,
1904+
_Out_ ArrayBufferFreeFn** freeFn);
1905+
18901906

18911907
#ifdef _WIN32
18921908
#include "ChakraCoreWindows.h"

lib/Jsrt/Core/JsrtCore.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,3 +1442,21 @@ JsConnectJITProcess(_In_ HANDLE processHandle, _In_opt_ void* serverSecurityDesc
14421442
return JsNoError;
14431443
}
14441444
#endif
1445+
CHAKRA_API
1446+
JsGetArrayBufferFreeFunction(
1447+
_In_ JsValueRef arrayBuffer,
1448+
_Out_ ArrayBufferFreeFn** freeFn)
1449+
{
1450+
VALIDATE_JSREF(arrayBuffer);
1451+
PARAM_NOT_NULL(freeFn);
1452+
return ContextAPINoScriptWrapper_NoRecord(
1453+
[&](Js::ScriptContext* scriptContext) -> JsErrorCode {
1454+
if (!Js::VarIs<Js::ArrayBuffer>(arrayBuffer))
1455+
{
1456+
return JsErrorInvalidArgument;
1457+
}
1458+
1459+
*freeFn = (ArrayBufferFreeFn*)Js::VarTo<Js::ArrayBuffer>(arrayBuffer)->GetArrayBufferFreeFn();
1460+
return JsNoError;
1461+
});
1462+
}

lib/Jsrt/JsrtCommonExports.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,5 @@
168168
JsVarSerializerSetTransferableVars
169169
JsVarSerializerWriteRawBytes
170170
JsVarSerializerWriteValue
171+
JsGetArrayBufferFreeFunction
171172
#endif

lib/Runtime/Library/ArrayBuffer.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,20 @@ namespace Js
831831
return result;
832832
}
833833

834+
ArrayBuffer::FreeFn* JavascriptArrayBuffer::GetArrayBufferFreeFn()
835+
{
836+
#if ENABLE_FAST_ARRAYBUFFER
837+
if (IsValidVirtualBufferLength(bufferLength))
838+
{
839+
return FreeMemAlloc;
840+
}
841+
else
842+
#endif
843+
{
844+
return free;
845+
}
846+
}
847+
834848
ArrayBufferDetachedStateBase* JavascriptArrayBuffer::CreateDetachedState(RefCountedBuffer * content, uint32 bufferLength)
835849
{
836850
FreeFn* freeFn = nullptr;

lib/Runtime/Library/ArrayBuffer.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ namespace Js
205205
virtual BYTE* GetBuffer() const override;
206206
RefCountedBuffer *GetBufferContent() { return bufferContent; }
207207
static int GetBufferContentsOffset() { return offsetof(ArrayBuffer, bufferContent); }
208+
209+
typedef void __cdecl FreeFn(void* ptr);
210+
virtual FreeFn* GetArrayBufferFreeFn() { return nullptr; }
208211
static int GetByteLengthOffset() { return offsetof(ArrayBuffer, bufferLength); }
209212
virtual void AddParent(ArrayBufferParent* parent) override;
210213

@@ -230,7 +233,6 @@ namespace Js
230233
protected:
231234
virtual void ReportExternalMemoryFree();
232235

233-
typedef void __cdecl FreeFn(void* ptr);
234236
virtual ArrayBufferDetachedStateBase* CreateDetachedState(RefCountedBuffer * content, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength) = 0;
235237

236238
// This function will be called from External buffer and projection buffer as they pass the buffer
@@ -308,7 +310,9 @@ namespace Js
308310
virtual bool IsValidAsmJsBufferLength(uint length, bool forceCheck = false) override;
309311
virtual bool IsValidVirtualBufferLength(uint length) const override;
310312

311-
protected:
313+
virtual FreeFn* GetArrayBufferFreeFn() override;
314+
315+
protected:
312316
JavascriptArrayBuffer(DynamicType * type);
313317
virtual ArrayBufferDetachedStateBase* CreateDetachedState(RefCountedBuffer * content, DECLSPEC_GUARD_OVERFLOW uint32 bufferLength) override;
314318

lib/SCACore/SCAEngine.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@ namespace Js
136136
AssertMsg(index < this->m_cTransferableVars, "Index out of range.");
137137
ArrayBuffer *ab = VarTo<ArrayBuffer>(m_transferableVars[index]);
138138

139-
// TODO reuse the same ArrayBuffer instead of creating a new ArrayBuffer.
140-
// Current ArrayBuffer's from m_transferableVars are JsrtExternalArrayBuffer.
141-
return library->CreateArrayBuffer((byte*)ab->GetBuffer(), ab->GetByteLength());
139+
return ab;
142140
}
143141

144142
static Dst Clone(Src root, Cloner* cloner, Var* transferableVars, size_t cTransferableVars)

0 commit comments

Comments
 (0)