// 可在 GC 线程直接调用此方法 public void FreeDelegationValue(JSValue value) { if (_mainThreadId == Thread.CurrentThread.ManagedThreadId) { _objectCache.RemoveDelegate(value); if (_rt != JSRuntime.Null) { JSApi.JS_FreeValueRT(_rt, value); } } else { var act = new JSAction() { value = value, callback = _FreeValueAndDelegationAction, }; lock (_pendingActions) { _pendingActions.Enqueue(act); } } }
// 在主线程回调 private static unsafe void _PostMessage(ScriptRuntime runtime, JSAction action) { var worker = action.worker; try { if (worker._runtime.isRunning && worker._parentRuntime.isRunning) { var context = runtime.GetMainContext(); var ctx = (JSContext)context; var onmessage = JSApi.JS_GetProperty(ctx, worker._self, context.GetAtom("onmessage")); if (onmessage.IsException()) { var exceptionString = ctx.GetExceptionString(); var logger = runtime.GetLogger(); if (logger != null) { logger.Write(LogLevel.Error, exceptionString); } } else { if (JSApi.JS_IsFunction(ctx, onmessage) == 1) { // read object => jsvalue JSValue data; fixed(byte *buf = action.buffer.data) { data = JSApi.JS_ReadObject(ctx, buf, action.buffer.readableBytes, 0); } if (data.IsException()) { var exceptionString = ctx.GetExceptionString(); var logger = runtime.GetLogger(); if (logger != null) { logger.Write(LogLevel.Error, exceptionString); } } else { var argv = stackalloc JSValue[1] { data }; var rval = JSApi.JS_Call(ctx, onmessage, worker._self, 1, argv); JSApi.JS_FreeValue(ctx, rval); } } else { // not function } JSApi.JS_FreeValue(ctx, onmessage); } } } finally { action.buffer.Release(); } }
private static void _FreeValueAction(ScriptRuntime rt, JSAction action) { JSApi.JS_FreeValueRT(rt, action.value); }
/// <summary> /// master 处理 worker 发送的消息 (在master线程回调) /// </summary> private static unsafe void _MasterOnMessage(ScriptRuntime runtime, JSAction action) { var args = (JSWorkerArgs)action.args; var buffer = args.buffer; try { var worker = args.worker; if (worker._runtime.isRunning && worker._parentRuntime.isRunning) { var context = runtime.GetMainContext(); var ctx = (JSContext)context; var onmessage = JSApi.JS_GetProperty(ctx, worker._self, context.GetAtom("onmessage")); if (onmessage.IsException()) { var exceptionString = ctx.GetExceptionString(); var logger = runtime.GetLogger(); if (logger != null) { logger.Write(LogLevel.Error, exceptionString); } } else { if (JSApi.JS_IsFunction(ctx, onmessage) == 1) { // read object => jsvalue JSValue data; fixed(byte *buf = buffer.data) { data = JSApi.JS_ReadObject(ctx, buf, buffer.readableBytes, JSApi.JS_READ_OBJ_REFERENCE); } do { if (!data.IsException()) { var evt = JSApi.JS_NewObject(ctx); if (!evt.IsException()) { JSApi.JS_SetProperty(ctx, evt, context.GetAtom("data"), data); var argv = stackalloc JSValue[1] { evt }; var rval = JSApi.JS_Call(ctx, onmessage, worker._self, 1, argv); JSApi.JS_FreeValue(ctx, rval); JSApi.JS_FreeValue(ctx, evt); break; } else { JSApi.JS_FreeValue(ctx, data); } } var exceptionString = ctx.GetExceptionString(); var logger = runtime.GetLogger(); if (logger != null) { logger.Write(LogLevel.Error, exceptionString); } } while (false); } else { // not function } JSApi.JS_FreeValue(ctx, onmessage); } } } finally { buffer.Release(); } }
private static void _EvalSource(ScriptRuntime runtime, JSAction value) { var args = (JSSourceArgs)value.args; runtime.GetMainContext().EvalSource(args.source, args.src); }