-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add JSRT weak reference APIs #2948
Changes from 4 commits
deb0a4e
671c390
5ea344e
617966a
042db69
7c2439e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -761,7 +761,7 @@ CHAKRA_API JsSetCurrentContext(_In_ JsContextRef newContext) | |
} | ||
else | ||
{ | ||
if(oldScriptContext->IsTTDRecordModeEnabled()) | ||
if(oldScriptContext->IsTTDRecordModeEnabled()) | ||
{ | ||
//already know newScriptContext != oldScriptContext so don't check again | ||
if(oldScriptContext->ShouldPerformRecordAction()) | ||
|
@@ -2890,6 +2890,50 @@ CHAKRA_API JsSetPromiseContinuationCallback(_In_ JsPromiseContinuationCallback p | |
/*allowInObjectBeforeCollectCallback*/true); | ||
} | ||
|
||
CHAKRA_API JsCreateWeakReference( | ||
_In_ JsValueRef value, | ||
_Out_ JsWeakRef* weakRef) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
PARAM_NOT_NULL check for out parameters in both APIs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Initialize weakRef to nullptr |
||
{ | ||
VALIDATE_JSREF(value); | ||
PARAM_NOT_NULL(weakRef); | ||
*weakRef = nullptr; | ||
|
||
return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { | ||
ThreadContext* threadContext = ThreadContext::GetContextForCurrentThread(); | ||
if (threadContext == nullptr) | ||
{ | ||
return JsErrorNoCurrentContext; | ||
} | ||
|
||
Recycler* recycler = threadContext->GetRecycler(); | ||
if (recycler->IsInObjectBeforeCollectCallback()) | ||
{ | ||
return JsErrorInObjectBeforeCollectCallback; | ||
} | ||
|
||
Memory::RecyclerWeakReference<char>* recyclerWeakReference = | ||
recycler->CreateWeakReferenceHandle<char>(reinterpret_cast<char*>(value)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Should it be ok to use FindOrCreateWeakReferenceHandle instead of CreateWeakReferenceHandle? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure. I think @boingoing actually wrote this code originally. Taylor can you comment on this? |
||
*weakRef = reinterpret_cast<JsWeakRef>(recyclerWeakReference); | ||
return JsNoError; | ||
}); | ||
} | ||
|
||
CHAKRA_API JsGetWeakReferenceValue( | ||
_In_ JsWeakRef weakRef, | ||
_Out_ JsValueRef* value) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Initialize value to JS_INVALID_REFERENCE |
||
{ | ||
VALIDATE_JSREF(weakRef); | ||
PARAM_NOT_NULL(value); | ||
*value = JS_INVALID_REFERENCE; | ||
|
||
return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is GC deterministic? What would happen in a TTD scenario when the object backing a weak reference is collected at different points? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know enough about how TTD works to answer that. I'd appreciate input from someone else about how weak references should interact with TTD. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mrkmarron can hopefully offer an opinion when he's got the time |
||
Memory::RecyclerWeakReference<char>* recyclerWeakReference = | ||
reinterpret_cast<Memory::RecyclerWeakReference<char>*>(weakRef); | ||
*value = reinterpret_cast<JsValueRef>(recyclerWeakReference->Get()); | ||
return JsNoError; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense to return a specific error code when the reference was already released? Having it return an invalid reference seems ok, I just wasn't sure whether this was consistent with other APIs. /cc @liminzhu There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would not consider it a failure when the weak-referenced value is not available, so I don't think it should return an error code then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's true and consistent with other libraries, there just aren't many APIs in JSRT where the out param can be JS_INVALID_REFERENCE after a successful call. I think the documentation is pretty clear, so that should cover it. |
||
}); | ||
} | ||
|
||
JsErrorCode RunScriptCore(JsValueRef scriptSource, const byte *script, size_t cb, | ||
LoadScriptFlag loadScriptFlag, JsSourceContext sourceContext, | ||
const WCHAR *sourceUrl, bool parseOnly, JsParseScriptAttributes parseAttributes, | ||
|
@@ -3904,7 +3948,7 @@ CHAKRA_API JsTTDPreExecuteSnapShotInterval(_In_ JsRuntimeHandle runtimeHandle, _ | |
return inflateStatus; | ||
} | ||
|
||
//If we are in the "active" segment set the continue breakpoint | ||
//If we are in the "active" segment set the continue breakpoint | ||
if((moveMode & JsTTDMoveMode::JsTTDMoveScanIntervalForContinueInActiveBreakpointSegment) == JsTTDMoveMode::JsTTDMoveScanIntervalForContinueInActiveBreakpointSegment) | ||
{ | ||
GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode | ||
|
@@ -3944,7 +3988,7 @@ CHAKRA_API JsTTDPreExecuteSnapShotInterval(_In_ JsRuntimeHandle runtimeHandle, _ | |
elog->PopMode(TTD::TTDMode::DebuggerLogBreakpoints); | ||
elog->PopMode(TTD::TTDMode::DebuggerSuppressBreakpoints); | ||
|
||
//If we are in the "active" segment un-set the continue breakpoint | ||
//If we are in the "active" segment un-set the continue breakpoint | ||
if((moveMode & JsTTDMoveMode::JsTTDMoveScanIntervalForContinueInActiveBreakpointSegment) == JsTTDMoveMode::JsTTDMoveScanIntervalForContinueInActiveBreakpointSegment) | ||
{ | ||
GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode | ||
|
@@ -4036,7 +4080,7 @@ CHAKRA_API JsTTDReplayExecution(_Inout_ JsTTDMoveMode* moveMode, _Out_ int64_t* | |
return JsNoError; | ||
}); | ||
|
||
if(bpstatus != JsNoError) | ||
if(bpstatus != JsNoError) | ||
{ | ||
return bpstatus; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,6 +103,8 @@ | |
JsGetRuntime | ||
JsIdle | ||
JsSetPromiseContinuationCallback | ||
JsCreateWeakReference | ||
JsGetWeakReferenceValue | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you moved the headers to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! |
||
#ifndef NTBUILD | ||
JsCreateString | ||
JsCreateStringUtf16 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this API should not be callable during collection callbacks as this allocates memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a check for that.