Browse Source

* Refactored

Michael Van Canneyt 4 months ago
parent
commit
ed2558bd86
1 changed files with 13 additions and 895 deletions
  1. 13 895
      packages/wasi/src/wasiworkerthreadhost.pas

+ 13 - 895
packages/wasi/src/wasiworkerthreadhost.pas

@@ -1,5 +1,5 @@
 {$IFNDEF FPC_DOTTEDUNITS}
 {$IFNDEF FPC_DOTTEDUNITS}
-unit wasiworkerthreadhost;
+unit wasiworkerthreadhost deprecated 'use rtl.threadrunner or rtl.workerthreadhost';
 {$ENDIF}
 {$ENDIF}
 
 
 {$mode ObjFPC}
 {$mode ObjFPC}
@@ -10,918 +10,36 @@ interface
 
 
 uses
 uses
 {$IFDEF FPC_DOTTEDUNITS}
 {$IFDEF FPC_DOTTEDUNITS}
-  System.Classes, System.SysUtils, JSApi.JS, Fcl.CustApp, BrowserApi.WebOrWorker, 
-  BrowserApi.Worker, BrowserApi.WebAssembly, Wasi.Env, System.WebThreads,
+  System.SysUtils, JSApi.JS,  System.WebThreads,
   Rtl.ThreadController;
   Rtl.ThreadController;
 {$ELSE} 
 {$ELSE} 
-  Classes, SysUtils, JS, custapp, weborworker, webworker, webassembly, wasienv,
-  Rtl.WebThreads, Rtl.ThreadController;
+  SysUtils, JS, Rtl.WebThreads, Rtl.ThreadController, Rtl.WorkerCommands, WasiWorkerApp,
+  rtl.workerthreadhost, rtl.threadrunner;
 {$ENDIF}
 {$ENDIF}
 
 
 const
 const
+  // no longer used
   ThreadRunnerScript = 'wasm_worker_runner.js';
   ThreadRunnerScript = 'wasm_worker_runner.js';
   ThreadCount = 4;
   ThreadCount = 4;
 
 
 Type
 Type
-  TWorkerThreadSupport = Class;
-  { TWASIThreadHost }
-
-  TWASIThreadHost = class(TWASIHost)
-  private
-    FSendOutputToBrowserWindow: Boolean;
-    FThreadEntryPoint: String;
-    FThreadSupport: TWorkerThreadSupport;
-    procedure SetThreadSupport(AValue: TWorkerThreadSupport);
-  Protected
-    Procedure RunWebAssemblyThread(aProc : TRunWebassemblyProc); virtual;
-    procedure DoStdWrite(Sender: TObject; const aOutput: String); override;
-  Public
-    constructor Create(aOwner: TComponent); override;
-    // Prepare webassembly thread
-    procedure PrepareWebAssemblyThread(aDescr: TWebAssemblyStartDescriptor);
-    // Thread entry point name for the WASI Host.
-    Property ThreadEntryPoint : String Read FThreadEntryPoint Write FThreadEntryPoint;
-    // Send output to main window
-    Property SendOutputToBrowserWindow : Boolean Read FSendOutputToBrowserWindow Write FSendOutputToBrowserWindow;
-    // our thread
-    Property ThreadSupport : TWorkerThreadSupport Read FThreadSupport Write SetThreadSupport;
-  end;
-
-
-  // This object has the thread support that is needed by the worker that runs a thread.
-
-  { TWorkerThreadSupport }
-
-  TWorkerThreadSupport = class(TWasmThreadSupport)
-  Private
-    Type
-      TWorkerState = (wsNeutral, wsLoading, wsLoaded, wsRunWaiting, wsRunning);
-  Private
-    FState: TWorkerState;
-    FCurrentThreadInfo : TThreadinfo;
-    FModule : TJSWebAssemblyModule;
-    FMemory : TJSWebAssemblyMemory;
-    FWasiHost: TWASIThreadHost;
-  Protected
-    // Incoming messages
-    procedure DoRunThread(aExports: TWASIExports); virtual;
-    procedure LoadWasmModule(aCommand: TWorkerLoadCommand); virtual;
-    procedure RunWasmModule(aCommand: TWorkerRunCommand); virtual;
-    procedure CancelWasmModule(aCommand: TWorkerCancelCommand); virtual;
-    procedure SendLoaded; virtual;
-    Procedure SendConsoleMessage(aMessage : String); overload;
-    Procedure SendConsoleMessage(aFmt : String; const aArgs : array of const); overload;
-    Procedure SendConsoleMessage(const aArgs : array of JSValue); overload;
-    procedure SendException(aError: Exception); overload;
-    procedure SendException(aError: TJSError); overload;
-  Protected
-    function thread_spawn(start_arg : longint) : longint; override;
-    Function thread_detach(thread_id : Integer) : Integer; override;
-    Function thread_cancel(thread_id : Integer) : Integer; override;
-  Public
-    // Handle incoming command
-    Procedure HandleCommand(aCommand : TWorkerCommand); override;
-    // Current thread info.
-    Property CurrentThreadInfo : TThreadInfo Read FCurrentThreadInfo;
-    // The WASI host, used to run routines.
-    Property Host : TWASIThreadHost Read FWasiHost Write FWasiHost;
-  end;
-
-  { TWorkerWASIHostApplication }
-
-  TWorkerWASIHostApplication = class(TCustomApplication)
-  private
-    FHost : TWASIHost;
-    FSendOutputToBrowser: Boolean;
-    FConsoleChannel: TJSBroadcastChannel;
-    FSendOutputToConsole: Boolean;
-    function GetAfterStart: TAfterStartEvent;
-    function GetBeforeStart: TBeforeStartEvent;
-    function GetcPredefinedConsoleInput: TStrings;
-    function GetEnv: TPas2JSWASIEnvironment;
-    function GetExported: TWASIExports;
-    function GetOnConsoleRead: TConsoleReadEvent;
-    function GetOnConsoleWrite: TConsoleWriteEvent;
-    function GetRunEntryFunction: String;
-    procedure SetAfterStart(AValue: TAfterStartEvent);
-    procedure SetBeforeStart(AValue: TBeforeStartEvent);
-    procedure SetOnConsoleRead(AValue: TConsoleReadEvent);
-    procedure SetOnConsoleWrite(AValue: TConsoleWriteEvent);
-    procedure SetPredefinedConsoleInput(AValue: TStrings);
-    procedure SetRunEntryFunction(AValue: String);
-  protected
-    procedure HandleMessage(aEvent: TJSEvent); virtual; abstract;
-    procedure DoOnSendCommand(Sender : TObject; aCommand : TWorkerCommand);
-    function CreateHost: TWASIHost; virtual; abstract;
-    procedure DoRun; override;
-    procedure DoLog(EventType: TEventType; const Msg: String); override;
-    function GetConsoleApplication: boolean; override;
-    function GetLocation: String; override;
-    property ConsoleChannel : TJSBroadCastChannel Read FConsoleChannel;
-    Property Host : TWASIHost Read FHost;
-  public
-    Constructor Create(aOwner : TComponent); override;
-    Destructor Destroy; override;
-    // Send a command to the process that started the worker.
-    procedure SendCommand(aCommand: TWorkerCommand); virtual;
-    // Get the list of environment variables.
-    procedure GetEnvironmentList(List: TStrings; NamesOnly: Boolean); override;
-    // Load and start webassembly. If DoRun is true, then Webassembly entry point is called.
-    // If aBeforeStart is specified, then it is called prior to calling run, and can disable running.
-    // If aAfterStart is specified, then it is called after calling run. It is not called is running was disabled.
-    Procedure StartWebAssembly(aPath: string; DoRun : Boolean = True;  aBeforeStart : TBeforeStartCallback = Nil; aAfterStart : TAfterStartCallback = Nil);
-    // Environment to be used
-    Property WasiEnvironment : TPas2JSWASIEnvironment Read GetEnv;
-    // Exported functions. Also available in start descriptor.
-    Property Exported : TWASIExports Read GetExported;
-    // Name of function to run, if empty default _start symbol is used.
-    Property RunEntryFunction : String Read GetRunEntryFunction Write SetRunEntryFunction;
-    // Called after webassembly start was run. Not called if webassembly was not run.
-    Property AfterStart : TAfterStartEvent Read GetAfterStart Write SetAfterStart;
-    // Called before running webassembly. If aAllowRun is false, running is disabled
-    Property BeforeStart : TBeforeStartEvent Read GetBeforeStart Write SetBeforeStart;
-    // Send output to browser window process?
-    Property SendOutputToBrowser : Boolean Read FSendOutputToBrowser Write FSendOutputToBrowser;
-    // Send output to console ?
-    Property SendOutputToConsole : Boolean Read FSendOutputToConsole Write FSendOutputToConsole;
-    // Default console input
-    Property PredefinedConsoleInput : TStrings Read GetcPredefinedConsoleInput Write SetPredefinedConsoleInput;
-    // Called when reading from console (stdin). If not set, PredefinedConsoleinput is used.
-    property OnConsoleRead : TConsoleReadEvent Read GetOnConsoleRead Write SetOnConsoleRead;
-    // Called when writing to console (stdout). If not set, console.log is used.
-    property OnConsoleWrite : TConsoleWriteEvent Read GetOnConsoleWrite Write SetOnConsoleWrite;
-  end;
-
-  { TWorkerThreadRunnerApplication }
-
-  TWorkerThreadRunnerApplication = class(TWorkerWASIHostApplication)
-  Private
-    FThreadSupport : TWorkerThreadSupport;
-  Protected
-    procedure HandleConsoleWrite(Sender: TObject; aOutput: string);
-    function HandleCustomCommand(aData: TWorkerCommand): Boolean; virtual;
-    function CreateHost: TWASIHost; override;
-    function CreateWorkerThreadSupport(aEnv: TPas2JSWasiEnvironment): TWorkerThreadSupport; virtual;
-    procedure HandleMessage(aEvent: TJSEvent); override;
-  Public
-    procedure ShowException(aError: Exception); override;
-    // Our thread support object
-    Property ThreadSupport : TWorkerThreadSupport Read FThreadSupport Write FThreadSupport;
-  end;
-
-  { TWASIThreadHost }
-
-  { TWASIThreadControllerHost }
-
-  TWASIThreadControllerHost = class(TWASIHost)
-  private
-    FSendOutputToBrowserWindow: Boolean;
-    FThreadSupport: TThreadController;
-    procedure SetThreadSupport(AValue: TThreadController);
-  Protected
-    procedure DoAfterInstantiate; override;
-  Public
-    constructor Create(aOwner: TComponent); override;
-    // Send output to main window
-    Property SendOutputToBrowserWindow : Boolean Read FSendOutputToBrowserWindow Write FSendOutputToBrowserWindow;
-    // our thread
-    Property ThreadSupport : TThreadController Read FThreadSupport Write SetThreadSupport;
-  end;
-
-  { TWorkerThreadControllerApplication }
-
-  TWorkerThreadControllerApplication = class(TWorkerWASIHostApplication)
-  Private
-    FThreadSupport : TThreadController;
-    function GetThreadHost: TWASIThreadControllerHost;
-  Protected
-    function CreateThreadSupport(aEnv: TPas2JSWASIEnvironment): TThreadController; virtual;
-    procedure HandleConsoleWrite(Sender: TObject; aOutput: string); virtual;
-    procedure HandleExecuteCommand(aCmd: TWorkerExecuteCommand); virtual;
-    procedure HandleRpcCommand(aCmd: TWorkerRpcCommand); virtual;
-    function HandleCustomCommand(aData: TWorkerCommand): Boolean; virtual;
-    procedure HandleMessage(aEvent: TJSEvent); override;
-    function CreateHost: TWASIHost; override;
-  Public
-    procedure ShowException(aError: Exception); override;
-    property ThreadSupport : TThreadController Read FThreadSupport;
-    property ThreadHost : TWASIThreadControllerHost read GetThreadHost;
-
-  end;
+  TWASIThreadHost = TWASIThreadControllerHost;
+  TWorkerThreadSupport = class(TWasmThreadSupportApi);
+  TWorkerWASIHostApplication = Class(WasiWorkerApp.TWorkerWASIHostApplication);
+  TWorkerThreadRunnerApplication = Class(Rtl.threadRunner.TWorkerThreadRunnerApplication);
+  TWorkerThreadControllerHost = Class(TWASIThreadControllerHost);
+  TWorkerThreadControllerApplication = class(rtl.workerthreadhost.TWorkerThreadControllerApplication);
 
 
 function GetJSClassName(aObj : TJSObject) : string;
 function GetJSClassName(aObj : TJSObject) : string;
 
 
 implementation
 implementation
 
 
-uses 
-{$IFDEF FPC_DOTTEDUNITS}
-  System.Types, System.TypInfo;
-{$ELSE} 
-  TypInfo, Types;
-{$ENDIF}
-
-var
-  EnvNames: TJSObject;
-
-procedure ReloadEnvironmentStrings;
-
-var
-  I : Integer;
-  S,N : String;
-  A,P : TStringDynArray;
-
-begin
-  if Assigned(EnvNames) then
-    FreeAndNil(EnvNames);
-  EnvNames:=TJSObject.new;
-  S:=self_.Location.search;
-  S:=Copy(S,2,Length(S)-1);
-  A:=TJSString(S).split('&');
-  for I:=0 to Length(A)-1 do
-    begin
-    P:=TJSString(A[i]).split('=');
-    N:=LowerCase(decodeURIComponent(P[0]));
-    if Length(P)=2 then
-      EnvNames[N]:=decodeURIComponent(P[1])
-    else if Length(P)=1 then
-      EnvNames[N]:=''
-    end;
-end;
-
-function MyGetEnvironmentVariable(Const EnvVar: String): String;
-
-Var
-  aName : String;
-
-begin
-  aName:=Lowercase(EnvVar);
-  if EnvNames.hasOwnProperty(aName) then
-    Result:=String(EnvNames[aName])
-  else
-    Result:='';
-end;
-
-function MyGetEnvironmentVariableCount: Integer;
-begin
-  Result:=length(TJSOBject.getOwnPropertyNames(envNames));
-end;
-
-function MyGetEnvironmentString(Index: Integer): String;
-begin
-  Result:=String(EnvNames[TJSOBject.getOwnPropertyNames(envNames)[Index]]);
-end;
-
-
-{ TWASIThreadHost }
-
-procedure TWASIThreadHost.SetThreadSupport(AValue: TWorkerThreadSupport);
-begin
-  if FThreadSupport=AValue then Exit;
-  if Assigned(FThreadSupport) then
-    FThreadSupport.Host:=Nil;
-  FThreadSupport:=AValue;
-  if Assigned(FThreadSupport) then
-    FThreadSupport.Host:=Self;
-end;
-
-procedure TWASIThreadHost.RunWebAssemblyThread(aProc : TRunWebassemblyProc);
-begin
-//  Writeln('TWASIThreadHost.Entering RunWebAssemblyThread ');
-  RunWebAssemblyInstance(Nil,Nil,aProc);
-end;
-
-procedure TWASIThreadHost.PrepareWebAssemblyThread( aDescr: TWebAssemblyStartDescriptor);
-
-begin
-  PrepareWebAssemblyInstance(aDescr);
-end;
-
-procedure TWASIThreadHost.DoStdWrite(Sender: TObject; const aOutput: String);
-begin
-  inherited DoStdWrite(Sender, aOutput);
-  if FSendOutputToBrowserWindow and assigned(FThreadSupport) then
-    FThreadSupport.SendConsoleMessage(aOutput);
-end;
-
-constructor TWASIThreadHost.Create(aOwner: TComponent);
-begin
-  inherited Create(aOwner);
-  FThreadEntryPoint:=DefaultThreadEntryPoint;
-  FSendOutputToBrowserWindow:=True;
-end;
-
-{ TWorkerThreadSupport }
-
-function TWorkerThreadSupport.thread_spawn(start_arg: longint): longint;
-
-Var
-  P : TWorkerSpawnThreadCommand;
-
-begin
-  P:=TWorkerSpawnThreadCommand.Create(start_arg,start_arg);
-  SendCommand(P);
-  Result:=start_arg;
-end;
-
-function TWorkerThreadSupport.thread_detach(thread_id: Integer): Integer;
-begin
-  Result:=0;
-  if thread_id=0 then ;
-end;
-
-function TWorkerThreadSupport.thread_cancel(thread_id: Integer): Integer;
-begin
-  Result:=0;
-  if thread_id=0 then ;
-end;
-
-
-procedure TWorkerThreadSupport.SendLoaded;
-
-Var
-  L : TWorkerLoadedCommand;
-
-begin
-  L:=TWorkerLoadedCommand.Create();
-  SendCommand(L);
-end;
-
-procedure TWorkerThreadSupport.SendConsoleMessage(aMessage: String);
-
-Var
-  L : TWorkerConsoleCommand;
-
-begin
-  L:=TWorkerConsoleCommand.Create(aMessage,FCurrentThreadInfo.ThreadId);
-  SendCommand(L);
-end;
-
-procedure TWorkerThreadSupport.SendConsoleMessage(aFmt: String;
-  const aArgs: array of const);
-begin
-  SendConsoleMessage(Format(aFmt,aArgs));
-end;
-
-procedure TWorkerThreadSupport.SendConsoleMessage(const aArgs: array of JSValue);
-
-Var
-  L : TWorkerConsoleCommand;
-
-begin
-  L:=TWorkerConsoleCommand.Create(aArgs,FCurrentThreadInfo.ThreadId);
-  SendCommand(L);
-end;
-
-procedure TWorkerThreadSupport.CancelWasmModule(aCommand : TWorkerCancelCommand);
-
-begin
-  if (aCommand<>Nil) then ;
-  // todo
-end;
-
-
-procedure TWorkerThreadSupport.SendException(aError : Exception);
-
-Var
-  E : TWorkerExceptionCommand;
-
-begin
-  E:=TWorkerExceptionCommand.CreateNew(aError.ClassName,aError.Message,FCurrentThreadInfo.ThreadId);
-  SendCommand(E);
-end;
-
-procedure TWorkerThreadSupport.SendException(aError: TJSError);
-
-Var
-  aMessage,aClass : String;
-  E : TWorkerExceptionCommand;
-
-begin
-  aClass:='Error';
-  aMessage:=aError.Message;
-  E:=TWorkerExceptionCommand.CreateNew(aClass,aMessage,FCurrentThreadInfo.ThreadId);
-  SendCommand(E);
-end;
-
-Procedure TWorkerThreadSupport.DoRunThread(aExports : TWASIExports);
-
-Var
-  aResult : Integer;
-
-
-begin
-  try
-    FState:=wsRunning;
-    // Writeln('About to run webassembly entry point (',Host.ThreadEntryPoint,') for thread ID ',aCommand.ThreadID);
-    aResult:=TThreadEntryPointFunction(aExports[Host.ThreadEntryPoint])(FCurrentThreadInfo.ThreadID,FCurrentThreadInfo.Arguments);
-    FState:=wsLoaded;
-    if aResult>0 then
-      SendConsoleMessage('Thread run function result= %d ',[aResult]);
-    SendCommand(TWorkerCleanupCommand.Create(Self.FCurrentThreadInfo.ThreadID,aResult));
-  except
-    on E : Exception do
-      SendException(E);
-    on JE : TJSError do
-      SendException(JE);
-    on JE : TJSError do
-      SendException(JE)
-  end;
-end;
-
-
-procedure TWorkerThreadSupport.RunWasmModule(aCommand : TWorkerRunCommand);
-
-begin
-  if (FState=wsNeutral) then
-    begin
-    {$IFNDEF NOLOGAPICALLS}
-    DoLog('No webassembly loaded');
-    {$ENDIF}
-    exit; // Todo: send error back
-    end;
-  if (FState in [wsRunning,wsRunWaiting]) then
-    begin
-    {$IFNDEF NOLOGAPICALLS}
-    DoLog('Webassembly already running');
-    {$ENDIF}
-    exit; // Todo: send error back
-    end;
-  // Writeln('Entering TWorkerThreadSupport.RunWasmModule '+TJSJSON.Stringify(aCommand));
-  // initialize current thread info
-  FCurrentThreadInfo.ThreadID:=aCommand.ThreadID;
-  FCurrentThreadInfo.Arguments:=aCommand.Args;
-  if FState=wsLoaded then
-    Host.RunWebAssemblyThread(@DoRunThread)
-  else
-    FState:=wsRunWaiting;
-end;
-
-procedure TWorkerThreadSupport.LoadWasmModule(aCommand: TWorkerLoadCommand);
-
-
-Var
-  WASD : TWebAssemblyStartDescriptor;
-  aTable : TJSWebAssemblyTable;
-
-  function doOK(aValue: JSValue): JSValue;
-  // We are using the overload that takes a compiled module.
-  // In that case the promise resolves to a WebAssembly.Instance, not to a InstantiateResult !
-  Var
-    aInstance : TJSWebAssemblyInstance absolute aValue;
-
-  begin
-    Result:=True;
-    WASD.Instance:=aInstance;
-    WASD.Exported:=TWASIExports(TJSObject(aInstance.exports_));
-    WASD.CallRun:=Nil;
-    Host.PrepareWebAssemblyThread(WASD);
-    SendLoaded;
-    if FState=wsRunWaiting then
-      Host.RunWebAssemblyThread(@DoRunThread)
-    else
-      FState:=wsLoaded;
-  end;
-
-  function DoFail(aValue: JSValue): JSValue;
-
-  var
-    E: Exception;
-
-  begin
-    FState:=wsNeutral;
-    Result:=True;
-    E:=Exception.Create('Failed to create webassembly. Reason: '+TJSJSON.Stringify(aValue));
-    SendException(E);
-    E.Free;
-  end;
-
-
-begin
-  FState:=wsLoading;
-  FMemory:=aCommand.Memory;
-  FModule:=aCommand.Module;
-  try
-    aTable:=TJSWebAssemblyTable.New(Host.TableDescriptor);
-    WASD:=Host.InitStartDescriptor(FMemory,aTable,Nil);
-    TJSWebAssembly.Instantiate(FModule,WASD.Imports)._then(@DoOK,@DoFail).Catch(@DoFail);
-  except
-    on E : Exception do
-      SendException(E);
-    on JE : TJSError do
-      SendException(JE);
-  end;
-end;
-
-procedure TWorkerThreadSupport.HandleCommand(aCommand: TWorkerCommand);
-
-begin
-  case aCommand.Command of
-    cmdload : LoadWasmModule(TWorkerLoadCommand(aCommand));
-    cmdRun : RunWasmModule(TWorkerRunCommand(aCommand));
-    cmdCancel : CancelWasmModule(TWorkerCancelCommand(aCommand));
-  end;
-end;
-
-
-
-{ TWorkerWASIHostApplication }
-
-function TWorkerWASIHostApplication.GetAfterStart: TAfterStartEvent;
-begin
-  Result:=FHost.AfterStart;
-end;
-
-function TWorkerWASIHostApplication.GetBeforeStart: TBeforeStartEvent;
-begin
-  Result:=FHost.BeforeStart;
-end;
-
-function TWorkerWASIHostApplication.GetcPredefinedConsoleInput: TStrings;
-begin
-  Result:=FHost.PredefinedConsoleInput;
-end;
-
-function TWorkerWASIHostApplication.GetEnv: TPas2JSWASIEnvironment;
-begin
-  Result:=FHost.WasiEnvironment;
-end;
-
-function TWorkerWASIHostApplication.GetExported: TWASIExports;
-begin
-  Result:=FHost.Exported;
-end;
-
-
-function TWorkerWASIHostApplication.GetOnConsoleRead: TConsoleReadEvent;
-begin
-  Result:=FHost.OnConsoleRead;
-end;
-
-function TWorkerWASIHostApplication.GetOnConsoleWrite: TConsoleWriteEvent;
-begin
-  Result:=FHost.OnConsoleWrite;
-end;
-
-function TWorkerWASIHostApplication.GetRunEntryFunction: String;
-begin
-  Result:=FHost.RunEntryFunction;
-end;
-
-
-procedure TWorkerWASIHostApplication.SetAfterStart(AValue: TAfterStartEvent);
-begin
-  FHost.AfterStart:=aValue;
-end;
-
-procedure TWorkerWASIHostApplication.SetBeforeStart(AValue: TBeforeStartEvent);
-begin
-  FHost.BeforeStart:=aValue;
-end;
-
-procedure TWorkerWASIHostApplication.SetOnConsoleRead(AValue: TConsoleReadEvent
-  );
-begin
-  FHost.OnConsoleRead:=aValue;
-end;
-
-procedure TWorkerWASIHostApplication.SetOnConsoleWrite(
-  AValue: TConsoleWriteEvent);
-begin
-    FHost.OnConsoleWrite:=aValue;
-end;
-
-procedure TWorkerWASIHostApplication.SetPredefinedConsoleInput(AValue: TStrings);
-begin
-  FHost.PredefinedConsoleInput:=aValue;
-end;
-
-procedure TWorkerWASIHostApplication.SetRunEntryFunction(AValue: String);
-begin
-  FHost.RunEntryFunction:=aValue;
-end;
-
-
-procedure TWorkerWASIHostApplication.DoRun;
-begin
-  Self_.addEventListener('message',@HandleMessage);
-end;
-
-procedure TWorkerWASIHostApplication.DoLog(EventType: TEventType; const Msg: String);
-var
-  S : String;
-begin
-  S:=GetEnumName(TypeInfo(TEventType),Ord(EventType));
-  ConsoleChannel.PostMessage(TWorkerConsoleCommand.Create(Format('[%s] %s',[S,Msg])));
-end;
-
-
-procedure TWorkerWASIHostApplication.DoOnSendCommand(Sender: TObject;
-  aCommand: TWorkerCommand);
-begin
-  SendCommand(aCommand);
-end;
-
-procedure TWorkerWASIHostApplication.SendCommand(aCommand: TWorkerCommand);
-begin
-  Self_.PostMessage(aCommand);
-end;
-
-function TWorkerWASIHostApplication.GetConsoleApplication: boolean;
-begin
-  Result:=true;
-end;
-
-function TWorkerWASIHostApplication.GetLocation: String;
-begin
-  Result:={$IFDEF FPC_DOTTEDUNITS}BrowserApi.Worker.{$ELSE}WebWorker.{$ENDIF}Location.pathname;
-end;
-
-constructor TWorkerWASIHostApplication.Create(aOwner: TComponent);
-begin
-  inherited Create(aOwner);
-  FHost:=CreateHost;
-  FConsoleChannel:=TJSBroadcastChannel.new(channelConsole);
-  FSendOutputToConsole:=true;
-end;
-
-destructor TWorkerWASIHostApplication.Destroy;
-begin
-  FConsoleChannel.Close;
-  FreeAndNil(FHost);
-  inherited Destroy;
-end;
-
-procedure TWorkerWASIHostApplication.GetEnvironmentList(List: TStrings;
-  NamesOnly: Boolean);
-var
-  Names: TStringDynArray;
-  i: Integer;
-begin
-  Names:=TJSObject.getOwnPropertyNames(EnvNames);
-  for i:=0 to length(Names)-1 do
-  begin
-    if NamesOnly then
-      List.Add(Names[i])
-    else
-      List.Add(Names[i]+'='+String(EnvNames[Names[i]]));
-  end;
-end;
-
-
-procedure TWorkerWASIHostApplication.StartWebAssembly(aPath: string; DoRun: Boolean;
-  aBeforeStart: TBeforeStartCallback = nil; aAfterStart: TAfterStartCallback = nil);
-
-begin
-  FHost.StartWebAssembly(aPath,DoRun,aBeforeStart,aAfterStart);
-end;
-
-{ TWorkerThreadRunnerApplication }
-
-procedure TWorkerThreadRunnerApplication.HandleConsoleWrite(Sender: TObject; aOutput: string);
-begin
-  if SendOutputToConsole then
-    Writeln(aOutput);
-  if SendOutputToBrowser then
-    ConsoleChannel.postMessage(TWorkerConsoleCommand.Create(aOutput));
-end;
-
-function TWorkerThreadRunnerApplication.CreateWorkerThreadSupport(aEnv : TPas2JSWasiEnvironment) : TWorkerThreadSupport;
-
-begin
-  Result:=TWorkerThreadSupport.Create(aEnv);
-end;
-
-function TWorkerThreadRunnerApplication.CreateHost: TWASIHost;
-
-var
-  TH : TWasiThreadHost;
-
-begin
-  TH:=TWASIThreadHost.Create(Self);
-  TH.OnConsoleWrite:=@HandleConsoleWrite;
-  FThreadSupport:=CreateWorkerThreadSupport(TH.WasiEnvironment);
-  FThreadSupport.OnSendCommand:=@DoOnSendCommand;
-  TH.ThreadSupport:=FThreadSupport; // Sets FThreadSupport.host
-  Result:=TH;
-end;
-
-procedure TWorkerThreadRunnerApplication.ShowException(aError: Exception);
-
-Var
-  Ex : TWorkerExceptionCommand;
-
-begin
-  Ex:=TWorkerExceptionCommand.CreateNew(aError.ClassName,aError.Message);
-  SendCommand(Ex);
-end;
-
-
-function TWorkerThreadRunnerApplication.HandleCustomCommand(aData : TWorkerCommand) : Boolean;
-
-begin
-  if aData<>Nil then;
-  Result:=False;
-end;
-
-procedure TWorkerThreadRunnerApplication.HandleMessage(aEvent: TJSEvent);
-
-Var
-  aMessageEvent : TJSMessageEvent absolute aEvent;
-  aData : TWorkerCommand;
-
-begin
-  {$IFNDEF NOLOGAPICALLS}
-  DoLog(etDebug,'Message received in worker');
-  {$ENDIF}
-  if IsObject(aMessageEvent.Data) and TJSObject(aMessageEvent.Data).hasOwnProperty('Command') then
-    begin
-    aData:=TWorkerCommand(aMessageEvent.Data);
-    {$IFNDEF NOLOGAPICALLS}
-    DoLog(etDebug,'Command Message received in worker: '+TJSJSON.Stringify(aData));
-    {$ENDIF}
-    if not HandleCustomCommand(aData) then
-      FThreadSupport.HandleCommand(aData);
-    end
-  else
-    FThreadSupport.SendConsoleMessage('Unknown message received: '+TJSJSON.Stringify(aMessageEvent.Data));
-end;
-
-{ TWASIThreadControllerHost }
-
-procedure TWASIThreadControllerHost.SetThreadSupport(AValue: TThreadController);
-begin
-  if Assigned(FThreadSupport) then
-    FThreadSupport.Host:=Nil;
-  FThreadSupport:=AValue;
-  if Assigned(FThreadSupport) then
-    FThreadSupport.Host:=Self;
-end;
-
-procedure TWASIThreadControllerHost.DoAfterInstantiate;
-begin
-  inherited DoAfterInstantiate;
-  If Assigned(FThreadSupport) then
-    FThreadSupport.SendLoadCommands;
-end;
-
-constructor TWASIThreadControllerHost.Create(aOwner: TComponent);
-begin
-  inherited Create(aOwner);
-end;
-
-
-{ TWorkerThreadControllerApplication }
-
-procedure TWorkerThreadControllerApplication.ShowException(aError: Exception);
-Var
-  Ex : TWorkerExceptionCommand;
-
-begin
-  Ex:=TWorkerExceptionCommand.CreateNew(aError.ClassName,aError.Message);
-  SendCommand(Ex);
-end;
-
-procedure TWorkerThreadControllerApplication.HandleExecuteCommand(aCmd : TWorkerExecuteCommand);
-
-(*
-Function DoPrepare(Sender : TObject; aDescriptor : TWebAssemblyStartDescriptor) : Boolean;
-
-  begin
-//    aDescriptor.
-    Result:=True;
-  end;
-*)
-
-begin
-  if isObject(aCmd.Env) then
-    EnvNames:=aCmd.Env;
-  if isString(aCmd.executeFunc) then
-    FHost.RunEntryFunction:=aCmd.executeFunc;
-  StartWebAssembly(aCmd.Url,True,Nil {@DoPrepare}, Nil)
-end;
-
 function GetJSClassName(aObj : TJSObject) : string;
 function GetJSClassName(aObj : TJSObject) : string;
-
-begin
-  Result:='';
-  if aObj=Nil then
-    exit;
-  asm
-    return aObj.constructor.name;
-  end;
-end;
-
-procedure TWorkerThreadControllerApplication.HandleRpcCommand(aCmd: TWorkerRpcCommand);
-
-var
-  res : TWorkerRpcResultCommand;
-  data : JSValue;
-  errClass : String;
-  errMessage : String;
-
-begin
-  if aCmd.Id='' then
-    Res:=TWorkerRpcResultCommand.CreateError(aCmd.id,-32600,'Invalid request: No json-rpc ID')
-  else if aCmd.jsonrpc<>'2.0' then
-    Res:=TWorkerRpcResultCommand.CreateError(aCmd.id,-32600,'Invalid request: no jsonrpc version')
-  else if Not Assigned(Exported.functions[aCmd.method]) then
-    Res:=TWorkerRpcResultCommand.CreateError(aCmd.id,-32601,'Method "'+aCmd.method+'" not found')
-  else
-    begin
-    try
-      if isArray(aCmd.Params) then
-        data:=Exported.functions[aCmd.method].Apply(nil,TJSValueDynArray(aCmd.Params))
-      else
-        data:=Exported.functions[aCmd.method].call(nil);
-      Res:=TWorkerRpcResultCommand.Create(aCmd.id,Data);
-    except
-      on JE : TJSError do
-        begin
-        errClass:=GetJSClassName(JE);
-        errMessage:=JE.message;
-        end;
-      on E : Exception do
-        begin
-        errClass:=E.ClassName;
-        errMessage:=E.Message;
-        end;
-    end;
-    if not assigned(Res) then
-      Res:=TWorkerRpcResultCommand.CreateError(aCmd.id,-32603,'Exception '+ErrClass+' while executing "'+aCmd.method+'" : '+ErrMessage);
-    end;
-  Self_.postMessage(Res);
-end;
-
-procedure TWorkerThreadControllerApplication.HandleConsoleWrite(Sender: TObject; aOutput: string);
-begin
-  if SendOutputToConsole then
-    Writeln(aOutput);
-  if SendOutputToBrowser then
-    FConsoleChannel.postMessage(TWorkerConsoleCommand.Create(aOutput,0));
-end;
-
-function TWorkerThreadControllerApplication.HandleCustomCommand(aData : TWorkerCommand) : Boolean;
-
-begin
-  if not Assigned(aData) then
-    Exit(True);
-  Result:=False;
-end;
-
-procedure TWorkerThreadControllerApplication.HandleMessage(aEvent: TJSEvent);
-
-var
-  aMessageEvent : TJSMessageEvent absolute aEvent;
-  aData: TWorkerCommand;
-
-begin
-  Writeln('Thread Message received');
-  if IsObject(aMessageEvent.Data) and TJSObject(aMessageEvent.Data).hasOwnProperty('Command') then
-    begin
-    aData:=TWorkerCommand(aMessageEvent.Data);
-    Writeln('Command message received: '+TJSJSON.Stringify(aData));
-    case aData.Command of
-      cmdExecute : HandleExecuteCommand(TWorkerExecuteCommand(aData));
-      cmdRpc : HandleRPCCommand(TWorkerRpcCommand(aData));
-    else
-      if not HandleCustomCommand(aData) then
-        FThreadSupport.HandleCommand(aData);
-    end;
-    end;
-end;
-
-function TWorkerThreadControllerApplication.GetThreadHost: TWASIThreadControllerHost;
-begin
-  Result:=(Host as  TWASIThreadControllerHost)
-end;
-
-function TWorkerThreadControllerApplication.CreateThreadSupport(aEnv : TPas2JSWASIEnvironment) : TThreadController;
-
-begin
-  Result:=TThreadController.Create(aEnv,ThreadRunnerScript,ThreadCount);
-end;
-
-function TWorkerThreadControllerApplication.CreateHost: TWASIHost;
-var
-  TH : TWASIThreadControllerHost;
-  Mem : TJSWebAssemblyMemoryDescriptor;
 begin
 begin
-  TH:=TWASIThreadControllerHost.Create(Self);
-  TH.OnConsoleWrite:=@HandleConsoleWrite;
-  FThreadSupport:=CreateThreadSupport(TH.WasiEnvironment);
-  Mem.Initial:=256;
-  Mem.maximum:=512;
-  Mem.shared:=True;
-  TH.MemoryDescriptor:=Mem;
-  FThreadSupport.OnSendCommand:=@DoOnSendCommand;
-  TH.ThreadSupport:=FThreadSupport; // Sets FThreadSupport.host
-  Result:=TH;
+  Result:=JSClassName(aObj);
 end;
 end;
 
 
 Initialization
 Initialization
-  ReloadEnvironmentStrings;
-  OnGetEnvironmentVariable:=@MyGetEnvironmentVariable;
-  OnGetEnvironmentVariableCount:=@MyGetEnvironmentVariableCount;
-  OnGetEnvironmentString:=@MyGetEnvironmentString;
+  TWasmThreadController.SetInstanceClass(TWorkerThreadRunner);
 end.
 end.