diff --git a/Fiddling/Fiddling.csproj b/Fiddling/Fiddling.csproj
index a3304ec..b801171 100644
--- a/Fiddling/Fiddling.csproj
+++ b/Fiddling/Fiddling.csproj
@@ -27,6 +27,6 @@
-
+
\ No newline at end of file
diff --git a/Source/Noesis.Javascript/JavaScript.Net.vcxproj b/Source/Noesis.Javascript/JavaScript.Net.vcxproj
index 7185756..7d8f6cf 100644
--- a/Source/Noesis.Javascript/JavaScript.Net.vcxproj
+++ b/Source/Noesis.Javascript/JavaScript.Net.vcxproj
@@ -1,9 +1,9 @@
-
-
-
-
+
+
+
+ Debug
@@ -100,6 +100,8 @@
DisabledWIN32;_DEBUG;%(PreprocessorDefinitions)NotUsing
+ stdcpp20
+ /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions)v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies)
@@ -115,6 +117,8 @@
Disabled_DEBUG;%(PreprocessorDefinitions)NotUsing
+ stdcpp20
+ /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions)v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies)
@@ -129,6 +133,8 @@
Level3WIN32;NDEBUG;%(PreprocessorDefinitions)NotUsing
+ stdcpp20
+ /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions)v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies)
@@ -143,6 +149,8 @@
Level3NDEBUG;%(PreprocessorDefinitions)NotUsing
+ stdcpp20
+ /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions)v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies)
@@ -183,9 +191,9 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Noesis.Javascript/JavascriptContext.cpp b/Source/Noesis.Javascript/JavascriptContext.cpp
index 0089f72..21031fa 100644
--- a/Source/Noesis.Javascript/JavascriptContext.cpp
+++ b/Source/Noesis.Javascript/JavascriptContext.cpp
@@ -118,11 +118,6 @@ v8::Local ToV8String(Isolate* isolate, System::String^ value) {
return String::NewFromTwoByte(isolate, (uint16_t*)name, v8::NewStringType::kNormal).ToLocalChecked();
}
-static JavascriptContext::JavascriptContext()
-{
- UnmanagedInitialisation();
-}
-
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -151,6 +146,11 @@ void JavascriptContext::FatalErrorCallbackMember(const char* location, const cha
JavascriptContext::JavascriptContext()
{
+ // Certain static operations like setting flags cannot be performed after V8 has been initialized. Since we allow setting flags by
+ // a static method we can't do the unmanaged initialization in the static constructor, because that would always run before any other
+ // static method. Instead we call it here. The internal checks in UnmanagedInitialisation make this thread safe.
+ UnmanagedInitialisation();
+
// Unfortunately the fatal error handler is not installed early enough to catch
// out-of-memory errors while creating new isolates
// (see my post Catching V8::FatalProcessOutOfMemory while creating an isolate (SetFatalErrorHandler does not work)).
@@ -232,6 +232,8 @@ void JavascriptContext::SetFatalErrorHandler(FatalErrorHandler^ handler)
void JavascriptContext::SetFlags(System::String^ flags)
{
+ if (initialized)
+ throw gcnew System::InvalidOperationException("Flags can only be set once before the first context and therefore V8 is initialized.");
std::string convertedFlags = msclr::interop::marshal_as(flags);
v8::V8::SetFlagsFromString(convertedFlags.c_str(), (int)convertedFlags.length());
}
@@ -281,7 +283,7 @@ JavascriptContext::SetParameter(System::String^ iName, System::Object^ iObject,
if (options != SetParameterOptions::None) {
Local obj = value.As();
if (!obj.IsEmpty()) {
- Local wrap = obj->GetInternalField(0).As();
+ Local wrap = obj->GetInternalField(0).As().As();
if (!wrap.IsEmpty()) {
JavascriptExternal* external = static_cast(wrap->Value());
external->SetOptions(options);
@@ -310,7 +312,8 @@ void JavascriptContext::SetConstructor(System::String^ name, System::Type^ assoc
Local className = ToV8String(isolate, name);
Local functionTemplate = JavascriptInterop::GetFunctionTemplateFromSystemDelegate(constructor);
functionTemplate->SetClassName(className);
- JavascriptInterop::InitObjectWrapperTemplate(functionTemplate->InstanceTemplate());
+ auto instanceTemplate = functionTemplate->InstanceTemplate();
+ JavascriptInterop::InitObjectWrapperTemplate(instanceTemplate);
mTypeToConstructorMapping[associatedType] = System::IntPtr(new Persistent(isolate, functionTemplate));
Local::New(isolate, *mContext)->Global()->Set(context, className, functionTemplate->GetFunction(context).ToLocalChecked());
}
@@ -512,7 +515,9 @@ JavascriptContext::Exit(v8::Locker *locker, JavascriptContext^ old_context)
void
JavascriptContext::Collect()
{
- while(!this->isolate->IdleNotificationDeadline(1)) {};
+ // The method used originally here does not exist anymore and this is the best guess for a replacement.
+ // Since this isn't used in internal tests anywhere it can't be checked for validity.
+ this->isolate->MemoryPressureNotification(v8::MemoryPressureLevel::kModerate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -542,7 +547,8 @@ JavascriptContext::GetObjectWrapperConstructorTemplate(System::Type ^type)
System::IntPtr ptrToConstructor;
if (!mTypeToConstructorMapping->TryGetValue(type, ptrToConstructor)) {
Local constructor = FunctionTemplate::New(GetCurrentIsolate());
- JavascriptInterop::InitObjectWrapperTemplate(constructor->InstanceTemplate());
+ auto instanceTemplate = constructor->InstanceTemplate();
+ JavascriptInterop::InitObjectWrapperTemplate(instanceTemplate);
mTypeToConstructorMapping[type] = System::IntPtr(new Persistent(isolate, constructor));
return constructor;
}
@@ -557,6 +563,11 @@ System::String^ JavascriptContext::V8Version::get()
return gcnew System::String(v8::V8::GetVersion());
}
+bool JavascriptContext::IsV8Initialized::get()
+{
+ return initialized;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
Local