public void Dispose() { if (_NativeV8EngineProxy != null) { _TerminateWorker(); // (will return only when it has successfully terminated) // ... clear all handles of object IDs for disposal ... HandleProxy *hProxy; for (var i = 0; i < _HandleProxies.Length; i++) { hProxy = _HandleProxies[i]; if (hProxy != null && !hProxy->IsDisposed) { hProxy->_ObjectID = -2; // (note: this must be <= -2, otherwise the ID auto updates -1 to -2 to flag the ID as already processed) } } // ... allow all objects to be finalized by the GC ... ObservableWeakReference <V8NativeObject> weakRef; for (var i = 0; i < _Objects.Count; i++) { if ((weakRef = _Objects[i]) != null && weakRef.Object != null) { weakRef.Object._ID = null; weakRef.Object.Template = null; weakRef.Object._Handle = ObjectHandle.Empty; } } // ... destroy the native engine ... if (_NativeV8EngineProxy != null) { _Engines[_NativeV8EngineProxy->ID] = null; // (notifies any lingering handles that this engine is now gone) V8NetProxy.DestroyV8EngineProxy(_NativeV8EngineProxy); _NativeV8EngineProxy = null; } } }
public V8Engine() { this.RunMarshallingTests(); lock (_GlobalLock) // (required because engine proxy instance IDs are tracked on the native side in a static '_DisposedEngines' vector [for quick disposal of handles]) { _NativeV8EngineProxy = V8NetProxy.CreateV8EngineProxy(false, null, 0); _RegisterEngine(_NativeV8EngineProxy->ID); _GlobalObjectTemplateProxy = CreateObjectTemplate <ObjectTemplate>(); _GlobalObjectTemplateProxy.UnregisterPropertyInterceptors(); // (it's much faster to use a native object for the global scope) GlobalObject = V8NetProxy.SetGlobalObjectTemplate(_NativeV8EngineProxy, _GlobalObjectTemplateProxy._NativeObjectTemplateProxy); // (returns the global object handle) } ___V8GarbageCollectionRequestCallback = _V8GarbageCollectionRequestCallback; V8NetProxy.RegisterGCCallback(_NativeV8EngineProxy, ___V8GarbageCollectionRequestCallback); _Initialize_Handles(); _Initialize_ObjectTemplate(); _Initialize_Worker(); // (DO THIS LAST!!! - the worker expects everything to be ready) }
public static extern HandleProxy *CreateNumber(NativeV8EngineProxy *engine, double num);
public static extern bool DoIdleNotification(NativeV8EngineProxy *engine, int hint = 1000);
public static extern void RegisterGCCallback(NativeV8EngineProxy *engine, V8GarbageCollectionRequestCallback garbageCollectionRequestCallback);
public static extern HandleProxy *CreateNullValue(NativeV8EngineProxy *engine);
public static extern HandleProxy *CreateArray(NativeV8EngineProxy *engine, HandleProxy **items = null, Int32 length = 0);
public static extern HandleProxy *CreateDate(NativeV8EngineProxy *engine, double ms);
public static extern HandleProxy *V8ExecuteCompiledScript(NativeV8EngineProxy *engine, HandleProxy *script);
/// <summary> /// If there's any marshalling incompatibility, this will throw an exception. /// </summary> public void RunMarshallingTests() { HandleProxy * hp = V8NetProxy.CreateHandleProxyTest(); NativeV8EngineProxy * nv8ep = V8NetProxy.CreateV8EngineProxyTest(); NativeObjectTemplateProxy * notp = V8NetProxy.CreateObjectTemplateProxyTest(); NativeFunctionTemplateProxy *nftp = V8NetProxy.CreateFunctionTemplateProxyTest(); byte[] data; byte ofs = 0; // (skip type) try { ofs = (byte)((int)&hp->NativeClassType - (int)hp); if (hp->NativeClassType != ProxyObjectType.HandleProxyClass) { _ThrowMarshalTestError("HandleProxy", "NativeClassType", ofs, null, (byte *)&hp->NativeClassType, 4); } ofs = (byte)((int)&hp->ID - (int)hp); if ((Int32)hp->ID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "ID", ofs, data, (byte *)&hp->ID); } ofs = (byte)((int)&hp->_ObjectID - (int)hp); if ((Int32)hp->_ObjectID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "_ObjectID", ofs, data, (byte *)&hp->_ObjectID); } ofs = (byte)((int)&hp->_CLRTypeID - (int)hp); if ((Int32)hp->_CLRTypeID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "_CLRTypeID", ofs, data, (byte *)&hp->_CLRTypeID); } ofs = (byte)((int)&hp->_Type - (int)hp); if ((Int32)hp->_Type != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "_ValueType", ofs, data, (byte *)&hp->_Type); } // region ### HANDLE VALUE ### - Note: This is only valid upon calling 'UpdateValue()'. ofs = (byte)((int)&hp->V8Boolean - (int)hp); if ((byte)hp->V8Boolean != _GetMarshalTestByteValue(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "V8Boolean", ofs, data, (byte *)&hp->V8Boolean); } if ((Int64)hp->V8Integer != _GetMarshalTestInt64Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "V8Integer", ofs, data, (byte *)&hp->V8Integer); } if ((double)hp->V8Number != _GetMarshalTestDoubleValue(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "V8Number", ofs, data, (byte *)&hp->V8Number); } ofs = (byte)((int)&hp->V8String - (int)hp); if ((Int64)hp->V8String != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "V8String", ofs, data, (byte *)&hp->V8String); } // endregion ofs = (byte)((int)&hp->ManagedReference - (int)hp); if ((Int64)hp->ManagedReference != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "ManagedReference", ofs, data, (byte *)&hp->ManagedReference); // The number of references on the managed side. } ofs = (byte)((int)&hp->Disposed - (int)hp); if ((Int32)hp->Disposed != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "Disposed", ofs, data, (byte *)&hp->Disposed); // (0 = in use, 1 = managed side ready to dispose, 2 = object is weak (if applicable), 3 = disposed/cached) } ofs = (byte)((int)&hp->EngineID - (int)hp); if ((Int32)hp->EngineID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "EngineID", ofs, data, (byte *)&hp->EngineID); } ofs = (byte)((int)&hp->NativeEngineProxy - (int)hp); if ((Int64)hp->NativeEngineProxy != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "NativeEngineProxy", ofs, data, (byte *)&hp->NativeEngineProxy); // Pointer to the native V8 engine proxy object associated with this proxy handle instance (used native side to free the handle upon destruction). } ofs = (byte)((int)&hp->NativeV8Handle - (int)hp); if ((Int64)hp->NativeV8Handle != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("HandleProxy", "NativeV8Handle", ofs, data, (byte *)&hp->NativeV8Handle); // The native V8 persistent object handle (not used on the managed side). } ofs = (byte)((int)&nv8ep->NativeClassType - (int)nv8ep); if (nv8ep->NativeClassType != ProxyObjectType.V8EngineProxyClass) { _ThrowMarshalTestError("NativeV8EngineProxy", "NativeClassType", ofs, null, (byte *)&nv8ep->NativeClassType, 4); } ofs = (byte)((int)&nv8ep->ID - (int)nv8ep); if ((Int32)nv8ep->ID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("NativeV8EngineProxy", "ID", ofs, data, (byte *)&nv8ep->ID); } ofs += (byte)data.Length; ofs = (byte)((int)¬p->NativeClassType - (int)notp); if (notp->NativeClassType != ProxyObjectType.ObjectTemplateProxyClass) { _ThrowMarshalTestError("NativeObjectTemplateProxy", "NativeClassType", ofs, null, (byte *)¬p->NativeClassType, 4); } ofs = (byte)((int)¬p->NativeEngineProxy - (int)notp); if ((Int64)notp->NativeEngineProxy != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("NativeObjectTemplateProxy", "NativeEngineProxy", ofs, data, (byte *)¬p->NativeEngineProxy); } ofs = (byte)((int)¬p->EngineID - (int)notp); if ((Int32)notp->EngineID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("NativeObjectTemplateProxy", "EngineID", ofs, data, (byte *)¬p->EngineID); } ofs = (byte)((int)¬p->ObjectID - (int)notp); if ((Int32)notp->ObjectID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("NativeObjectTemplateProxy", "ObjectID", ofs, data, (byte *)¬p->ObjectID); } ofs = (byte)((int)¬p->NativeObjectTemplate - (int)notp); if ((Int64)notp->NativeObjectTemplate != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("NativeObjectTemplateProxy", "NativeObjectTemplate", ofs, data, (byte *)¬p->NativeObjectTemplate); } ofs = (byte)((int)&nftp->NativeClassType - (int)nftp); if (nftp->NativeClassType != ProxyObjectType.FunctionTemplateProxyClass) { _ThrowMarshalTestError("NativeFunctionTemplateProxy", "NativeClassType", ofs, null, (byte *)&nftp->NativeClassType, 4); } ofs = (byte)((int)&nftp->NativeEngineProxy - (int)nftp); if ((Int64)nftp->NativeEngineProxy != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("NativeFunctionTemplateProxy", "NativeEngineProxy", ofs, data, (byte *)&nftp->NativeEngineProxy); } ofs = (byte)((int)&nftp->EngineID - (int)nftp); if ((Int32)nftp->EngineID != _GetMarshalTestInt32Value(ofs, out data)) { _ThrowMarshalTestError("NativeFunctionTemplateProxy", "EngineID", ofs, data, (byte *)&nftp->EngineID); } ofs = (byte)((int)&nftp->NativeFucntionTemplate - (int)nftp); if ((Int64)nftp->NativeFucntionTemplate != _GetMarshalTestPTRValue(ofs, out data)) { _ThrowMarshalTestError("NativeFunctionTemplateProxy", "NativeFucntionTemplate", ofs, data, (byte *)&nftp->NativeFucntionTemplate); } } finally { V8NetProxy.DeleteTestData(hp); V8NetProxy.DeleteTestData(nv8ep); V8NetProxy.DeleteTestData(notp); V8NetProxy.DeleteTestData(nftp); } }
public static unsafe extern void SetFlagsFromString(NativeV8EngineProxy *engine, [MarshalAs(UnmanagedType.AnsiBStr)] string name);
public static extern void TerminateExecution(NativeV8EngineProxy *engine);
public extern static HandleProxy *SetContext64(NativeV8EngineProxy *engine, NativeContext *context);
public extern static NativeContext *CreateContext64(NativeV8EngineProxy *engine, NativeObjectTemplateProxy *templatePoxy);
public static extern HandleProxy *CreateString(NativeV8EngineProxy *engine, string str);
public static unsafe extern NativeObjectTemplateProxy *CreateObjectTemplateProxy(NativeV8EngineProxy *engine);
public static extern HandleProxy *CreateError(NativeV8EngineProxy *engine, string message, JSValueType errorType);
public static unsafe extern HandleProxy *SetGlobalObjectTemplate(NativeV8EngineProxy *engine, NativeObjectTemplateProxy *proxy);
public static extern HandleProxy *CreateObject(NativeV8EngineProxy *engine, Int32 managedObjectID);
public static extern void DestroyV8EngineProxy(NativeV8EngineProxy *engine);
public static extern HandleProxy *CreateStringArray(NativeV8EngineProxy *engine, char **items, Int32 length = 0);
public static unsafe extern NativeFunctionTemplateProxy *CreateFunctionTemplateProxy(NativeV8EngineProxy *engine, string className, ManagedJSFunctionCallback callback);
public static extern void WithV8HandleScope(NativeV8EngineProxy *engine, Action action);
public static extern HandleProxy *CreateBoolean(NativeV8EngineProxy *engine, bool b);
public static extern void ForceGC(NativeV8EngineProxy *engine);
public static extern HandleProxy *CreateInteger(NativeV8EngineProxy *engine, Int32 num);
public static extern HandleProxy *V8Execute(NativeV8EngineProxy *engine, string script, string sourceName = null);
public extern static NativeContext *GetContext32(NativeV8EngineProxy *engine);