From deb0a4edd62192513db20a27a11a880951ac05d2 Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Mon, 8 May 2017 15:50:11 -0700 Subject: [PATCH 1/6] Add JSRT weak-reference APIs --- lib/Jsrt/ChakraCommon.h | 37 ++++++++++++++++++++++++++++++ lib/Jsrt/Jsrt.cpp | 42 ++++++++++++++++++++++++++++++---- lib/Jsrt/JsrtCommonExports.inc | 2 ++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/lib/Jsrt/ChakraCommon.h b/lib/Jsrt/ChakraCommon.h index c303079dea3..348a816c436 100644 --- a/lib/Jsrt/ChakraCommon.h +++ b/lib/Jsrt/ChakraCommon.h @@ -406,6 +406,16 @@ typedef unsigned short uint16_t; /// typedef JsRef JsPropertyIdRef; + /// + /// A weak reference to a JavaScript value. + /// + /// + /// A value with only weak references is available for garbage-collection. A strong reference + /// to the value (JsValueRef) may be obtained from a weak reference if the value happens + /// to still be available. + /// + typedef JsRef JsWeakRef; + /// /// Attributes of a runtime. /// @@ -2390,6 +2400,33 @@ typedef unsigned short uint16_t; _In_ JsPromiseContinuationCallback promiseContinuationCallback, _In_opt_ void *callbackState); + /// + /// Creates a weak reference to a value. + /// + /// The value to be referenced. + /// Weak reference to the value. + /// + /// The code JsNoError if the operation succeeded, a failure code otherwise. + /// + CHAKRA_API + JsCreateWeakReference( + _In_ JsValueRef value, + _Out_ JsWeakRef* weakRef); + + /// + /// Gets a strong reference to the value referred to by a weak reference. + /// + /// A weak reference. + /// Reference to the value, or JS_INVALID_REFERENCE if the value is + /// no longer available. + /// + /// The code JsNoError if the operation succeeded, a failure code otherwise. + /// + CHAKRA_API + JsGetWeakReferenceValue( + _In_ JsWeakRef weakRef, + _Out_ JsValueRef* value); + #ifdef _WIN32 #include "ChakraCommonWindows.h" #endif // _WIN32 diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp index 0e2a24da758..0596e8a0892 100644 --- a/lib/Jsrt/Jsrt.cpp +++ b/lib/Jsrt/Jsrt.cpp @@ -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,40 @@ CHAKRA_API JsSetPromiseContinuationCallback(_In_ JsPromiseContinuationCallback p /*allowInObjectBeforeCollectCallback*/true); } +CHAKRA_API JsCreateWeakReference( + _In_ JsValueRef value, + _Out_ JsWeakRef* weakRef) +{ + VALIDATE_JSREF(value); + + return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { + ThreadContext* threadContext = ThreadContext::GetContextForCurrentThread(); + if (threadContext == nullptr) + { + return JsErrorNoCurrentContext; + } + + Recycler* recycler = threadContext->GetRecycler(); + Memory::RecyclerWeakReference* recyclerWeakReference = + recycler->CreateWeakReferenceHandle(reinterpret_cast(value)); + *weakRef = reinterpret_cast(recyclerWeakReference); + return JsNoError; + }); +} + +CHAKRA_API JsGetWeakReferenceValue( + _In_ JsWeakRef weakRef, + _Out_ JsValueRef* value) +{ + VALIDATE_JSREF(weakRef); + + return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { + Memory::RecyclerWeakReference* recyclerWeakReference = reinterpret_cast*>(weakRef); + *value = reinterpret_cast(recyclerWeakReference->Get()); + return JsNoError; + }); +} + JsErrorCode RunScriptCore(JsValueRef scriptSource, const byte *script, size_t cb, LoadScriptFlag loadScriptFlag, JsSourceContext sourceContext, const WCHAR *sourceUrl, bool parseOnly, JsParseScriptAttributes parseAttributes, @@ -3904,7 +3938,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 +3978,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 +4070,7 @@ CHAKRA_API JsTTDReplayExecution(_Inout_ JsTTDMoveMode* moveMode, _Out_ int64_t* return JsNoError; }); - if(bpstatus != JsNoError) + if(bpstatus != JsNoError) { return bpstatus; } diff --git a/lib/Jsrt/JsrtCommonExports.inc b/lib/Jsrt/JsrtCommonExports.inc index a1828185c14..852576380df 100644 --- a/lib/Jsrt/JsrtCommonExports.inc +++ b/lib/Jsrt/JsrtCommonExports.inc @@ -103,6 +103,8 @@ JsGetRuntime JsIdle JsSetPromiseContinuationCallback + JsCreateWeakReference + JsGetWeakReferenceValue #ifndef NTBUILD JsCreateString JsCreateStringUtf16 From 671c3909310f0872578517b440f23ffd05d790bb Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Tue, 9 May 2017 12:18:00 -0700 Subject: [PATCH 2/6] Add native test for weak references --- test/native-tests/test-weakref/Platform.js | 52 ++++++++++++++++ test/native-tests/test-weakref/sample.cpp | 71 ++++++++++++++++++++++ test/native-tests/test_native.sh | 3 + 3 files changed, 126 insertions(+) create mode 100644 test/native-tests/test-weakref/Platform.js create mode 100644 test/native-tests/test-weakref/sample.cpp diff --git a/test/native-tests/test-weakref/Platform.js b/test/native-tests/test-weakref/Platform.js new file mode 100644 index 00000000000..48c25f2e6cb --- /dev/null +++ b/test/native-tests/test-weakref/Platform.js @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +var isWindows = !WScript.Platform || WScript.Platform.OS == 'win32'; +var path_sep = isWindows ? '\\' : '/'; +var isStaticBuild = WScript.Platform && WScript.Platform.LINK_TYPE == 'static'; + +if (!isStaticBuild) { + // test will be ignored + print("# IGNORE_THIS_TEST"); +} else { + var platform = WScript.Platform.OS; + var binaryPath = WScript.Platform.BINARY_PATH; + // discard `ch` from path + binaryPath = binaryPath.substr(0, binaryPath.lastIndexOf(path_sep)); + var makefile = +"IDIR=" + binaryPath + "/../../lib/Jsrt \n\ +\n\ +LIBRARY_PATH=" + binaryPath + "/lib\n\ +PLATFORM=" + platform + "\n\ +LDIR=$(LIBRARY_PATH)/libChakraCoreStatic.a \n\ +\n\ +ifeq (darwin, ${PLATFORM})\n\ +\tICU4C_LIBRARY_PATH ?= /usr/local/opt/icu4c\n\ +\tCFLAGS=-lstdc++ -std=c++11 -I$(IDIR)\n\ +\tFORCE_STARTS=-Wl,-force_load,\n\ +\tFORCE_ENDS=\n\ +\tLIBS=-framework CoreFoundation -framework Security -lm -ldl -Wno-c++11-compat-deprecated-writable-strings \ + -Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\ +\tLDIR+=$(ICU4C_LIBRARY_PATH)/lib/libicudata.a \ + $(ICU4C_LIBRARY_PATH)/lib/libicuuc.a \ + $(ICU4C_LIBRARY_PATH)/lib/libicui18n.a\n\ +else\n\ +\tCFLAGS=-lstdc++ -std=c++0x -I$(IDIR)\n\ +\tFORCE_STARTS=-Wl,--whole-archive\n\ +\tFORCE_ENDS=-Wl,--no-whole-archive\n\ +\tLIBS=-pthread -lm -ldl -licuuc -Wno-c++11-compat-deprecated-writable-strings \ + -Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\ +endif\n\ +\n\ +testmake:\n\ +\t$(CC) sample.cpp $(CFLAGS) $(FORCE_STARTS) $(LDIR) $(FORCE_ENDS) $(LIBS)\n\ +\n\ +.PHONY: clean\n\ +\n\ +clean:\n\ +\trm sample.o\n"; + + print(makefile) +} diff --git a/test/native-tests/test-weakref/sample.cpp b/test/native-tests/test-weakref/sample.cpp new file mode 100644 index 00000000000..f420db97743 --- /dev/null +++ b/test/native-tests/test-weakref/sample.cpp @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +#include "ChakraCore.h" +#include +#include +#include +#include + +#define FAIL_CHECK(cmd) \ + do \ + { \ + JsErrorCode errCode = cmd; \ + if (errCode != JsNoError) \ + { \ + printf("Error %d at '%s'\n", \ + errCode, #cmd); \ + return 1; \ + } \ + } while(0) + +using namespace std; + +int main() +{ + JsRuntimeHandle runtime; + JsContextRef context; + unsigned currentSourceContext = 0; + + // Create a runtime. + JsCreateRuntime(JsRuntimeAttributeNone, nullptr, &runtime); + + // Create an execution context. + JsCreateContext(runtime, &context); + + // Now set the current execution context. + JsSetCurrentContext(context); + + JsValueRef valueRef; + FAIL_CHECK(JsCreateString("sample", strlen("sample"), &valueRef)); + + JsWeakRef weakRef; + FAIL_CHECK(JsCreateWeakReference(valueRef, &weakRef)); + + FAIL_CHECK(JsGetWeakReferenceValue(weakRef, &valueRef)); + if (valueRef == JS_INVALID_REFERENCE) { + printf("JsGetWeakReference() returned invalid reference.\n"); + return 1; + } + + // Clear the reference on the stack, so that the value will be GC'd. + valueRef = JS_INVALID_REFERENCE; + + FAIL_CHECK(JsCollectGarbage(runtime)); + + FAIL_CHECK(JsGetWeakReferenceValue(weakRef, &valueRef)); + if (valueRef != JS_INVALID_REFERENCE) { + printf("JsGetWeakReference() should have returned invalid reference after GC.\n"); + return 1; + } + + printf("Result -> SUCCESS \n"); + + // Dispose runtime + JsSetCurrentContext(JS_INVALID_REFERENCE); + JsDisposeRuntime(runtime); + + return 0; +} diff --git a/test/native-tests/test_native.sh b/test/native-tests/test_native.sh index 79d97a60721..648f173adff 100755 --- a/test/native-tests/test_native.sh +++ b/test/native-tests/test_native.sh @@ -87,6 +87,9 @@ RUN "test-char16" # test-static-native RUN "test-static-native" +# test-weakref +RUN "test-weakref" + # shared lib tests LIB_DIR="$(dirname ${CH_DIR})" if [[ `uname -a` =~ "Darwin" ]]; then From 5ea344e4b012ac2762368371ac2bf97c0d29c64f Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Wed, 10 May 2017 09:20:12 -0700 Subject: [PATCH 3/6] Address review feedback in weak-reference APIs --- lib/Jsrt/Jsrt.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp index 0596e8a0892..c406b1007e7 100644 --- a/lib/Jsrt/Jsrt.cpp +++ b/lib/Jsrt/Jsrt.cpp @@ -2895,6 +2895,8 @@ CHAKRA_API JsCreateWeakReference( _Out_ JsWeakRef* weakRef) { VALIDATE_JSREF(value); + PARAM_NOT_NULL(weakRef); + *weakRef = nullptr; return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { ThreadContext* threadContext = ThreadContext::GetContextForCurrentThread(); @@ -2904,6 +2906,11 @@ CHAKRA_API JsCreateWeakReference( } Recycler* recycler = threadContext->GetRecycler(); + if (recycler->IsInObjectBeforeCollectCallback()) + { + return JsErrorInObjectBeforeCollectCallback; + } + Memory::RecyclerWeakReference* recyclerWeakReference = recycler->CreateWeakReferenceHandle(reinterpret_cast(value)); *weakRef = reinterpret_cast(recyclerWeakReference); @@ -2916,9 +2923,12 @@ CHAKRA_API JsGetWeakReferenceValue( _Out_ JsValueRef* value) { VALIDATE_JSREF(weakRef); + PARAM_NOT_NULL(value); + *value = JS_INVALID_REFERENCE; return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { - Memory::RecyclerWeakReference* recyclerWeakReference = reinterpret_cast*>(weakRef); + Memory::RecyclerWeakReference* recyclerWeakReference = + reinterpret_cast*>(weakRef); *value = reinterpret_cast(recyclerWeakReference->Get()); return JsNoError; }); From 617966ab51fcbc58bd219c8b30eb4e7a0c663360 Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Wed, 10 May 2017 10:19:30 -0700 Subject: [PATCH 4/6] Move weak-reference test to JsRTApiTest.cpp --- bin/NativeTests/JsRTApiTest.cpp | 31 ++++++++++ test/native-tests/test-weakref/Platform.js | 52 ---------------- test/native-tests/test-weakref/sample.cpp | 71 ---------------------- test/native-tests/test_native.sh | 3 - 4 files changed, 31 insertions(+), 126 deletions(-) delete mode 100644 test/native-tests/test-weakref/Platform.js delete mode 100644 test/native-tests/test-weakref/sample.cpp diff --git a/bin/NativeTests/JsRTApiTest.cpp b/bin/NativeTests/JsRTApiTest.cpp index 3a40a675b5a..c093f3afbdc 100644 --- a/bin/NativeTests/JsRTApiTest.cpp +++ b/bin/NativeTests/JsRTApiTest.cpp @@ -102,6 +102,37 @@ namespace JsRTApiTest JsRTApiTest::RunWithAttributes(JsRTApiTest::ReferenceCountingTest); } + void WeakReferenceTest(JsRuntimeAttributes attributes, JsRuntimeHandle runtime) + { + JsValueRef valueRef = JS_INVALID_REFERENCE; + REQUIRE(JsCreateString("test", strlen("test"), &valueRef) == JsNoError); + + JsWeakRef weakRef = JS_INVALID_REFERENCE; + REQUIRE(JsCreateWeakReference(valueRef, &weakRef) == JsNoError); + + // JsGetWeakReferenceValue should return the original value reference. + JsValueRef valueRefFromWeakRef = JS_INVALID_REFERENCE; + CHECK(JsGetWeakReferenceValue(weakRef, &valueRefFromWeakRef) == JsNoError); + CHECK(valueRefFromWeakRef != JS_INVALID_REFERENCE); + CHECK(valueRefFromWeakRef == valueRef); + + // Clear the references on the stack, so that the value will be GC'd. + valueRef = JS_INVALID_REFERENCE; + valueRefFromWeakRef = JS_INVALID_REFERENCE; + + CHECK(JsCollectGarbage(runtime) == JsNoError); + + // JsGetWeakReferenceValue should return an invalid reference after the value was GC'd. + JsValueRef valueRefAfterGC = JS_INVALID_REFERENCE; + CHECK(JsGetWeakReferenceValue(weakRef, &valueRefAfterGC) == JsNoError); + CHECK(valueRefAfterGC == JS_INVALID_REFERENCE); + } + + TEST_CASE("ApiTest_WeakReferenceTest", "[ApiTest]") + { + JsRTApiTest::RunWithAttributes(JsRTApiTest::WeakReferenceTest); + } + void ObjectsAndPropertiesTest1(JsRuntimeAttributes attributes, JsRuntimeHandle runtime) { JsValueRef object = JS_INVALID_REFERENCE; diff --git a/test/native-tests/test-weakref/Platform.js b/test/native-tests/test-weakref/Platform.js deleted file mode 100644 index 48c25f2e6cb..00000000000 --- a/test/native-tests/test-weakref/Platform.js +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------------------------------- -// Copyright (C) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -//------------------------------------------------------------------------------------------------------- - -var isWindows = !WScript.Platform || WScript.Platform.OS == 'win32'; -var path_sep = isWindows ? '\\' : '/'; -var isStaticBuild = WScript.Platform && WScript.Platform.LINK_TYPE == 'static'; - -if (!isStaticBuild) { - // test will be ignored - print("# IGNORE_THIS_TEST"); -} else { - var platform = WScript.Platform.OS; - var binaryPath = WScript.Platform.BINARY_PATH; - // discard `ch` from path - binaryPath = binaryPath.substr(0, binaryPath.lastIndexOf(path_sep)); - var makefile = -"IDIR=" + binaryPath + "/../../lib/Jsrt \n\ -\n\ -LIBRARY_PATH=" + binaryPath + "/lib\n\ -PLATFORM=" + platform + "\n\ -LDIR=$(LIBRARY_PATH)/libChakraCoreStatic.a \n\ -\n\ -ifeq (darwin, ${PLATFORM})\n\ -\tICU4C_LIBRARY_PATH ?= /usr/local/opt/icu4c\n\ -\tCFLAGS=-lstdc++ -std=c++11 -I$(IDIR)\n\ -\tFORCE_STARTS=-Wl,-force_load,\n\ -\tFORCE_ENDS=\n\ -\tLIBS=-framework CoreFoundation -framework Security -lm -ldl -Wno-c++11-compat-deprecated-writable-strings \ - -Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\ -\tLDIR+=$(ICU4C_LIBRARY_PATH)/lib/libicudata.a \ - $(ICU4C_LIBRARY_PATH)/lib/libicuuc.a \ - $(ICU4C_LIBRARY_PATH)/lib/libicui18n.a\n\ -else\n\ -\tCFLAGS=-lstdc++ -std=c++0x -I$(IDIR)\n\ -\tFORCE_STARTS=-Wl,--whole-archive\n\ -\tFORCE_ENDS=-Wl,--no-whole-archive\n\ -\tLIBS=-pthread -lm -ldl -licuuc -Wno-c++11-compat-deprecated-writable-strings \ - -Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\ -endif\n\ -\n\ -testmake:\n\ -\t$(CC) sample.cpp $(CFLAGS) $(FORCE_STARTS) $(LDIR) $(FORCE_ENDS) $(LIBS)\n\ -\n\ -.PHONY: clean\n\ -\n\ -clean:\n\ -\trm sample.o\n"; - - print(makefile) -} diff --git a/test/native-tests/test-weakref/sample.cpp b/test/native-tests/test-weakref/sample.cpp deleted file mode 100644 index f420db97743..00000000000 --- a/test/native-tests/test-weakref/sample.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------------------------------- -// Copyright (C) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. -//------------------------------------------------------------------------------------------------------- - -#include "ChakraCore.h" -#include -#include -#include -#include - -#define FAIL_CHECK(cmd) \ - do \ - { \ - JsErrorCode errCode = cmd; \ - if (errCode != JsNoError) \ - { \ - printf("Error %d at '%s'\n", \ - errCode, #cmd); \ - return 1; \ - } \ - } while(0) - -using namespace std; - -int main() -{ - JsRuntimeHandle runtime; - JsContextRef context; - unsigned currentSourceContext = 0; - - // Create a runtime. - JsCreateRuntime(JsRuntimeAttributeNone, nullptr, &runtime); - - // Create an execution context. - JsCreateContext(runtime, &context); - - // Now set the current execution context. - JsSetCurrentContext(context); - - JsValueRef valueRef; - FAIL_CHECK(JsCreateString("sample", strlen("sample"), &valueRef)); - - JsWeakRef weakRef; - FAIL_CHECK(JsCreateWeakReference(valueRef, &weakRef)); - - FAIL_CHECK(JsGetWeakReferenceValue(weakRef, &valueRef)); - if (valueRef == JS_INVALID_REFERENCE) { - printf("JsGetWeakReference() returned invalid reference.\n"); - return 1; - } - - // Clear the reference on the stack, so that the value will be GC'd. - valueRef = JS_INVALID_REFERENCE; - - FAIL_CHECK(JsCollectGarbage(runtime)); - - FAIL_CHECK(JsGetWeakReferenceValue(weakRef, &valueRef)); - if (valueRef != JS_INVALID_REFERENCE) { - printf("JsGetWeakReference() should have returned invalid reference after GC.\n"); - return 1; - } - - printf("Result -> SUCCESS \n"); - - // Dispose runtime - JsSetCurrentContext(JS_INVALID_REFERENCE); - JsDisposeRuntime(runtime); - - return 0; -} diff --git a/test/native-tests/test_native.sh b/test/native-tests/test_native.sh index 648f173adff..79d97a60721 100755 --- a/test/native-tests/test_native.sh +++ b/test/native-tests/test_native.sh @@ -87,9 +87,6 @@ RUN "test-char16" # test-static-native RUN "test-static-native" -# test-weakref -RUN "test-weakref" - # shared lib tests LIB_DIR="$(dirname ${CH_DIR})" if [[ `uname -a` =~ "Darwin" ]]; then From 042db692062febd95ed228c8b2cde5dbbffafe7e Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Wed, 10 May 2017 14:46:21 -0700 Subject: [PATCH 5/6] More review feedback for weak-reference APIs - Move new APIs from ChakraCommon.h to ChakraCore.h, conditional on CHAKRACOREBUILD_ - Call FindOrCreateWeakReferenceHandle() instead of CreateWeakReferenceHandle() --- lib/Jsrt/ChakraCommon.h | 37 ----------------- lib/Jsrt/ChakraCore.h | 46 +++++++++++++++++++-- lib/Jsrt/Jsrt.cpp | 89 +++++++++++++++++++++-------------------- 3 files changed, 87 insertions(+), 85 deletions(-) diff --git a/lib/Jsrt/ChakraCommon.h b/lib/Jsrt/ChakraCommon.h index 348a816c436..c303079dea3 100644 --- a/lib/Jsrt/ChakraCommon.h +++ b/lib/Jsrt/ChakraCommon.h @@ -406,16 +406,6 @@ typedef unsigned short uint16_t; /// typedef JsRef JsPropertyIdRef; - /// - /// A weak reference to a JavaScript value. - /// - /// - /// A value with only weak references is available for garbage-collection. A strong reference - /// to the value (JsValueRef) may be obtained from a weak reference if the value happens - /// to still be available. - /// - typedef JsRef JsWeakRef; - /// /// Attributes of a runtime. /// @@ -2400,33 +2390,6 @@ typedef unsigned short uint16_t; _In_ JsPromiseContinuationCallback promiseContinuationCallback, _In_opt_ void *callbackState); - /// - /// Creates a weak reference to a value. - /// - /// The value to be referenced. - /// Weak reference to the value. - /// - /// The code JsNoError if the operation succeeded, a failure code otherwise. - /// - CHAKRA_API - JsCreateWeakReference( - _In_ JsValueRef value, - _Out_ JsWeakRef* weakRef); - - /// - /// Gets a strong reference to the value referred to by a weak reference. - /// - /// A weak reference. - /// Reference to the value, or JS_INVALID_REFERENCE if the value is - /// no longer available. - /// - /// The code JsNoError if the operation succeeded, a failure code otherwise. - /// - CHAKRA_API - JsGetWeakReferenceValue( - _In_ JsWeakRef weakRef, - _Out_ JsValueRef* value); - #ifdef _WIN32 #include "ChakraCommonWindows.h" #endif // _WIN32 diff --git a/lib/Jsrt/ChakraCore.h b/lib/Jsrt/ChakraCore.h index d999f287ab3..695bff57e2d 100644 --- a/lib/Jsrt/ChakraCore.h +++ b/lib/Jsrt/ChakraCore.h @@ -508,9 +508,47 @@ CHAKRA_API /// The code JsNoError if the operation succeeded, a failure code otherwise. /// CHAKRA_API -JsCreatePromise( - _Out_ JsValueRef *promise, - _Out_ JsValueRef *resolveFunction, - _Out_ JsValueRef *rejectFunction); + JsCreatePromise( + _Out_ JsValueRef *promise, + _Out_ JsValueRef *resolveFunction, + _Out_ JsValueRef *rejectFunction); + +/// +/// A weak reference to a JavaScript value. +/// +/// +/// A value with only weak references is available for garbage-collection. A strong reference +/// to the value (JsValueRef) may be obtained from a weak reference if the value happens +/// to still be available. +/// +typedef JsRef JsWeakRef; + +/// +/// Creates a weak reference to a value. +/// +/// The value to be referenced. +/// Weak reference to the value. +/// +/// The code JsNoError if the operation succeeded, a failure code otherwise. +/// +CHAKRA_API + JsCreateWeakReference( + _In_ JsValueRef value, + _Out_ JsWeakRef* weakRef); + +/// +/// Gets a strong reference to the value referred to by a weak reference. +/// +/// A weak reference. +/// Reference to the value, or JS_INVALID_REFERENCE if the value is +/// no longer available. +/// +/// The code JsNoError if the operation succeeded, a failure code otherwise. +/// +CHAKRA_API + JsGetWeakReferenceValue( + _In_ JsWeakRef weakRef, + _Out_ JsValueRef* value); + #endif // CHAKRACOREBUILD_ #endif // _CHAKRACORE_H_ diff --git a/lib/Jsrt/Jsrt.cpp b/lib/Jsrt/Jsrt.cpp index c406b1007e7..f9f202e637d 100644 --- a/lib/Jsrt/Jsrt.cpp +++ b/lib/Jsrt/Jsrt.cpp @@ -2890,50 +2890,6 @@ CHAKRA_API JsSetPromiseContinuationCallback(_In_ JsPromiseContinuationCallback p /*allowInObjectBeforeCollectCallback*/true); } -CHAKRA_API JsCreateWeakReference( - _In_ JsValueRef value, - _Out_ JsWeakRef* weakRef) -{ - 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* recyclerWeakReference = - recycler->CreateWeakReferenceHandle(reinterpret_cast(value)); - *weakRef = reinterpret_cast(recyclerWeakReference); - return JsNoError; - }); -} - -CHAKRA_API JsGetWeakReferenceValue( - _In_ JsWeakRef weakRef, - _Out_ JsValueRef* value) -{ - VALIDATE_JSREF(weakRef); - PARAM_NOT_NULL(value); - *value = JS_INVALID_REFERENCE; - - return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { - Memory::RecyclerWeakReference* recyclerWeakReference = - reinterpret_cast*>(weakRef); - *value = reinterpret_cast(recyclerWeakReference->Get()); - return JsNoError; - }); -} - JsErrorCode RunScriptCore(JsValueRef scriptSource, const byte *script, size_t cb, LoadScriptFlag loadScriptFlag, JsSourceContext sourceContext, const WCHAR *sourceUrl, bool parseOnly, JsParseScriptAttributes parseAttributes, @@ -4589,4 +4545,49 @@ CHAKRA_API JsCreatePromise(_Out_ JsValueRef *promise, _Out_ JsValueRef *resolve, return JsNoError; }); } + +CHAKRA_API JsCreateWeakReference( + _In_ JsValueRef value, + _Out_ JsWeakRef* weakRef) +{ + 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; + } + + recycler->FindOrCreateWeakReferenceHandle( + reinterpret_cast(value), + reinterpret_cast**>(weakRef)); + return JsNoError; + }); +} + +CHAKRA_API JsGetWeakReferenceValue( + _In_ JsWeakRef weakRef, + _Out_ JsValueRef* value) +{ + VALIDATE_JSREF(weakRef); + PARAM_NOT_NULL(value); + *value = JS_INVALID_REFERENCE; + + return GlobalAPIWrapper_NoRecord([&]() -> JsErrorCode { + Memory::RecyclerWeakReference* recyclerWeakReference = + reinterpret_cast*>(weakRef); + *value = reinterpret_cast(recyclerWeakReference->Get()); + return JsNoError; + }); +} + #endif // CHAKRACOREBUILD_ From 7c2439e32ceb2647f10738def840a2495045839c Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Wed, 10 May 2017 14:56:15 -0700 Subject: [PATCH 6/6] Fix weakref exports conditional --- lib/Jsrt/JsrtCommonExports.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Jsrt/JsrtCommonExports.inc b/lib/Jsrt/JsrtCommonExports.inc index 852576380df..6de2f6c2747 100644 --- a/lib/Jsrt/JsrtCommonExports.inc +++ b/lib/Jsrt/JsrtCommonExports.inc @@ -103,8 +103,6 @@ JsGetRuntime JsIdle JsSetPromiseContinuationCallback - JsCreateWeakReference - JsGetWeakReferenceValue #ifndef NTBUILD JsCreateString JsCreateStringUtf16 @@ -118,4 +116,6 @@ JsCreatePropertyId JsCopyPropertyId JsCreatePromise + JsCreateWeakReference + JsGetWeakReferenceValue #endif