#1 2020-08-24 13:21:14

gd
Member
Registered: 2018-07-19
Posts: 3

Problems with TSMEngineManager inside a DLL module

Hello

I'm trying to use TSMEngineManager as an engine to run a JavaScript in Delphi application.

It works fine but I want to put it inside a closed DLL module and run it with a JavaScript as an method argument. But I have encountered a problem. When I create an instance of TSMEngineManager inside a DLL method and free it, then my application crashes after about 5 seconds after the FreeLibrary().
I have reduced my test application to the absolute minimum and it still crashes everytime. Now it doesn't do anything beside creating and freeing the TSMEngineManager. When I remove the creation of TSMEngineManager, it doesn't crash.

Am I doing something wrong?

Delphi version used: XE 10.1 Berlin
Tested on the newest mORMot from here https://github.com/synopse/mORMot (master).
DLL files needed to run the project: libnspr4.dll and mozjs-24.dll (I have both from 2017 - are they the most recent ones?).
Maybe I use wrong version of mozjs-24.dll? I know it's pretty old SM implementation but I'm not sure how to use SM45 or SM52 and where to find new DLLs for it.

Here's the example. It has 2 DPR files only:

---------------------------------------------------------------
DLL file
---------------------------------------------------------------

library JavaScriptRunnerLib;

uses
  SynSM,
  SynCommons;

{$R *.res}

procedure RunMethodTest(); stdcall;
var
  SMEngineManager: TSMEngineManager;
begin
  SMEngineManager := TSMEngineManager.Create;
//  SMEngineManager.ReleaseCurrentThreadEngine; // < it doesn't help at all
  SMEngineManager.Free;
end;

exports
  RunMethodTest;

begin

end.

---------------------------------------------------------------
Host application
---------------------------------------------------------------

program JavaScriptRunnerExample;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  Winapi.Windows,
  System.SysUtils;

type
  TRunMethodTestProc = procedure (); stdcall;

const
  ScriptRunnerLibFileName = 'JavaScriptRunnerLib.dll';

function LoadScriptRunnerLibrary: THandle;
begin
  result := LoadLibrary(ScriptRunnerLibFileName);
//  result := SafeLoadLibrary(ScriptRunnerLibFileName, SEM_FAILCRITICALERRORS);  // < it doesn't help
  if result = 0 then
    raise exception.CreateFmt('Error loading library %s', [ScriptRunnerLibFileName]);
end;

procedure Test2;
var
  LibHandle: THandle;
  RunMethodTestProc: TRunMethodTestProc;
begin
  LibHandle := LoadScriptRunnerLibrary;
  try
    RunMethodTestProc := GetProcAddress(LibHandle, 'RunMethodTest');
    RunMethodTestProc();
  finally
    FreeLibrary(LibHandle); // < after this command the application will crash within about 5 seconds
      // If I don't use the FreeLibrary() it won't crash but I need to it
  end;
end;

begin
  ReportMemoryLeaksOnShutdown := true;
  try
    writeln('start');
    Test2;
    writeln('sleep');
    sleep(5000);
    writeln('after sleep - press enter');
    //probably it will crash before this line
    Readln;
    writeln('ok');
  except
    on E: exception do
    begin
      writeln(E.ClassName, ': ', E.Message);
      readln;
    end;
  end;

end.

Thank you for any help.

Offline

#2 2020-08-24 17:59:48

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,061
Website

Re: Problems with TSMEngineManager inside a DLL module

Wokring SyNode version is currently in feature/synodeCleanup brunch. It's for SpiderMonkey52. Links to compiled DLLs is in the SyNode/README.md.
But after Mozilla rewrote most of the part of SpiderMonkey using C++ we lost Deplhi compatibility - please, see this discussion https://synopse.info/forum/viewtopic.php?id=5442.
We use a FPC 3.2.0 (x64) for both Windows and Linux.

In case you do not need a NodeJS build-in modules and JavaScript Debugger the good choice is a Chakra Core wrapper. Chakra API is MUCH simple compared to SM and exported as C.
Or pure Delphi besen ECMAScript (no JIT optimization)

Offline

Board footer

Powered by FluxBB