示例#1
0
文件: Worker.cs 项目: wclwksn/code
        // who is calling?
        // triggered by InternalInvoke
        static void __worker_onfirstmessage(
            MessageEvent e,

            int InternalThreadCounter,
            object data___string,

            bool[] MethodTargetObjectDataIsProgress,
            object[] MethodTargetObjectData,

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201411/20141112
            object[] MethodTargetObjectDataTypes,

            object MethodTargetTypeIndex,


            // set by ?
            string MethodToken,
            string MethodType,


            object state_ObjectData,
            object stateTypeHandleIndex,
            object state,

            bool IsIProgress,
            //bool IsTuple2_Item1_IsIProgress,

            __Task <object>[] TaskArray
            )
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201501/20150111

            #region ConsoleFormWriter
            var w = new InternalInlineWorkerTextWriter();

            var o = Console.Out;

            Console.SetOut(w);

            w.AtWrite =
                AtWrite =>
            {
                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                //dynamic zdata = new object();
                //zdata.AtWrite = x;

                // working with multiple threads, keep the id in the log!
                // () means we are setting the thread up... [] is the thread
                AtWrite = "[" + Thread.CurrentThread.ManagedThreadId + "] " + AtWrite;

                var zdata = new { AtWrite };



                foreach (MessagePort port in e.ports)
                {
                    port.postMessage((object)zdata, new MessagePort[0]);
                }
            };

            #endregion

            __Thread.InternalCurrentThread.ManagedThreadId = InternalThreadCounter;
            __Thread.InternalCurrentThread.IsBackground    = true;

            // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
            dynamic self = Native.self;

            var stateType = default(Type);

            if (stateTypeHandleIndex != null)
            {
                stateType = Type.GetTypeFromHandle(new __RuntimeTypeHandle((IntPtr)self[stateTypeHandleIndex]));
            }

            // X:\jsc.svn\examples\javascript\async\AsyncNonStaticHandler\AsyncNonStaticHandler\Application.cs
            var MethodTargetType = default(Type);

            if (MethodTargetTypeIndex != null)
            {
                MethodTargetType = Type.GetTypeFromHandle(new __RuntimeTypeHandle((IntPtr)self[MethodTargetTypeIndex]));
            }
            // stateType = <Namespace>.xFoo,



            // MethodTargetTypeIndex = type$GV0nCx_bM8z6My5NDh7GXlQ,

            Console.WriteLine(
                "__worker_onfirstmessage: " +
                new
            {
                Thread.CurrentThread.ManagedThreadId,
                Native.worker.location.href,

                MethodTargetTypeIndex,
                MethodTargetType,

                MethodToken,
                MethodType,


                //IsTuple2_Item1_IsIProgress,


                // X:\jsc.svn\examples\javascript\test\TestTypeHandle\TestTypeHandle\Application.cs
                stateTypeHandleIndex,
                stateType,
                state,
                IsIProgress,

                //MethodTokenReference
            }
                );

            #region MethodTokenReference
            var MethodTokenReference = default(IFunction);
            var MethodTarget         = default(object);

            if (MethodTargetType == null)
            {
                MethodTokenReference = IFunction.Of(MethodToken);
            }
            else
            {
                MethodTarget = FormatterServices.GetUninitializedObject(MethodTargetType);

                var MethodTargetTypeSerializableMembers = FormatterServices.GetSerializableMembers(MethodTargetType);

                // X:\jsc.svn\examples\javascript\async\test\TestWorkerScopeProgress\TestWorkerScopeProgress\Application.cs

                for (int i = 0; i < MethodTargetTypeSerializableMembers.Length; i++)
                {
                    var xMember     = MethodTargetTypeSerializableMembers[i] as FieldInfo;
                    var xObjectData = MethodTargetObjectData[i];

                    var xMethodTargetObjectDataTypeIndex = MethodTargetObjectDataTypes[i];


                    var xIsProgress = MethodTargetObjectDataIsProgress[i];

                    // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServer\ChromeTCPServer\Application.cs
                    // does our chrome tcp server get the damn path?
                    Console.WriteLine(new { xMember, xMethodTargetObjectDataTypeIndex, xObjectData, xIsProgress });

                    // need to resurrect the semaphores!
                    // X:\jsc.svn\examples\javascript\async\Test\TestSemaphoreSlim\TestSemaphoreSlim\ApplicationControl.cs


                    #region MethodTargetObjectDataIsProgress
                    // cant we use xMethodTargetObjectDataType instead?
                    if (xIsProgress)
                    {
                        var ii = i;
                        MethodTargetObjectData[ii] = new __Progress <object>(
                            ProgressEvent =>
                        {
                            // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                            dynamic zdata = new object();

                            zdata.MethodTargetObjectDataProgressReport = new { ProgressEvent, ii };

                            foreach (MessagePort port in e.ports)
                            {
                                port.postMessage((object)zdata, new MessagePort[0]);
                            }

                            //Console.WriteLine(new { MethodTargetTypeSerializableMember, MethodTargetTypeSerializableMemberIsProgress, ProgressEvent });
                        }
                            );
                    }
                    #endregion

                    else
                    {
                        var xMethodTargetObjectDataType = default(Type);
                        if (xMethodTargetObjectDataTypeIndex != null)
                        {
                            xMethodTargetObjectDataType = Type.GetTypeFromHandle(new __RuntimeTypeHandle((IntPtr)self[xMethodTargetObjectDataTypeIndex]));
                        }

                        // now we know the type. should we review it?

                        if (xMethodTargetObjectDataType != null)
                        {
                            var scope2copy = FormatterServices.GetUninitializedObject(xMethodTargetObjectDataType);

                            //shall we copy the members too?
                            //FormatterServices.PopulateObjectMembers(scope2copy, scope2TypeSerializableMembers, scope2ObjectData);

                            MethodTargetObjectData[i] = scope2copy;

                            #region __SemaphoreSlim
                            // X:\jsc.svn\examples\javascript\async\Test\TestSemaphoreSlim\TestSemaphoreSlim\ApplicationControl.cs
                            var xSemaphoreSlim = scope2copy as __SemaphoreSlim;
                            if (xSemaphoreSlim != null)
                            {
                                // we now have to complete the entanglement. we have the caller on the UI.

                                Action <string> WriteLine0 = text =>
                                {
                                    Console.WriteLine("(" + xMember.Name + ") " + text);
                                };


                                //xSemaphoreSlim.InternalIsEntangled = true;



                                #region InternalVirtualWaitAsync
                                var xInternalVirtualWaitAsync = default(TaskCompletionSource <object>);

                                xSemaphoreSlim.InternalVirtualWaitAsync += continuation =>
                                {
                                    WriteLine0("enter xSemaphoreSlim.InternalVirtualWaitAsync, worker is now awaiting for signal");

                                    xInternalVirtualWaitAsync = continuation;
                                };

                                // at this point lets call the UI to set up a new signal channel..

                                //new MessageChannel();

                                var c = new MessageChannel();

                                c.port1.onmessage +=
                                    ce =>
                                {
                                    // ui has released?

                                    if (xInternalVirtualWaitAsync == null)
                                    {
                                        // what if the thread is not yet awaiting?
                                        WriteLine0("ui has sent a release signal, yet nobody awaiting");
                                        return;
                                    }

                                    WriteLine0("ui has sent a release signal, resync");

                                    // we should have byte fields now.
                                    // next strings as in thread hopping...

                                    dynamic data = ce.data;

                                    #region read xSemaphoreSlim_ByteArrayFields
                                    {
                                        __Task.xByteArrayField[] xSemaphoreSlim_ByteArrayFields = data.xSemaphoreSlim_ByteArrayFields;

                                        // X:\jsc.svn\examples\javascript\async\test\TestBytesToSemaphore\TestBytesToSemaphore\Application.cs
                                        if (xSemaphoreSlim_ByteArrayFields != null)
                                        {
                                            foreach (var item in xSemaphoreSlim_ByteArrayFields)
                                            {
                                                var xFieldInfo = (FieldInfo)MethodTargetTypeSerializableMembers[item.index];

                                                // can we set the value?
                                                WriteLine0("worker resync " + new
                                                {
                                                    item.index,
                                                    //item.Name,
                                                    xFieldInfo = xFieldInfo.Name,
                                                    item.value
                                                });

                                                xFieldInfo.SetValue(
                                                    MethodTarget,

                                                    // null?
                                                    item.value
                                                    );
                                            }
                                        }
                                    }
                                    #endregion

                                    xInternalVirtualWaitAsync.SetResult(null);
                                };

                                c.port1.start();
                                c.port2.start();

                                WriteLine0("will set up the signal channel");

                                foreach (var p in e.ports)
                                {
                                    p.postMessage(
                                        new { xSemaphoreSlim = xMember.Name },
                                        transfer: new[] { c.port2 }
                                        );
                                }
                                #endregion


                                #region InternalVirtualRelease
                                xSemaphoreSlim.InternalVirtualRelease += delegate
                                {
                                    WriteLine0("enter xSemaphoreSlim.InternalVirtualRelease, will send a signal to ui...");

                                    // worker needs sync data about now.
                                    // the ui would be happy to have the latest version of the data.
                                    // this is tricky. we would really need to know which data fields have changed by now
                                    // and what will happen if the data was also changed on the ui.
                                    // technically we are doing a merge conflict resolver...

                                    // this is somewhat the same situation, we alrady have
                                    // when entering a worker
                                    // when exiting a worker
                                    // when hoping to or from a worker.

                                    // what data fields do we have to upload yo ui?
                                    // how much IL analysis is available for us to know what to sync
                                    // we should not sync fields that wont be used on the ui

                                    // the thread hop looks at strings only right now, as they are immputable yet primitive
                                    // what about bytewarrays?
                                    // X:\jsc.svn\examples\javascript\async\test\TestBytesFromSemaphore\TestBytesFromSemaphore\Application.cs

                                    #region xSemaphoreSlim_ByteArrayFields
                                    var xSemaphoreSlim_ByteArrayFields = new List <__Task.xByteArrayField>();


                                    var MethodTargetTypeSerializableMembers_index = 0;
                                    foreach (FieldInfo item in MethodTargetTypeSerializableMembers)
                                    {
                                        // how would we know if the array is a byte array?

                                        // FieldType is not exactly available yet
                                        //Console.WriteLine("worker resync candidate " + new { item.Name, item.FieldType, item.FieldType.IsArray });

                                        var item_value = item.GetValue(MethodTarget);
                                        if (item_value != null)
                                        {
                                            var item_value_constructor = Expando.Of(item_value).constructor;
                                            var item_value_IsByteArray = Native.self_Uint8ClampedArray == item_value_constructor;

                                            if (item_value_IsByteArray)
                                            {
                                                var value = (byte[])item_value;

                                                xSemaphoreSlim_ByteArrayFields.Add(
                                                    new __Task.xByteArrayField
                                                {
                                                    index = MethodTargetTypeSerializableMembers_index,

                                                    // keep name for diagnostics
                                                    Name = item.Name,

                                                    value = value
                                                }
                                                    );

                                                WriteLine0("worker resync xByteArrayField candidate " + new { item.Name, value.Length });
                                            }
                                        }


                                        MethodTargetTypeSerializableMembers_index++;
                                    }
                                    #endregion


                                    foreach (var p in e.ports)
                                    {
                                        p.postMessage(
                                            new
                                        {
                                            xSemaphoreSlim = xMember.Name,
                                            xSemaphoreSlim_ByteArrayFields = xSemaphoreSlim_ByteArrayFields.ToArray()
                                        }
                                            );
                                    }
                                };
                                #endregion
                            }
                            #endregion
                        }
                    }
                }

                FormatterServices.PopulateObjectMembers(
                    MethodTarget,
                    MethodTargetTypeSerializableMembers,
                    MethodTargetObjectData
                    );



                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                MethodTokenReference = (MethodTarget as dynamic)[MethodToken];
            }

            // what if we are being called from within a secondary app?

            //  stateTypeHandleIndex = type$XjKww8iSKT_aFTpY_bSs5vBQ,
            if (MethodTokenReference == null)
            {
                // tested at
                // X:\jsc.svn\examples\javascript\WorkerInsideSecondaryApplication\WorkerInsideSecondaryApplication\Application.cs


                // X:\jsc.svn\examples\javascript\Test\TestHopToThreadPoolAwaitable\TestHopToThreadPoolAwaitable\Application.cs
                // why?
                throw new InvalidOperationException(
                          new { MethodToken } +" function is not available at " + new { Native.worker.location.href }
                          );
            }
            #endregion

            //Console.WriteLine(
            //     new
            //     {
            //         MethodTokenReference,
            //         Thread.CurrentThread.ManagedThreadId
            //     }
            // );

            // whats the type?



            #region xstate
            var xstate = default(object);

            if (stateType != null)
            {
                xstate = FormatterServices.GetUninitializedObject(stateType);
                var xstate_SerializableMembers = FormatterServices.GetSerializableMembers(stateType);

                FormatterServices.PopulateObjectMembers(
                    xstate,
                    xstate_SerializableMembers,
                    (object[])state_ObjectData
                    );

                // MethodType = FuncOfObjectToObject
                //Console.WriteLine("as FuncOfObjectToObject");
            }
            #endregion

            #region CreateProgress
            Func <__Progress <object> > CreateProgress =
                () => new __Progress <object>(
                    value =>
            {
                //Console.WriteLine("__IProgress_Report " + new { value });

                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                dynamic zdata = new object();

                zdata.__IProgress_Report = new { value };

                foreach (MessagePort port in e.ports)
                {
                    port.postMessage((object)zdata, new MessagePort[0]);
                }
            }
                    );

            // X:\jsc.svn\examples\javascript\async\Test\TestWorkerProgress\TestWorkerProgress\Application.cs
            if (IsIProgress)
            {
                xstate = CreateProgress();
            }


            #endregion



            #region __string
            // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
            dynamic target = __string;
            var     m      = Expando.Of(data___string).GetMembers();
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201308/20130826-domainmemory
            foreach (ExpandoMember nn in m)
            {
                target[nn.Name] = nn.Value;

                var trigger         = "set_" + nn.Name;
                var trigger_default = IFunction.Of(trigger);

                (Native.self as dynamic)[trigger] = IFunction.OfDelegate(
                    new Action <string>(
                        Value =>
                {
                    if (nn.Value == Value)
                    {
                        return;
                    }

                    trigger_default.apply(null, Value);

                    #region sync one field only

                    {
                        dynamic zdata          = new object();
                        dynamic zdata___string = new object();

                        zdata.__string = zdata___string;


                        zdata___string[nn.Name] = Value;

                        // prevent sync via diff
                        nn.Value = Value;

                        foreach (MessagePort port in e.ports)
                        {
                            port.postMessage((object)zdata, new MessagePort[0]);
                        }
                    }


                    #endregion
                }
                        )
                    );
            }
            #endregion


            {
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201308/20130828-thread-run
                // for now we only support static calls


                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                dynamic zdata = new object();


                if (MethodType == typeof(ActionOfDedicatedWorkerGlobalScope).Name)
                {
                    MethodTokenReference.apply(null, Native.worker);
                }
                else if (MethodType == typeof(FuncOfObjectToObject).Name)
                {
                    //Console.WriteLine("worker Task Run function call");


                    #region FuncOfObjectToObject
                    // X:\jsc.svn\examples\javascript\test\TestTaskStartToString\TestTaskStartToString\Application.cs
                    // X:\jsc.svn\examples\javascript\async\test\TestTaskRun\TestTaskRun\Application.cs
                    // X:\jsc.svn\examples\javascript\Test\TestGetUninitializedObject\TestGetUninitializedObject\Application.cs


                    var value = MethodTokenReference.apply(MethodTarget, xstate);

                    // X:\jsc.svn\examples\javascript\async\test\TaskAsyncTaskRun\TaskAsyncTaskRun\Application.cs

                    // whatif its an Action not a Func?
                    //enter HopToThreadPoolAwaitable yield HopToUIAwaitable
                    //worker Task Run function has returned {{ value_Task = null, value_TaskOfT = null }}
                    //__Task.InternalStart inner complete {{ yield = {{ value = null }} }}

                    var value_Task    = value as __Task;
                    var value_TaskOfT = value as __Task <object>;

                    // if we are in a hop. allow the return task to be overriden.
                    if (InternalOverrideTaskOfT != null)
                    {
                        value_TaskOfT = InternalOverrideTaskOfT;
                    }


                    // 0:25611ms Task Run function has returned { value_Task = [object Object], value_TaskOfT = [object Object] }
                    //Console.WriteLine("worker Task Run function has returned " + new { value_Task, value_TaskOfT, InternalOverrideTaskOfT });
                    // 0:4284ms Task Run function has returned { value_Task = { IsCompleted = 1, Result =  }, value_TaskOfT = { IsCompleted = 1, Result =  } }
                    // 0:5523ms Task Run function has returned { value_Task = { IsCompleted = false, Result =  }, value_TaskOfT = { IsCompleted = false, Result =  } }

                    if (value_TaskOfT != null)
                    {
                        // special situation

                        // if IsCompleted, called twice? or heard twice?
                        value_TaskOfT.ContinueWith(
                            t =>
                        {
                            //Console.WriteLine("worker Task Run ContinueWith " + new { t });


                            // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                            dynamic zzdata = new object();

                            // null?
                            if (t.Result == null)
                            {
                                zzdata.ContinueWithResult = new { t.Result };
                                foreach (MessagePort port in e.ports)
                                {
                                    port.postMessage((object)zzdata, new MessagePort[0]);
                                }
                                return;
                            }

                            var ResultType      = t.Result.GetType();
                            var ResultTypeIndex = __Type.GetTypeIndex("workerResult", ResultType);

                            var ResultTypeSerializableMembers = FormatterServices.GetSerializableMembers(ResultType);
                            var ResultObjectData = FormatterServices.GetObjectData(t.Result, ResultTypeSerializableMembers);

                            var ContinueWithResult = new
                            {
                                ResultTypeIndex,
                                ResultObjectData,

                                t.Result
                            };

                            zzdata.ContinueWithResult = ContinueWithResult;

                            foreach (MessagePort port in e.ports)
                            {
                                port.postMessage((object)zzdata, new MessagePort[0]);
                            }
                        }
                            );
                    }
                    else
                    {
                        if (value_Task != null)
                        {
                            // X:\jsc.svn\examples\javascript\async\test\TestWorkerScopeProgress\TestWorkerScopeProgress\Application.cs

                            throw new NotImplementedException();
                        }
                        else
                        {
                            var yield = new { value };

                            //Console.WriteLine(new { yield });

                            zdata.yield = yield;
                        }
                    }
                    #endregion
                    // now what?
                }
                else if (MethodType == typeof(FuncOfTaskToObject).Name)
                {
                    // tested by?
                    #region FuncOfTaskToObject
                    // need to reconstruct the caller task?


                    var value = MethodTokenReference.apply(null, TaskArray.Single());
                    var yield = new { value };

                    //Console.WriteLine(new { yield });

                    zdata.yield = yield;
                    #endregion
                    // now what?
                }
                else if (MethodType == typeof(FuncOfTaskOfObjectArrayToObject).Name)
                {
                    // tested by?

                    #region FuncOfTaskOfObjectArrayToObject
                    // need to reconstruct the caller task?

                    Console.WriteLine("__worker_onfirstmessage: " + new { TaskArray = TaskArray.Length });

                    //Debugger.Break();

                    var args = new object[] { TaskArray };

                    var value = MethodTokenReference.apply(
                        o: null,

                        // watch out
                        args: args
                        );

                    var yield = new { value };

                    //Console.WriteLine(new { yield });

                    zdata.yield = yield;
                    #endregion
                    // now what?
                }

                #region [sync] diff and upload changes to DOM context, the latest now
                {
                    dynamic zdata___string = new object();

                    zdata.__string = zdata___string;

                    foreach (ExpandoMember nn in m)
                    {
                        string Value = (string)Expando.InternalGetMember((object)target, nn.Name);
                        // this is preferred:
                        //string Value = target[nn.Name];

                        if (Value != nn.Value)
                        {
                            zdata___string[nn.Name] = Value;
                        }
                    }
                }
                #endregion

                //e.post
                foreach (MessagePort port in e.ports)
                {
                    port.postMessage((object)zdata, new MessagePort[0]);
                }
            }
        }
示例#2
0
        // who is calling?
        // triggered by InternalInvoke
        static void __worker_onfirstmessage(
            MessageEvent e,

            int InternalThreadCounter,
             object data___string,

            bool[] MethodTargetObjectDataIsProgress,
            object[] MethodTargetObjectData,

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201411/20141112
            object[] MethodTargetObjectDataTypes,

            object MethodTargetTypeIndex,


              // set by ?
              string MethodToken,
            string MethodType,


            object state_ObjectData,
            object stateTypeHandleIndex,
            object state,

            bool IsIProgress,
            //bool IsTuple2_Item1_IsIProgress,

            __Task<object>[] TaskArray
            )
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201501/20150111

            #region ConsoleFormWriter
            var w = new InternalInlineWorkerTextWriter();

            var o = Console.Out;

            Console.SetOut(w);

            w.AtWrite =
                 AtWrite =>
                 {
                     // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                     //dynamic zdata = new object();
                     //zdata.AtWrite = x;

                     // working with multiple threads, keep the id in the log!
                     // () means we are setting the thread up... [] is the thread
                     AtWrite = "W[" + Thread.CurrentThread.ManagedThreadId + "] " + AtWrite;

                     var zdata = new { AtWrite };



                     foreach (MessagePort port in e.ports)
                     {


                         port.postMessage((object)zdata, new MessagePort[0]);
                     }

                 };

            #endregion

            __Thread.InternalCurrentThread.ManagedThreadId = InternalThreadCounter;
            __Thread.InternalCurrentThread.IsBackground = true;

            // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
            dynamic self = Native.self;

            var stateType = default(Type);

            if (stateTypeHandleIndex != null)
                stateType = Type.GetTypeFromHandle(new __RuntimeTypeHandle((IntPtr)self[stateTypeHandleIndex]));

            // X:\jsc.svn\examples\javascript\async\AsyncNonStaticHandler\AsyncNonStaticHandler\Application.cs
            var MethodTargetType = default(Type);

            if (MethodTargetTypeIndex != null)
                MethodTargetType = Type.GetTypeFromHandle(new __RuntimeTypeHandle((IntPtr)self[MethodTargetTypeIndex]));
            // stateType = <Namespace>.xFoo,



            // MethodTargetTypeIndex = type$GV0nCx_bM8z6My5NDh7GXlQ, 

            Console.WriteLine(
                "__worker_onfirstmessage: " +
                new
                {
                    Thread.CurrentThread.ManagedThreadId,
                    Native.worker.location.href,

                    MethodTargetTypeIndex,
                    MethodTargetType,

                    MethodToken,
                    MethodType,


                    //IsTuple2_Item1_IsIProgress,


                    // X:\jsc.svn\examples\javascript\test\TestTypeHandle\TestTypeHandle\Application.cs
                    stateTypeHandleIndex,
                    stateType,
                    state,
                    IsIProgress,

                    //MethodTokenReference
                }
            );

            #region MethodTokenReference
            var MethodTokenReference = default(IFunction);
            var MethodTarget = default(object);

            if (MethodTargetType == null)
            {
                MethodTokenReference = IFunction.Of(MethodToken);
            }
            else
            {
                MethodTarget = FormatterServices.GetUninitializedObject(MethodTargetType);

                var MethodTargetTypeSerializableMembers = FormatterServices.GetSerializableMembers(MethodTargetType);

                // X:\jsc.svn\examples\javascript\async\test\TestWorkerScopeProgress\TestWorkerScopeProgress\Application.cs

                for (int i = 0; i < MethodTargetTypeSerializableMembers.Length; i++)
                {
                    var xMember = MethodTargetTypeSerializableMembers[i] as FieldInfo;
                    var xObjectData = MethodTargetObjectData[i];

                    var xMethodTargetObjectDataTypeIndex = MethodTargetObjectDataTypes[i];


                    var xIsProgress = MethodTargetObjectDataIsProgress[i];

                    // X:\jsc.svn\examples\javascript\chrome\apps\ChromeTCPServer\ChromeTCPServer\Application.cs
                    // does our chrome tcp server get the damn path?
                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150428
                    //Console.WriteLine(new { xMember, xMethodTargetObjectDataTypeIndex, xObjectData, xIsProgress });
                    Console.WriteLine(new { xMember, xMethodTargetObjectDataTypeIndex, xIsProgress });

                    // need to resurrect the semaphores!
                    // X:\jsc.svn\examples\javascript\async\Test\TestSemaphoreSlim\TestSemaphoreSlim\ApplicationControl.cs


                    #region MethodTargetObjectDataIsProgress
                    // cant we use xMethodTargetObjectDataType instead?
                    if (xIsProgress)
                    {

                        var ii = i;
                        MethodTargetObjectData[ii] = new __Progress<object>(
                            ProgressEvent =>
                            {
                                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                                dynamic zdata = new object();

                                zdata.MethodTargetObjectDataProgressReport = new { ProgressEvent, ii };

                                foreach (MessagePort port in e.ports)
                                {
                                    port.postMessage((object)zdata, new MessagePort[0]);
                                }

                                //Console.WriteLine(new { MethodTargetTypeSerializableMember, MethodTargetTypeSerializableMemberIsProgress, ProgressEvent });
                            }
                        );
                    }
                    #endregion

                    else
                    {
                        var xMethodTargetObjectDataType = default(Type);
                        if (xMethodTargetObjectDataTypeIndex != null)
                            xMethodTargetObjectDataType = Type.GetTypeFromHandle(new __RuntimeTypeHandle((IntPtr)self[xMethodTargetObjectDataTypeIndex]));

                        // now we know the type. should we review it?

                        if (xMethodTargetObjectDataType != null)
                        {
                            var scope2copy = FormatterServices.GetUninitializedObject(xMethodTargetObjectDataType);

                            //shall we copy the members too?
                            //FormatterServices.PopulateObjectMembers(scope2copy, scope2TypeSerializableMembers, scope2ObjectData);

                            MethodTargetObjectData[i] = scope2copy;

                            #region __SemaphoreSlim
                            // X:\jsc.svn\examples\javascript\async\Test\TestSemaphoreSlim\TestSemaphoreSlim\ApplicationControl.cs
                            var xSemaphoreSlim = scope2copy as __SemaphoreSlim;
                            if (xSemaphoreSlim != null)
                            {
                                // we now have to complete the entanglement. we have the caller on the UI.

                                Action<string> UIWriteLine0 = text =>
                                {
                                    // mimick roslyn syntax
                                    Console.WriteLine("$" + xMember.Name + " " + text);
                                };


                                //xSemaphoreSlim.InternalIsEntangled = true;




                                #region InternalVirtualWaitAsync
                                var xInternalVirtualWaitAsync = default(TaskCompletionSource<object>);

                                xSemaphoreSlim.InternalVirtualWaitAsync += continuation =>
                                {
                                    UIWriteLine0("enter xSemaphoreSlim.InternalVirtualWaitAsync, worker is now awaiting for signal " + new { xSemaphoreSlim.Name });

                                    xInternalVirtualWaitAsync = continuation;
                                };

                                // at this point lets call the UI to set up a new signal channel..

                                //new MessageChannel();

                                var c = new MessageChannel();

                                c.port1.onmessage +=
                                    ce =>
                                    {
                                        // ui has released?

                                        if (xInternalVirtualWaitAsync == null)
                                        {
                                            // what if the thread is not yet awaiting?
                                            UIWriteLine0("ui has sent a release signal, yet nobody awaiting");
                                            return;
                                        }

                                        UIWriteLine0("ui has sent a release signal, resync");

                                        // we should have byte fields now.
                                        // next strings as in thread hopping...

                                        dynamic data = ce.data;

                                        #region read xSemaphoreSlim_ByteArrayFields
                                        {
                                            __Task.xByteArrayField[] xSemaphoreSlim_ByteArrayFields = data.xSemaphoreSlim_ByteArrayFields;

                                            // X:\jsc.svn\examples\javascript\async\test\TestBytesToSemaphore\TestBytesToSemaphore\Application.cs
                                            if (xSemaphoreSlim_ByteArrayFields != null)
                                                foreach (var item in xSemaphoreSlim_ByteArrayFields)
                                                {
                                                    var xFieldInfo = (FieldInfo)MethodTargetTypeSerializableMembers[item.index];

                                                    // X:\jsc.svn\examples\javascript\chrome\apps\ChromeThreadedCameraTracker\ChromeThreadedCameraTracker\Application.cs

                                                    // can we set the value?
                                                    UIWriteLine0("worker resync " + new
                                                    {
                                                        item.index,
                                                        //item.Name,
                                                        xFieldInfo = xFieldInfo.Name,
                                                        //item.value
                                                    });

                                                    xFieldInfo.SetValue(
                                                        MethodTarget,

                                                        // null?
                                                        item.value
                                                    );

                                                }
                                        }
                                        #endregion

                                        xInternalVirtualWaitAsync.SetResult(null);
                                    };

                                c.port1.start();
                                c.port2.start();

                                UIWriteLine0("will set up the signal channel");

                                foreach (var p in e.ports)
                                {
                                    p.postMessage(
                                        new { xSemaphoreSlim = xMember.Name },
                                        transfer: new[] { c.port2 }
                                    );
                                }
                                #endregion


                                #region InternalVirtualRelease
                                xSemaphoreSlim.InternalVirtualRelease += delegate
                                {
                                    UIWriteLine0("enter xSemaphoreSlim.InternalVirtualRelease, will send a signal to ui...");

                                    // worker needs sync data about now.
                                    // the ui would be happy to have the latest version of the data.
                                    // this is tricky. we would really need to know which data fields have changed by now
                                    // and what will happen if the data was also changed on the ui.
                                    // technically we are doing a merge conflict resolver...

                                    // this is somewhat the same situation, we alrady have
                                    // when entering a worker
                                    // when exiting a worker
                                    // when hoping to or from a worker.

                                    // what data fields do we have to upload yo ui?
                                    // how much IL analysis is available for us to know what to sync
                                    // we should not sync fields that wont be used on the ui

                                    // the thread hop looks at strings only right now, as they are immputable yet primitive
                                    // what about bytewarrays?
                                    // X:\jsc.svn\examples\javascript\async\test\TestBytesFromSemaphore\TestBytesFromSemaphore\Application.cs

                                    #region xSemaphoreSlim_ByteArrayFields
                                    var xSemaphoreSlim_ByteArrayFields = new List<__Task.xByteArrayField>();


                                    var MethodTargetTypeSerializableMembers_index = 0;
                                    foreach (FieldInfo item in MethodTargetTypeSerializableMembers)
                                    {
                                        // how would we know if the array is a byte array?

                                        // FieldType is not exactly available yet
                                        //Console.WriteLine("worker resync candidate " + new { item.Name, item.FieldType, item.FieldType.IsArray });

                                        var item_value = item.GetValue(MethodTarget);
                                        if (item_value != null)
                                        {
                                            var item_value_constructor = Expando.Of(item_value).constructor;
                                            var item_value_IsByteArray = Native.self_Uint8ClampedArray == item_value_constructor;

                                            if (item_value_IsByteArray)
                                            {
                                                var value = (byte[])item_value;

                                                xSemaphoreSlim_ByteArrayFields.Add(
                                                    new __Task.xByteArrayField
                                                    {
                                                        index = MethodTargetTypeSerializableMembers_index,

                                                        // keep name for diagnostics
                                                        Name = item.Name,

                                                        value = value
                                                    }
                                                );

                                                UIWriteLine0("worker resync xByteArrayField candidate " + new { item.Name, value.Length });
                                            }
                                        }


                                        MethodTargetTypeSerializableMembers_index++;
                                    }
                                    #endregion


                                    foreach (var p in e.ports)
                                    {
                                        p.postMessage(
                                            new
                                            {
                                                xSemaphoreSlim = xMember.Name,
                                                xSemaphoreSlim_ByteArrayFields = xSemaphoreSlim_ByteArrayFields.ToArray()
                                            }
                                        );
                                    }
                                };
                                #endregion


                            }
                            #endregion
                        }
                    }
                }

                FormatterServices.PopulateObjectMembers(
                    MethodTarget,
                    MethodTargetTypeSerializableMembers,
                    MethodTargetObjectData
                );



                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                MethodTokenReference = (MethodTarget as dynamic)[MethodToken];
            }

            // what if we are being called from within a secondary app?

            //  stateTypeHandleIndex = type$XjKww8iSKT_aFTpY_bSs5vBQ,
            if (MethodTokenReference == null)
            {
                // tested at
                // X:\jsc.svn\examples\javascript\WorkerInsideSecondaryApplication\WorkerInsideSecondaryApplication\Application.cs


                // X:\jsc.svn\examples\javascript\Test\TestHopToThreadPoolAwaitable\TestHopToThreadPoolAwaitable\Application.cs
                // why?
                throw new InvalidOperationException(
                    new { MethodToken } + " function is not available at " + new { Native.worker.location.href }
                );
            }
            #endregion

            //Console.WriteLine(
            //     new
            //     {
            //         MethodTokenReference,
            //         Thread.CurrentThread.ManagedThreadId
            //     }
            // );

            // whats the type?



            #region xstate
            var xstate = default(object);

            if (stateType != null)
            {
                xstate = FormatterServices.GetUninitializedObject(stateType);
                var xstate_SerializableMembers = FormatterServices.GetSerializableMembers(stateType);

                FormatterServices.PopulateObjectMembers(
                    xstate,
                    xstate_SerializableMembers,
                    (object[])state_ObjectData
                );

                // MethodType = FuncOfObjectToObject
                //Console.WriteLine("as FuncOfObjectToObject");
            }
            #endregion

            #region CreateProgress
            Func<__Progress<object>> CreateProgress =
                () => new __Progress<object>(
                    value =>
                    {
                        //Console.WriteLine("__IProgress_Report " + new { value });

                        // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                        dynamic zdata = new object();

                        zdata.__IProgress_Report = new { value };

                        foreach (MessagePort port in e.ports)
                        {
                            port.postMessage((object)zdata, new MessagePort[0]);
                        }
                    }
                );

            // X:\jsc.svn\examples\javascript\async\Test\TestWorkerProgress\TestWorkerProgress\Application.cs
            if (IsIProgress)
                xstate = CreateProgress();


            #endregion



            #region __string
            // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
            dynamic target = __string;
            var m = Expando.Of(data___string).GetMembers();
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201308/20130826-domainmemory
            foreach (ExpandoMember nn in m)
            {
                target[nn.Name] = nn.Value;

                var trigger = "set_" + nn.Name;
                var trigger_default = IFunction.Of(trigger);

                (Native.self as dynamic)[trigger] = IFunction.OfDelegate(
                    new Action<string>(
                        Value =>
                        {
                            if (nn.Value == Value)
                                return;

                            trigger_default.apply(null, Value);

                            #region sync one field only

                            {
                                dynamic zdata = new object();
                                dynamic zdata___string = new object();

                                zdata.__string = zdata___string;


                                zdata___string[nn.Name] = Value;

                                // prevent sync via diff
                                nn.Value = Value;

                                foreach (MessagePort port in e.ports)
                                {
                                    port.postMessage((object)zdata, new MessagePort[0]);
                                }

                            }


                            #endregion
                        }
                    )
                );
            }
            #endregion


            {
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201308/20130828-thread-run
                // for now we only support static calls


                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                dynamic zdata = new object();


                if (MethodType == typeof(ActionOfDedicatedWorkerGlobalScope).Name)
                {
                    MethodTokenReference.apply(null, Native.worker);
                }
                else if (MethodType == typeof(FuncOfObjectToObject).Name)
                {
                    Console.WriteLine("worker Task Run function call, FuncOfObjectToObject, will invoke MethodTokenReference");


                    #region FuncOfObjectToObject
                    // X:\jsc.svn\examples\javascript\test\TestTaskStartToString\TestTaskStartToString\Application.cs
                    // X:\jsc.svn\examples\javascript\async\test\TestTaskRun\TestTaskRun\Application.cs
                    // X:\jsc.svn\examples\javascript\Test\TestGetUninitializedObject\TestGetUninitializedObject\Application.cs


                    var value = MethodTokenReference.apply(MethodTarget, xstate);

                    Console.WriteLine("worker Task Run function call, FuncOfObjectToObject, will invoke MethodTokenReference " + new { value });


                    // X:\jsc.svn\examples\javascript\async\test\TaskAsyncTaskRun\TaskAsyncTaskRun\Application.cs

                    // whatif its an Action not a Func?
                    //enter HopToThreadPoolAwaitable yield HopToUIAwaitable
                    //worker Task Run function has returned {{ value_Task = null, value_TaskOfT = null }}
                    //__Task.InternalStart inner complete {{ yield = {{ value = null }} }}

                    var value_Task = value as __Task;
                    var value_TaskOfT = value as __Task<object>;

                    // if we are in a hop. allow the return task to be overriden.
                    if (InternalOverrideTaskOfT != null)
                        value_TaskOfT = InternalOverrideTaskOfT;


                    // 0:25611ms Task Run function has returned { value_Task = [object Object], value_TaskOfT = [object Object] } 
                    //Console.WriteLine("worker Task Run function has returned " + new { value_Task, value_TaskOfT, InternalOverrideTaskOfT });
                    // 0:4284ms Task Run function has returned { value_Task = { IsCompleted = 1, Result =  }, value_TaskOfT = { IsCompleted = 1, Result =  } } 
                    // 0:5523ms Task Run function has returned { value_Task = { IsCompleted = false, Result =  }, value_TaskOfT = { IsCompleted = false, Result =  } } 

                    if (value_TaskOfT != null)
                    {
                        // special situation

                        // if IsCompleted, called twice? or heard twice?
                        value_TaskOfT.ContinueWith(
                            t =>
                            {
                                //Console.WriteLine("worker Task Run ContinueWith " + new { t });


                                // X:\jsc.svn\examples\javascript\Test\Test435CoreDynamic\Test435CoreDynamic\Class1.cs
                                dynamic zzdata = new object();

                                // null?
                                if (t.Result == null)
                                {
                                    zzdata.ContinueWithResult = new { t.Result };
                                    foreach (MessagePort port in e.ports)
                                    {
                                        port.postMessage((object)zzdata, new MessagePort[0]);
                                    }
                                    return;
                                }

                                var ResultType = t.Result.GetType();
                                var ResultTypeIndex = __Type.GetTypeIndex("workerResult", ResultType);

                                var ResultTypeSerializableMembers = FormatterServices.GetSerializableMembers(ResultType);
                                var ResultObjectData = FormatterServices.GetObjectData(t.Result, ResultTypeSerializableMembers);

                                var ContinueWithResult = new
                                {
                                    ResultTypeIndex,
                                    ResultObjectData,

                                    t.Result

                                };

                                zzdata.ContinueWithResult = ContinueWithResult;

                                foreach (MessagePort port in e.ports)
                                {
                                    port.postMessage((object)zzdata, new MessagePort[0]);
                                }
                            }
                        );

                    }
                    else
                    {

                        if (value_Task != null)
                        {
                            // X:\jsc.svn\examples\javascript\async\test\TestWorkerScopeProgress\TestWorkerScopeProgress\Application.cs

                            throw new NotImplementedException();
                        }
                        else
                        {

                            var yield = new { value };

                            //Console.WriteLine(new { yield });

                            Console.WriteLine("worker Task Run function call, FuncOfObjectToObject, will yield? " + new { value_Task, value_TaskOfT });

                            zdata.yield = yield;
                        }
                    }
                    #endregion
                    // now what?
                }
                else if (MethodType == typeof(FuncOfTaskToObject).Name)
                {
                    Console.WriteLine("bugcheck FuncOfTaskToObject ?");

                    // tested by?
                    #region FuncOfTaskToObject
                    // need to reconstruct the caller task?


                    var value = MethodTokenReference.apply(null, TaskArray.Single());
                    var yield = new { value };

                    //Console.WriteLine(new { yield });

                    zdata.yield = yield;
                    #endregion
                    // now what?
                }
                else if (MethodType == typeof(FuncOfTaskOfObjectArrayToObject).Name)
                {
                    // tested by?

                    #region FuncOfTaskOfObjectArrayToObject
                    // need to reconstruct the caller task?

                    Console.WriteLine("__worker_onfirstmessage: " + new { TaskArray = TaskArray.Length });

                    //Debugger.Break();

                    var args = new object[] { TaskArray };

                    var value = MethodTokenReference.apply(
                        o: null,

                        // watch out
                        args: args
                    );

                    var yield = new { value };

                    //Console.WriteLine(new { yield });

                    zdata.yield = yield;
                    #endregion
                    // now what?
                }

                #region [sync] diff and upload changes to DOM context, the latest now
                {
                    dynamic zdata___string = new object();

                    zdata.__string = zdata___string;

                    foreach (ExpandoMember nn in m)
                    {
                        string Value = (string)Expando.InternalGetMember((object)target, nn.Name);
                        // this is preferred:
                        //string Value = target[nn.Name];

                        if (Value != nn.Value)
                        {
                            zdata___string[nn.Name] = Value;
                        }
                    }




                }
                #endregion

                //e.post
                foreach (MessagePort port in e.ports)
                {
                    port.postMessage((object)zdata, new MessagePort[0]);
                }
            }
        }