#51 2016-10-31 14:46:19

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

About rooting in SpiderMonkey:

Everything (strings, objects, integers, result of CreateJSInstanceObjForSimpleRTTI call, etc.) inside SpiderMonkey represented as JSValue - a 64 bit structure. SpiderMonkey engine create a reference counter for each structure, and when reference counter === 0 will free a JSValue (during garbage collection circle) - this is the same as for Strings or dynamic array in Delphi, but in Delphi string will be destroyed just after reference counted became zero, in JavaScript - when garbage collection circle is executed.

 
jsval := CreateJSInstanceObjForSimpleRTTI(....); // 0) create a new JSValue inside Engine
try
  rootObj := cx.NewRooted*(jsval); // 1) When we want to use a JSValue from outside the SpiderMonkey Engine (from Delphi code) we must say Engine to increase a reference counter
  // do something with JSValue
  vp.rval := rootObj.ptr.ToJSValue; //see notes* below about ptr
finally 
  cx.FreeRooted*(rootObj); // 2) When we do not need a reference to JSValue from Delphy, we must say Engine to decrease a reference counter by

cx.FreeRooted is not actually a Free operation - just a dec to the internal reference counter.

Notes* about ptr
Between events 1) and 2) SpiderMonkey can in any moment run a internal memory optimization procedure and move the actual in-memory position of the JSValue to another place. This is why we must not memorize a direct pointer to a JSValue (in our case jsval created on the step 0), but use a rootObj.ptr.

Notes about root/unroot order
Important thing about rooting/unrooting order - inside the SM45 rooting is a stack, so we must unroot things in order opposite we root it. In C++ this solved by automatically variable scoping. In Delphi even if we use a Variants as AB did in SM24 there is no guaranty of variant uninit order, so we must manually and carefully root/unroot.

Last edited by mpv (2016-10-31 14:54:23)

Offline

#52 2016-10-31 15:17:54

edwinsn
Member
Registered: 2010-07-02
Posts: 1,049

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Wow! If all the node.js built-in modules are implemented, it means that we will be able to **make use** of the vast amount of node modules available on the Internet, right?


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#53 2016-10-31 16:14:18

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Currently not all build-in are implemented. But we are working on it. My current production environment use 119 nodules from NPM smile

Offline

#54 2016-11-01 05:42:00

edwinsn
Member
Registered: 2010-07-02
Posts: 1,049

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Wow! That's really a great achievement!

Is the list of that 119 node modules public somewhere?


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#55 2016-11-01 11:24:36

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Just a short list: mime-db xml2js xmlbuilder xmldom lodash underscore moment mustache nunjucks  node-cron odata-parser async docusign-esign uglify-js

Offline

#56 2016-11-01 11:40:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 11,693
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

AFAIR the Delphi Web Script JavaScript back-end has been released again under Open Source.
We may include it to compile directly from high-level pascal to JavaScript, then execute it in SyNode... and its full JIT performance... may be a perspective of some interest...

Offline

#57 2016-11-05 08:23:30

ComingNine
Member
Registered: 2010-07-29
Posts: 293

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

mpv wrote:

About rooting in SpiderMonkey:

Everything (strings, objects, integers, result of CreateJSInstanceObjForSimpleRTTI call, etc.) inside SpiderMonkey represented as JSValue - a 64 bit structure. SpiderMonkey engine create a reference counter for each structure, and when reference counter === 0 will free a JSValue (during garbage collection circle) - this is the same as for Strings or dynamic array in Delphi, but in Delphi string will be destroyed just after reference counted became zero, in JavaScript - when garbage collection circle is executed.

 
jsval := CreateJSInstanceObjForSimpleRTTI(....); // 0) create a new JSValue inside Engine
try
  rootObj := cx.NewRooted*(jsval); // 1) When we want to use a JSValue from outside the SpiderMonkey Engine (from Delphi code) we must say Engine to increase a reference counter
  // do something with JSValue
  vp.rval := rootObj.ptr.ToJSValue; //see notes* below about ptr
finally 
  cx.FreeRooted*(rootObj); // 2) When we do not need a reference to JSValue from Delphy, we must say Engine to decrease a reference counter by

cx.FreeRooted is not actually a Free operation - just a dec to the internal reference counter.

Notes* about ptr
Between events 1) and 2) SpiderMonkey can in any moment run a internal memory optimization procedure and move the actual in-memory position of the JSValue to another place. This is why we must not memorize a direct pointer to a JSValue (in our case jsval created on the step 0), but use a rootObj.ptr.

Notes about root/unroot order
Important thing about rooting/unrooting order - inside the SM45 rooting is a stack, so we must unroot things in order opposite we root it. In C++ this solved by automatically variable scoping. In Delphi even if we use a Variants as AB did in SM24 there is no guaranty of variant uninit order, so we must manually and carefully root/unroot.

I appreciate your efforts and helpful comments very much !

ab wrote:

AFAIR the Delphi Web Script JavaScript back-end has been released again under Open Source.
We may include it to compile directly from high-level pascal to JavaScript, then execute it in SyNode... and its full JIT performance... may be a perspective of some interest...

Sounds really interesting ! Looking forward to the proto type big_smile

Offline

#58 2016-11-05 12:42:45

ComingNine
Member
Registered: 2010-07-29
Posts: 293

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Dear mpv, I am trying to access the "mainForm" exported by the host SpiderMonkey45Binding.exe from the plugin mathModule.dll. The reason behind my attempt is that if this is indeed possible, this looks like a good way of manipulating "central business service" exported by the host .exe from plugin .dll. Complex additional manipulation referencing the "central business service" could be compiled into plugin .dll without changing the host .exe.

Modified files are uploaded onto gist : uMathModule.pas belongs to "01 - Dll Modules\math-module\src\" and the rest six files belong to "02 - Bindings".

However, I have met several problems in trying with the above files:

(1) The plugin methods have to reference the business class. That is to say, ufrmSM45Demo has to be used in uMathModule.pas. But then the type incompatibility issue arises. For example, in function try_work_tform1_1, InstRec.instance is TfrmSM45Demo fails. I wonder whether it is safe or dangerous to hard cast as done in the code ?

(2) Further attempts try to access the ability of the mainForm , which is obtained by hard-cast, to evaluate JavaScript. In other words:
  (a) host evaluates JavaScript string, where host exports mainForm
  (b) in the JavaScript string, host calls plugin JS method with the mainForm exported
  (c) in the plugin native method, the mainForm obtained by hard-cast is asked to evaluate JavaScript

  However, the attempts all fail: function try_work_tform1_2 does not completes 100% correct, and function try_work_tform2_2 gives access violation; function try_work_tform1_3 and try_work_tform2_3 both give "A component named Form? already exists."

(3) The above problems are the same no matter FastMM4 or ShareMem is used for host or plugin or both.

Could you help to check the code and comment the reason ?  big_smile

Furthermore, if I am taking the wrong way, could you help to comment the correct solution to access the "central business service" of host .exe within the plugin dll ? big_smile

Last edited by ComingNine (2016-11-05 12:46:12)

Offline

#59 2016-11-08 07:39:04

ComingNine
Member
Registered: 2010-07-29
Posts: 293

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

ComingNine wrote:

Dear mpv, I am trying to access the "mainForm" exported by the host SpiderMonkey45Binding.exe from the plugin mathModule.dll. The reason behind my attempt is that if this is indeed possible, this looks like a good way of manipulating "central business service" exported by the host .exe from plugin .dll. Complex additional manipulation referencing the "central business service" could be compiled into plugin .dll without changing the host .exe.......

http://www.delphigroups.info/2/f9/304620.html
http://www.delphigroups.info/2/41/523159.html
http://www.delphigroups.info/2/aa/523141.html

According to the links above, the prerequisite is that (1) everything which needs to be referred to in both .exe and .dll should be put into a package, and (2) both .exe and .dll should be built with Runtime-package enabled.

Furethermore, according to the FastMM FAQ, these FullDebugMode, UseRuntimePackages, ShareMM, ShareMMIfLibrary, AttemptToUseSharedMM defines are enabled. Also, according to one post on the FastMM forum, FastMM is put into its own package and referred to in all other packages, .exe, and .dll projects.

However, the problem now is that when testing in Win7 x64 VM (1 core, 2GB mem), memory leaks are reported when main form is shut down, which should be related to the unload order of runtime packages. sad
Note that there are no memory leaks reported in Win10 x61 OS (4 core, 32GB mem).

The modified files are upload as mORMot.20161108151029.zip, and the steps to reproduce the memory leaks are below:

(*

In Win7 x64 VM (1 core, 2GB mem),
use D:\mORMot\SyNode\Samples\02 - Bindings\SpiderMonkey45Binding_D24.bat to run the main form,
paste the javascript below, 
run any of them, 
close main form directly without closing Form1 or Form2, 
there is memory leak:

const mathModule = require('../../Samples/01 - Dll Modules/math-module');
mathModule.work_tform1_1(mainForm)
mathModule.work_tform1_2(mainForm)
mathModule.work_tform1_3(mainForm)
mathModule.work_tform2_1(mainForm)
mathModule.work_tform2_2(mainForm)
mathModule.work_tform2_3(mainForm)

--------------------------------2016/11/8 15:04:04--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

13 - 20 bytes: AnsiString x 2
21 - 36 bytes: AnsiString x 1, Unknown x 2
37 - 52 bytes: TSMDebugger x 1
69 - 84 bytes: TCrtSocket x 1
85 - 100 bytes: TSMRemoteDebuggerThread x 1
149 - 164 bytes: TObjectListLocked x 2
245 - 276 bytes: TRawUTF8ListHashedLocked x 2

*)

ShareMem in the uses clause and replacement BorlndMM.dll in the path does not help.
FastMM's NeverUninstall combined with disabling FastMM's reporting memory leaks completely makes debugging memory leaks much more difficult.

Could you help to comment whether it is possible to prevent the memory leaks when using runtime packages, by making FastMM to unload last or in some other ways ? big_smile

Offline

#60 2017-01-30 14:46:50

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Hi,

In SyNode defineClass can't register a Class with more than 255 methods?
  How can I register a Class with more than 255 methods?

The Code In SyNode.pas

/// Define a Delphi class as JS class (prototype), so it can be created via new:
    //    engine.defineClass(TmyObject, TSMNewRTTIProtoObject);
    //  and in JS
    //    var myObj = new TmyObject();
    // - Class will be exposed in the aParent javaScript object, if aParent is omitted - in the global object
    // - AProto parameter can be a TSMCustomProtoObject descendant (TSMSimpleRTTIProtoObject, TSMNewRTTIProtoObject)
    // WARNING - possible prototypes count is limited to 255 - JSCLASS_GLOBAL_SLOT_COUNT = 76 for SM45,
    //   so it is better to use a bindings, add where a native functions and wrap it in class into the JavaScript
    //   see `fs.js` for sample.
    function defineClass(AForClass: TClass; AProto: TSMCustomProtoObjectClass; aParent: PJSRootedObject = nil): TSMCustomProtoObject;

Offline

#61 2017-01-31 16:03:35

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Current implementation do not support Delphi classes with mote when 255 public members. But for your task (COM object) we have a better solution - see this topic

Offline

#62 2017-02-02 13:30:20

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

@mpv:
Thanks for your help!

I download some lib from http://registry.unitybase.info
@unitybase/stubs and @unitybase/base etc..
but they can't work well with SyNode, is there any thing I need change?
example: when I use http.get("http://www.xxx.com"); it will show _http.writeEnd is not a function,
I have defineClasses THTTPClient but the THTTPClient not have the "writeEnd" method.

Offline

#63 2017-02-02 13:56:23

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Can we use SpiderNode? https://github.com/mozilla/spidernode

Offline

#64 2017-02-02 14:01:56

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Packages from http://registry.unitybase.info registry is not for SyNode, but for our project UnityBase which is based on SyNode. So don't try to use it from SyNode..
But about http - this is a issue, for sure. http must be a part of synode, but we miss a THTTPClient binding. I'll extract it from our source tree and move to SyNode asap
About SpiderNode - this is a port of nodejs from V8 to SpiderMonkey. I don't think it is possible to built-in it into Delphi app.

Last edited by mpv (2017-02-02 14:05:25)

Offline

#65 2017-02-02 14:47:50

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Ok, Great!
Thank you!

Offline

#66 2017-02-03 16:59:53

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Just commit a http binding to SyNode. See updated sample "02 - Bindings" for usage

Offline

#67 2017-02-05 11:15:55

RaelB
Member
Registered: 2010-08-04
Posts: 26

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

ab wrote:

AFAIR the Delphi Web Script JavaScript back-end has been released again under Open Source.

Do you have a reference for that information?

Offline

#68 2017-02-05 11:37:10

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 11,693
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

See https://bitbucket.org/egrange/dwscript/ … ?at=master

The commit is https://bitbucket.org/egrange/dwscript/ … 6ad747811a
Names "JSCodeGen now under GPL v3".
From the 2016-08-05

Offline

#69 2017-02-08 02:29:00

Bo
Member
From: Melbourne
Registered: 2016-07-04
Posts: 43
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Hi mpv,

It seems that the script cannot be run more than once in "SyNode\Samples\02 - Bindings ", the error is "redeclaration of const fs.",
I guess the question is how to clear the script before next calling to FEngine.Evaluate?

Offline

#70 2017-02-08 04:10:48

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

I also want know how to clear the moudles loaded, I just used it Free every times and Create a New TSMEngine...

Offline

#71 2017-02-08 07:09:34

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

There is no way to "clear" the module once it is loaded (like there is no way to "un-uses" unit in Delphi ). And normally you never need such.
Sample 02 execute only selected lines, so to read file twice (for example) in first time select end execute

const fs = require('fs');
const path = require('path');
let content
content = fs.readFileSync(path.join(process.cwd(), 'ExtendDebuggerConsole.js'));
mainForm.toLog(content);

And after this exec as many time as you need

content = fs.readFileSync(path.join(process.cwd(), 'ExtendDebuggerConsole.js'));
mainForm.toLog(content);

If you need to execute something with side effects several time you need to put it into block (in ES6 block create a variable scope):

{
  const fs = require('fs');
  const path = require('path');
  let content = fs.readFileSync(path.join(process.cwd(), 'ExtendDebuggerConsole.js'));
  mainForm.toLog(content);
}

Or use a ES5 pattern - selt-executed function

(function(){
  const fs = require('fs');
  const path = require('path');
  let content = fs.readFileSync(path.join(process.cwd(), 'ExtendDebuggerConsole.js'));
  mainForm.toLog(content);
})()

In any case module required only once

Offline

#72 2017-02-08 22:19:56

Bo
Member
From: Melbourne
Registered: 2016-07-04
Posts: 43
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

markzql wrote:

I also want know how to clear the moudles loaded, I just used it Free every times and Create a New TSMEngine...

How did you do it?

Initially, I used following code and it threw AVs:

// evaluate a text from mSource memo
  FEngine := FSMManager.ThreadSafeEngine(nil);
  try

    if mSource.SelText <> '' then
      FEngine.Evaluate(mSource.SelText, 'mSourceSelected.js', 1, res)
    else
      FEngine.Evaluate(mSource.lines.Text, 'mSource.js', 1, res);

  finally
    FreeAndNil(FEngine);   
  end;

Then I change the way it freed and it seemed OK now:

// evaluate a text from mSource memo
  FEngine := FSMManager.ThreadSafeEngine(nil);
  try

    if mSource.SelText <> '' then
      FEngine.Evaluate(mSource.SelText, 'mSourceSelected.js', 1, res)
    else
      FEngine.Evaluate(mSource.lines.Text, 'mSource.js', 1, res);

  finally
    //FreeAndNil(FEngine);   
    FSMManager.ReleaseCurrentThreadEngine();
  end;

Offline

#73 2017-02-08 22:31:20

Bo
Member
From: Melbourne
Registered: 2016-07-04
Posts: 43
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

mpv wrote:

There is no way to "clear" the module once it is loaded (like there is no way to "un-uses" unit in Delphi ). And normally you never need such.
Sample 02 execute only selected lines, so to read file twice (for example) in first time select end execute
...
In any case module required only once

The solution you provided is OK in this sample (i.e., interactive), what if the engine is pooled and its script is loaded from script files which are written by the end users (for example, an integration engine runs customized scripts for data processing)? How the end users should program the scripts to avoid "redefine" issue we are talking here?

Offline

#74 2017-02-09 09:47:55

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

@Bo In this case end users should program his scripts as a module - see how modules work
User script myCalculation.js:

const fs = require('fs')
...
function onInit(){ ....}
function onDone(){..}
function doCalculation(){...}
module.exports = doCalculation
// another way is to export a several methods
//  module.exports.onInit = onInit; module.exports.onDone = onDone; module.exports.doCalculation = doCalculation;

Your code

FEngine.Evaluate('require("myCalculation")()', 'eval.js', 1, res)

Modules (user code in your case) are wrapped in closure by require function - you can see this in debugger

Offline

#75 2017-02-09 10:40:49

Bo
Member
From: Melbourne
Registered: 2016-07-04
Posts: 43
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

mpv wrote:

@Bo In this case end users should program his scripts as a module - see how modules work
User script myCalculation.js:

const fs = require('fs')
...
function onInit(){ ....}
function onDone(){..}
function doCalculation(){...}
module.exports = doCalculation
// another way is to export a several methods
//  module.exports.onInit = onInit; module.exports.onDone = onDone; module.exports.doCalculation = doCalculation;

Your code

FEngine.Evaluate('require("myCalculation")()', 'eval.js', 1, res)

Modules (user code in your case) are wrapped in closure by require function - you can see this in debugger

This will be the equivalent of specifying an entry function in using MSScript.ocx as the script engine wrapper.

Offline

#76 2017-02-09 11:46:06

Bo
Member
From: Melbourne
Registered: 2016-07-04
Posts: 43
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Hi mpv,

Re: SyNode Sample 02, I have found that if the code was referring to a non-existed property of the main form (wrong spelling or capitalized etc.), it raised an generic AV which is not helpful at all, for example, this line of code "mainForm.toLog(mainForm.Caption);" will raise an AV in which does not tell  you the line no, what type of error etc., but "mainForm.ToLog(mainForm.caption);" does. What can we do to improve catching/avoid this type of error?

Offline

#77 2017-02-09 12:06:05

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Actual issue is inside mainForm.toLog function. Fixed by [70cc3773fb]

Offline

#78 2017-02-12 12:22:47

Bo
Member
From: Melbourne
Registered: 2016-07-04
Posts: 43
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

mpv wrote:

Actual issue is inside mainForm.toLog function. Fixed by [70cc3773fb]

This fix does stop the AV, it would be nice if it can actual tell the script author that the variable passed in is undefined.

Also, I have noticed that there is another set of TSMEngineManager and TSMEngine etc in units SynSM, and they use Spider Monkey v24 instead of v45 in SyNode,
what are the main differences? What are the different using scenarios?

Offline

#79 2017-02-13 16:19:00

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Spider Monkey v24 implement a EcmaScript5, v45 - ES6

Offline

#80 2017-02-19 18:23:15

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Wow, node.js inside delphi!
Great work!
Is there a way to use VSCODE as development tool with their debugger?
I assume that map files (i have typescript sources) will not work?
How fast SyNode in comparison with NodeJS?

Last edited by George (2017-02-19 18:25:03)

Offline

#81 2017-02-19 20:00:17

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Not sure about VSCODE, but you can use Firefox remote debugger. AFAIK map files should work.
In most cases SyNode is faster compared do NodeJS (at techempower tests - twice faster - see https://github.com/UnityBaseJS/benchmarks). This is because of SpiderMonkey optimizer and a fact what SyNode don't use a event loop (SyNode is synchronous & multi-thread, nodeJS is single thread and asynchronous)

Offline

#82 2017-03-10 19:35:40

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

SyNode evaluates threadID automatically via "GetCurrentThreadId".
I have thread pool, which means that thread ID may be different.
While looking how to pass thru custom ID inside ThreadSafeEngine, i've found comment line: "SM 45 expects the context to be released in the same thread".

So, SyNode should not be used in applications with thread pool, right?
Then what is the best approach, may be private threads for each SM Engine?

Last edited by George (2017-03-10 19:52:03)

Offline

#83 2017-03-12 11:51:23

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

SyNode & SynSM are multithread by design (opposite to nodeJS & V8). See "22 - JavaScript HTTPApi web server". You should call SMManager.ThreadSafeEngine inside your working thread, as in TTestServer.Process from sample 22

Last edited by mpv (2017-03-12 11:52:58)

Offline

#84 2017-03-18 17:19:46

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Just for experiment purpose, i've created SyNode app with multiple FSMManager's each in separate thread.
For example if application need to work separately with different "coremodules" folders, with different "MaxPerEngineMemory" values, and so on.
That may be useless or not, don't know now)

Last edited by George (2017-03-18 17:20:32)

Offline

#85 2017-03-31 22:42:19

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

mpv wrote:

Not sure about VSCODE, but you can use Firefox remote debugger. AFAIK map files should work.

I hope that should be way to debug js from vscode...
Found special extension that can successfully connect with spidermonkey debugger.
But breakpoints not work.

As i saw in firefox, spidermonkey app determines as firefox addon.
Extension page says that 3 types of addons are supported: addonSdk, webExtension and legacy.
Regarding of addon type, corresponding config file is required.
Which type of addon SyNode simulate for debugging?

Last edited by George (2017-03-31 22:56:25)

Offline

#86 2017-04-01 08:05:43

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Interesting finding! Our primary IDE is WebStorm, but it not work directly with FireFox Remote Debugger Protocol, so we even don't investigate IDE integration. I just installed a VSCode and try to understand how it work...
TIPS: the main entry point for debugger is TSMRemoteDebuggerCommunicationThread.HandleMessage.

I move VSCode topic here

Last edited by mpv (2017-04-01 14:29:08)

Offline

#87 2017-04-01 12:23:58

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

SyNode now support latest SpiderMonkey52 engine - see [1adba740c7] ( to use it define a condition variable SM52).
You can build mozjs52 using BUild instruction , or download from URLs noted in SyNode.pas
SpiderMonkey52 not yet officially released by Mozilla, for example we can't build it without Promises and know some minor issues in debugger, but most of things work well.

Our next steps is:
- compile SyNode using NewPascal  (Windows target)
- compile SyNode using NewPascal  (Linux x64 target)

Last edited by mpv (2017-04-01 12:25:25)

Offline

#88 2017-04-02 10:43:42

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 11,693
Website

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

NewPascal support, especially under Linux, will make it a KILLING solution...

Offline

#89 2017-08-20 08:51:40

ComingNine
Member
Registered: 2010-07-29
Posts: 293

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Dear mpv, could you share us the news of SyNode support with NewPascal under Linux smile

Offline

#90 2017-08-27 09:03:15

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Hi @mpv
I download the dlls from x32: https://unitybase.info/downloads/mozjs-45.zip
Then I define SM52 on the global level, and it can run now, but in the COM object it shows an error.
I used the  UBComBridge from @unitybase\com-bridge,

var dm = createobject("dm.dmsoft");
Log(dm.Ver());  

This code is ok with SM45, but in the SM52 it will show

dm.Ver is not a function .

.
Is there something wrong with SM52?

Offline

#91 2017-08-28 20:55:46

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Hi, mpv!

What is the best approach to add "console" emulation for JS context?
Should i create a class with all required methods, instantiate it and then call aEngine.GlobalObject.ptr.DefineProperty?
Is there a way to group few methods in one variable (like console.log, console.clear) without class instance on delphi side?
PS: dll extension can provide such behavior, but i'm interested to implement console internally.

Offline

#92 2017-08-29 07:22:10

Orel
Member
Registered: 2014-04-14
Posts: 11

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

George wrote:

Hi, mpv!

What is the best approach to add "console" emulation for JS context?
Should i create a class with all required methods, instantiate it and then call aEngine.GlobalObject.ptr.DefineProperty?
Is there a way to group few methods in one variable (like console.log, console.clear) without class instance on delphi side?
PS: dll extension can provide such behavior, but i'm interested to implement console internally.

The best idea is group them in *.js file(like nodejs does). You can see source code of node's console.js on GitHub
In this case you must implement some bindings. You can find examples of bindings in Synode code. Also you can find implementation of nodejs binding on GitHub and translate it to Delphy synode SpiderMonkey compatible code
If you will do this then sharing code to community will be a good idea

Offline

#93 2017-08-29 12:13:43

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Thanks, will try.

Last edited by George (2017-08-30 16:02:30)

Offline

#94 2017-08-29 12:46:58

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

markzql wrote:

Hi @mpv
I download the dlls from x32: https://unitybase.info/downloads/mozjs-45.zip
Then I define SM52 on the global level, and it can run now, but in the COM object it shows an error.
I used the  UBComBridge from @unitybase\com-bridge,

var dm = createobject("dm.dmsoft");
Log(dm.Ver());  

This code is ok with SM45, but in the SM52 it will show

dm.Ver is not a function .

.
Is there something wrong with SM52?

Just fix this error in @unitybase/com-bridge@1.0.7. Thanks for report!
Here is the patch

Offline

#95 2017-08-29 12:54:11

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

ComingNine wrote:

Dear mpv, could you share us the news of SyNode support with NewPascal under Linux smile

We spend a month (or even more) just to compile a stand alone SpiderMonkey mozjs.so under Ubuntu due to this bug in config. So work move very slowly...

Offline

#96 2017-08-29 13:03:45

markzql
Member
Registered: 2017-01-30
Posts: 12

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Hi @mpv,
It's OK now!

I still think it's perfect to register over 255 functions for the defineClasses.
I have a few classes they have more than 255 functions.

how ever it's great now!

Thanks!

Offline

#97 2017-09-04 20:43:12

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Need little help, i get strange results while debugging Debugger.js.

    constructor (actorID, source, parent) {
        super(actorID, parent);
        parent._sourcesMap.set(source, this)
        this._source = source;
        this._breakpoints = {};
    }
    ...
    get _resp(){
        let source = this._source;// || this.generatedSource;
        consoleLog(stringify(source));   // -> [object undefined]
        consoleLog(source.url);          // -> ModuleLoader.js
        ...

How that possible?

With JSON.stringify i get:

    get _resp(){
        let source = this._source;// || this.generatedSource;
        consoleLog(JSON.stringify(source)); // -> {}
        consoleLog(source.url);             // -> ModuleLoader.js
        ...

I use output log to debug Debugger.js, is better way exists?

Last edited by George (2017-09-04 20:53:46)

Offline

#98 2017-09-05 07:15:02

Orel
Member
Registered: 2014-04-14
Posts: 11

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

George wrote:

Need little help, i get strange results while debugging Debugger.js.
...
I use output log to debug Debugger.js, is better way exists?

consoleLog(JSON.stringify(source)); // -> {}

is usual behavior for internal debugger's objects
We used for debug debugger

consoleLog(stringify(source.<propertyName>));

List of properties you can see on MDN
But I am not sure that information on that page is actual, so I recommend You see also source code

Offline

#99 2017-09-12 07:54:20

George
Member
Registered: 2016-04-05
Posts: 116

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

Inside folder "core_modules" present file "console.js", inside file i see comment:

Modified by UnityBase core team to be compatible with SyNode

Module initialization relies on process.stdout, process.stderr.
Maybe someone already have usage sample (per engine global console implementation linked with callback from delphi side)?
Or information about how that can be done..

I want create simple demo application that will use more features than shown in current two demos.
With vscode debugger support.

Last edited by George (2017-09-12 08:46:16)

Offline

#100 2017-09-13 08:37:04

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

Re: Beta release of SyNode - ES6 JavaScript + NPM modules

To make a console work, host application (Delphi executable what create a JS engine) must define process.stdout and process.stderr objects with write method. But this strongly relay on host process, so we do not put implementation inside SyNode.

Global object process is already defined by SMEngine - see TSMEngine.Create

So to implement a stdin & stdout in our application we put this code inside a SMManager.OnNewEngine handler

Multiple threads write to a process std* using SynLog writer - with EchoToConsole enabled 

 Log.Family.EchoToConsole := [sllWarning, sllError, sllLastError, sllException, sllExceptionOS, sllMemory] 

Last edited by mpv (2017-09-13 08:40:43)

Offline

Board footer

Powered by FluxBB