diff --git a/Fiddling/Fiddling.csproj b/Fiddling/Fiddling.csproj index 10a5ccc..45fd980 100644 --- a/Fiddling/Fiddling.csproj +++ b/Fiddling/Fiddling.csproj @@ -85,7 +85,7 @@ copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8.dll $(ProjectDir)$(OutDir) copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8_libbase.dll $(ProjectDir)$(OutDir) copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\v8_libplatform.dll $(ProjectDir)$(OutDir) -copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\zlib.dll $(ProjectDir)$(OutDir) +copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\third_party_*.dll $(ProjectDir)$(OutDir) copy $(ProjectDir)..\$(V8Platform)\$(Configuration)\icu*.* $(ProjectDir)$(OutDir) diff --git a/Source/Noesis.Javascript/JavaScript.Net.vcxproj b/Source/Noesis.Javascript/JavaScript.Net.vcxproj index 196e601..f27fd75 100644 --- a/Source/Noesis.Javascript/JavaScript.Net.vcxproj +++ b/Source/Noesis.Javascript/JavaScript.Net.vcxproj @@ -1,9 +1,9 @@ - - - - + + + + Debug @@ -28,7 +28,7 @@ v4.7.2 ManagedCProj JavaScriptNet - 10.0.18362.0 + 10.0 @@ -97,6 +97,8 @@ Disabled WIN32;_DEBUG;%(PreprocessorDefinitions) NotUsing + stdcpp20 + /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions) v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies) @@ -112,6 +114,8 @@ Disabled _DEBUG;%(PreprocessorDefinitions) NotUsing + stdcpp20 + /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions) v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies) @@ -126,6 +130,8 @@ Level3 WIN32;NDEBUG;%(PreprocessorDefinitions) NotUsing + stdcpp20 + /Zc:__cplusplus /DNOMINMAX %(AdditionalOptions) v8.dll.lib;v8_libbase.dll.lib;v8_libplatform.dll.lib;%(AdditionalDependencies) @@ -140,6 +146,8 @@ Level3 NDEBUG;%(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 61cb676..b4fec4d 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)). @@ -213,6 +213,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()); } @@ -262,7 +264,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); @@ -291,7 +293,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()); } @@ -493,7 +496,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); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -523,7 +528,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; } @@ -538,6 +544,11 @@ System::String^ JavascriptContext::V8Version::get() return gcnew System::String(v8::V8::GetVersion()); } +bool JavascriptContext::IsV8Initialized::get() +{ + return initialized; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// Local