From 90d8ddd2bc478cd1d5d599af27a301ed49c4b4c6 Mon Sep 17 00:00:00 2001 From: Kyle Farnung Date: Mon, 31 Jul 2017 15:13:58 -0700 Subject: [PATCH 1/2] Add JsGetDataViewInfo support Match the existing JsGetTypedArrayInfo signature in order to support making similar queries for DataViews. --- lib/Jsrt/ChakraCore.h | 17 ++++++++++++ lib/Jsrt/Jsrt.cpp | 40 ++++++++++++++++++++++++++++ lib/Jsrt/JsrtCommonExports.inc | 1 + lib/Runtime/Debug/TTActionEvents.cpp | 16 +++++++++++ lib/Runtime/Debug/TTActionEvents.h | 1 + lib/Runtime/Debug/TTEventLog.cpp | 10 +++++++ lib/Runtime/Debug/TTEventLog.h | 1 + lib/Runtime/Debug/TTEvents.h | 3 ++- 8 files changed, 88 insertions(+), 1 deletion(-) diff --git a/lib/Jsrt/ChakraCore.h b/lib/Jsrt/ChakraCore.h index 47eec84bfb9..0bbc279a843 100644 --- a/lib/Jsrt/ChakraCore.h +++ b/lib/Jsrt/ChakraCore.h @@ -733,5 +733,22 @@ JsCopyStringOneByte( _Out_opt_ char* buffer, _Out_opt_ size_t* written); +/// +/// Obtains frequently used properties of a data view. +/// +/// The data view instance. +/// The ArrayBuffer backstore of the view. +/// The offset in bytes from the start of arrayBuffer referenced by the array. +/// The number of bytes in the array. +/// +/// The code JsNoError if the operation succeeded, a failure code otherwise. +/// +CHAKRA_API + JsGetDataViewInfo( + _In_ JsValueRef dataView, + _Out_opt_ JsValueRef *arrayBuffer, + _Out_opt_ unsigned int *byteOffset, + _Out_opt_ unsigned int *byteLength); + #endif // _CHAKRACOREBUILD #endif // _CHAKRACORE_H_ diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp index 05f2fe77f41..484398bcc7a 100644 --- a/lib/Jsrt/Jsrt.cpp +++ b/lib/Jsrt/Jsrt.cpp @@ -4781,4 +4781,44 @@ CHAKRA_API JsCopyStringOneByte( }); } +CHAKRA_API JsGetDataViewInfo( + _In_ JsValueRef dataView, + _Out_opt_ JsValueRef *arrayBuffer, + _Out_opt_ unsigned int *byteOffset, + _Out_opt_ unsigned int *byteLength) +{ + VALIDATE_JSREF(dataView); + + BEGIN_JSRT_NO_EXCEPTION + { + if (!Js::DataView::Is(dataView)) + { + RETURN_NO_EXCEPTION(JsErrorInvalidArgument); + } + + Js::DataView* dv = Js::DataView::FromVar(dataView); + if (arrayBuffer != nullptr) { + *arrayBuffer = dv->GetArrayBuffer(); + } + + if (byteOffset != nullptr) { + *byteOffset = dv->GetByteOffset(); + } + + if (byteLength != nullptr) { + *byteLength = dv->GetLength(); + } + } + +#if ENABLE_TTD + Js::ScriptContext* scriptContext = Js::RecyclableObject::FromVar(dataView)->GetScriptContext(); + if(PERFORM_JSRT_TTD_RECORD_ACTION_CHECK(scriptContext) && arrayBuffer != nullptr) + { + scriptContext->GetThreadContext()->TTDLog->RecordJsRTGetDataViewInfo(dataView, *arrayBuffer); + } +#endif + + END_JSRT_NO_EXCEPTION +} + #endif // _CHAKRACOREBUILD diff --git a/lib/Jsrt/JsrtCommonExports.inc b/lib/Jsrt/JsrtCommonExports.inc index 897a82fc6b4..c10e758521d 100644 --- a/lib/Jsrt/JsrtCommonExports.inc +++ b/lib/Jsrt/JsrtCommonExports.inc @@ -121,4 +121,5 @@ JsGetAndClearExceptionWithMetadata JsHasOwnProperty JsCopyStringOneByte + JsGetDataViewInfo #endif diff --git a/lib/Runtime/Debug/TTActionEvents.cpp b/lib/Runtime/Debug/TTActionEvents.cpp index d97b48dcf0c..060c2aadd7c 100644 --- a/lib/Runtime/Debug/TTActionEvents.cpp +++ b/lib/Runtime/Debug/TTActionEvents.cpp @@ -5,6 +5,8 @@ #include "RuntimeDebugPch.h" #include "Library/JavascriptExceptionMetadata.h" +#include "Common/ByteSwap.h" +#include "Library/DataView.h" #if ENABLE_TTD @@ -719,6 +721,20 @@ namespace TTD JsRTActionHandleResultForReplay(executeContext, evt, res); } + void GetDataViewInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext) + { + const JsRTSingleVarArgumentAction* action = GetInlineEventDataAs(evt); + Js::Var var = InflateVarInReplay(executeContext, GetVarItem_0(action)); + + Js::DataView* dataView = Js::DataView::FromVar(var); + Js::Var res = dataView->GetArrayBuffer(); + + //Need additional notify since JsRTActionHandleResultForReplay may allocate but GetDataViewInfo does not enter runtime + //Failure will kick all the way out to replay loop -- which is what we want + AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_OutOfMemory); + JsRTActionHandleResultForReplay(executeContext, evt, res); + } + ////////////////// void JsRTRawBufferCopyAction_Emit(const EventLogEntry* evt, FileWriter* writer, ThreadContext* threadContext) diff --git a/lib/Runtime/Debug/TTActionEvents.h b/lib/Runtime/Debug/TTActionEvents.h index f7ee16f637a..14b00f931a4 100644 --- a/lib/Runtime/Debug/TTActionEvents.h +++ b/lib/Runtime/Debug/TTActionEvents.h @@ -509,6 +509,7 @@ namespace TTD void SetIndexAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext); void GetTypedArrayInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext); + void GetDataViewInfoAction_Execute(const EventLogEntry* evt, ThreadContextTTD* executeContext); ////////////////// diff --git a/lib/Runtime/Debug/TTEventLog.cpp b/lib/Runtime/Debug/TTEventLog.cpp index 945817e3e80..003e82096bc 100644 --- a/lib/Runtime/Debug/TTEventLog.cpp +++ b/lib/Runtime/Debug/TTEventLog.cpp @@ -562,6 +562,7 @@ namespace TTD TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(SetIndexActionTag, ContextAPIWrapper, JsRTTrippleVarArgumentAction, SetIndexAction_Execute); TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetTypedArrayInfoActionTag, None, JsRTSingleVarArgumentAction, GetTypedArrayInfoAction_Execute); + TTD_CREATE_EVENTLIST_VTABLE_ENTRY_COMMON(GetDataViewInfoActionTag, None, JsRTSingleVarArgumentAction, GetDataViewInfoAction_Execute); TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RawBufferCopySync, ContextAPIWrapper, JsRTRawBufferCopyAction, NSLogEvents::RawBufferCopySync_Execute, nullptr, NSLogEvents::JsRTRawBufferCopyAction_Emit, NSLogEvents::JsRTRawBufferCopyAction_Parse); TTD_CREATE_EVENTLIST_VTABLE_ENTRY(RawBufferModifySync, ContextAPIWrapper, JsRTRawBufferModifyAction, NSLogEvents::RawBufferModifySync_Execute, NSLogEvents::JsRTRawBufferModifyAction_UnloadEventMemory, NSLogEvents::JsRTRawBufferModifyAction_Emit, NSLogEvents::JsRTRawBufferModifyAction_Parse); @@ -2343,6 +2344,15 @@ namespace TTD giAction->Result = TTD_CONVERT_JSVAR_TO_TTDVAR(result); } + void EventLog::RecordJsRTGetDataViewInfo(Js::Var var, Js::Var result) + { + NSLogEvents::JsRTSingleVarArgumentAction* giAction = this->RecordGetInitializedEvent_DataOnly(); + NSLogEvents::SetVarItem_0(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var)); + + //entry/exit status should be set to clead by initialization so don't need to do anything + giAction->Result = TTD_CONVERT_JSVAR_TO_TTDVAR(result); + } + void EventLog::RecordJsRTRawBufferCopySync(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 dstIndex, Js::Var src, uint32 srcIndex, uint32 length) { TTDAssert(Js::ArrayBuffer::Is(dst) && Js::ArrayBuffer::Is(src), "Not array buffer objects!!!"); diff --git a/lib/Runtime/Debug/TTEventLog.h b/lib/Runtime/Debug/TTEventLog.h index 7baf66d2698..b0f7b1775a7 100644 --- a/lib/Runtime/Debug/TTEventLog.h +++ b/lib/Runtime/Debug/TTEventLog.h @@ -581,6 +581,7 @@ namespace TTD //Record a get info from a typed array void RecordJsRTGetTypedArrayInfo(Js::Var var, Js::Var result); + void RecordJsRTGetDataViewInfo(Js::Var var, Js::Var result); //Record various raw byte* from ArrayBuffer manipulations void RecordJsRTRawBufferCopySync(TTDJsRTActionResultAutoRecorder& actionPopper, Js::Var dst, uint32 dstIndex, Js::Var src, uint32 srcIndex, uint32 length); diff --git a/lib/Runtime/Debug/TTEvents.h b/lib/Runtime/Debug/TTEvents.h index f5fd419b9c3..bcf7703f2b5 100644 --- a/lib/Runtime/Debug/TTEvents.h +++ b/lib/Runtime/Debug/TTEvents.h @@ -168,8 +168,9 @@ namespace TTD ConstructCallActionTag, CodeParseActionTag, CallExistingFunctionActionTag, - + HasOwnPropertyActionTag, + GetDataViewInfoActionTag, Count }; From 3e20cf2841ad63a1874e6064ec7a464f04a16618 Mon Sep 17 00:00:00 2001 From: Kyle Farnung Date: Mon, 31 Jul 2017 15:48:44 -0700 Subject: [PATCH 2/2] PR feedback --- lib/Runtime/Debug/TTEventLog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Runtime/Debug/TTEventLog.cpp b/lib/Runtime/Debug/TTEventLog.cpp index 003e82096bc..a42d755f32e 100644 --- a/lib/Runtime/Debug/TTEventLog.cpp +++ b/lib/Runtime/Debug/TTEventLog.cpp @@ -2340,7 +2340,7 @@ namespace TTD NSLogEvents::JsRTSingleVarArgumentAction* giAction = this->RecordGetInitializedEvent_DataOnly(); NSLogEvents::SetVarItem_0(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var)); - //entry/exit status should be set to clead by initialization so don't need to do anything + // entry/exit status should be set to clear by initialization so don't need to do anything giAction->Result = TTD_CONVERT_JSVAR_TO_TTDVAR(result); } @@ -2349,7 +2349,7 @@ namespace TTD NSLogEvents::JsRTSingleVarArgumentAction* giAction = this->RecordGetInitializedEvent_DataOnly(); NSLogEvents::SetVarItem_0(giAction, TTD_CONVERT_JSVAR_TO_TTDVAR(var)); - //entry/exit status should be set to clead by initialization so don't need to do anything + // entry/exit status should be set to clear by initialization so don't need to do anything giAction->Result = TTD_CONVERT_JSVAR_TO_TTDVAR(result); }