source upload

This commit is contained in:
Razor12911
2022-01-17 22:16:47 +02:00
parent 12936d065b
commit 098e8c48de
1778 changed files with 1206749 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
{
"name": "math-module",
"version": "1.0.0",
"description": "Native (dll) module sample for SyNode",
"main": "./build/mathModule.dll",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"SyNode"
],
"author": "pavel.mash <pavel.mash@gmail.com> (https://unitybase.info)",
"license": "MIT"
}

View File

@@ -0,0 +1,54 @@
library MathModule;
uses
FastMM4,
SysUtils,
Classes,
Windows,
SpiderMonkey,
SyNodePluginIntf,
uMathModule in 'uMathModule.pas';
const
MAX_THREADS = 256;
// just copy Empty plugin,
// create unit with your plugin realization(descendant of the TCustomSMPlugin)
// and override methods Init and UnInit is needed
PluginType: TCustomSMPluginType = TSMMathPlugin; //In real realization you must declare you own class child of TCustomSMPlugin and override methods Init and UnInit
var
ThreadRecs: array[0..MAX_THREADS] of TThreadRec;
threadCounter: integer;
function InitPlugin(cx: PJSContext; exports_: PJSRootedObject; require: PJSRootedObject; module: PJSRootedObject; __filename: PWideChar; __dirname: PWideChar): boolean; cdecl;
var
l: integer;
begin
l := InterlockedIncrement(threadCounter);
if l>=MAX_THREADS then
raise Exception.Create('Too many thread. Max is 256');
ThreadRecs[l].threadID := GetCurrentThreadId;
ThreadRecs[l].plugin := PluginType.Create(cx, exports_, require, module, __filename, __dirname);
result := true;
end;
function UnInitPlugin(): boolean; cdecl;
var
i: integer;
begin
for I := 0 to MAX_THREADS - 1 do
if ThreadRecs[i].threadID = GetCurrentThreadId then begin
ThreadRecs[i].threadID := 0;
FreeAndNil(ThreadRecs[i].plugin);
end;
result := true;
end;
exports InitPlugin;
exports UnInitPlugin;
begin
IsMultiThread := True; //!!IMPORTANT for FastMM
threadCounter := -1;
FillMemory(@ThreadRecs[0], SizeOf(ThreadRecs), 0);
end.

View File

@@ -0,0 +1,125 @@
unit uMathModule;
interface
uses
SyNodePluginIntf;
type
TSMMathPlugin = class(TCustomSMPlugin)
procedure UnInit; override;
procedure Init(const rec: TSMPluginRec); override;
end;
implementation
uses
SpiderMonkey, SysUtils;
{ TSMMathPlugin }
type
TMathFun = function (const X, Y : Extended) : Extended;
function DoMathFun(cx: PJSContext; argc: uintN; var vp: JSArgRec; fun: TMathFun): Boolean; cdecl;
var
in_argv: PjsvalVector;
aVal1, aVal2, aRes: Double;
val: jsval;
begin
try
in_argv := vp.argv;
if (argc<>2) then
raise ESMException.Create('invalid args count for math function. Required (Number, Number)')
else if not in_argv[0].isNumber or not in_argv[1].isNumber then
raise ESMException.CreateUTF8('invalid args for math function. Required (Number, Number) but got (%, %)', [integer(in_argv[0].ValType(cx)), integer(in_argv[1].ValType(cx))]);
if in_argv[0].isInteger then
aVal1 := in_argv[0].asInteger
else
aVal1 := in_argv[0].asDouble;
if in_argv[1].isInteger then
aVal2 := in_argv[1].asInteger
else
aVal2 := in_argv[1].asDouble;
aRes := fun(aVal1, aVal2);
val.asDouble := aRes;
vp.rval := val;
Result := True;
except
on E: Exception do begin
Result := False;
vp.rval := JSVAL_VOID;
JSError(cx, E);
end;
end;
end;
function DoAdd(const X, Y : Extended) : Extended;
begin
result := X+Y;
end;
function DoSub(const X, Y : Extended) : Extended;
begin
result := X-Y;
end;
function DoMul(const X, Y : Extended) : Extended;
begin
result := X*Y;
end;
function DoDiv(const X, Y : Extended) : Extended;
begin
if Y = 0 then
raise ESMException.Create('division by zero');
result := X/Y;
end;
function math_add(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
begin
result := DoMathFun(cx, argc, vp, DoAdd);
end;
function math_sub(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
begin
result := DoMathFun(cx, argc, vp, DoSub);
end;
function math_mul(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
begin
result := DoMathFun(cx, argc, vp, DoMul);
end;
function math_div(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
begin
result := DoMathFun(cx, argc, vp, DoDiv);
end;
procedure TSMMathPlugin.Init(const rec: TSMPluginRec);
var val: jsval;
begin
inherited;
// this method is called when SM Engine required this plugin
// here you can define exports (rec.Exp) properties
// or redefime module (rec.Module) property 'exports'
rec.Exp.ptr.DefineFunction(rec.cx, 'add', math_add, 2, StaticROAttrs);
rec.Exp.ptr.DefineFunction(rec.cx, 'sub', math_sub, 2, StaticROAttrs);
rec.Exp.ptr.DefineFunction(rec.cx, 'mul', math_mul, 2, StaticROAttrs);
rec.Exp.ptr.DefineFunction(rec.cx, 'div', math_div, 2, StaticROAttrs);
val.asDouble := pi;
rec.Exp.ptr.DefineProperty(rec.cx, 'pi', val, StaticROAttrs, nil, nil);
end;
procedure TSMMathPlugin.UnInit;
begin
inherited;
// this method is called when SM Engine destroyed
// here you can finaliza your plugin if it is needed
end;
end.

View File

@@ -0,0 +1 @@
lib/

View File

@@ -0,0 +1,69 @@
import {setConsoleCommands, setConsoleMessageResolver} from 'DevTools/Debugger.js';
let dbg_binding = process.binding('debugger'),
global = dbg_binding.global;
setConsoleCommands({
help: () => 'Welcome to SyNode console.',
'$cwd': {
command: () => {return global.process.cwd(); },
description: 'Show current working dir'
},
'$mormot': {
command: () => 'http://synopse.info',
description:
`Show where the mORMot live.
Remember - RTFM before write to forum :)`
}
});
setConsoleMessageResolver((msg) => {
let timestamp = (new Date(msg.substr(0,4)+'-'+msg.substr(4,2)+'-'+msg.substr(6,2)+'T'+msg.substr(9,2)+':'+msg.substr(11,2)+':'+msg.substr(13,2)+'.'+msg.substr(15,2)+'0Z')).getTime(),
logLevel = msg.substr(20,7),
level,
category;
if (timestamp) {
msg = msg.substr(20).replace(/\t/gi, ' ');
const logLevelMap = {
' ': {category: 'webdev', level: 'log'},
' info ': {category: 'webdev', level: 'log'},
' debug ': {category: 'server', level: 'info'},
' trace ': {category: 'webdev', level: 'log'},
' warn ': {category: 'webdev', level: 'warn'},
' ERROR ': {category: 'webdev', level: 'error'},
' + ': {category: 'webdev', level: 'log'},
' - ': {category: 'webdev', level: 'log'},
' OSERR ': {category: 'webdev', level: 'error'},
' EXC ': {category: 'webdev', level: 'error'},
' EXCOS ': {category: 'webdev', level: 'error'},
' mem ': {category: 'webdev', level: 'log'},
' stack ': {category: 'webdev', level: 'log'},
' fail ': {category: 'webdev', level: 'error'},
' SQL ': {category: 'webdev', level: 'info'},
' cache ': {category: 'webdev', level: 'log'},
' res ': {category: 'webdev', level: 'log'},
' DB ': {category: 'webdev', level: 'log'},
' http ': {category: 'network', level: 'log'},
' clnt ': {category: 'network', level: 'warn'},
' srvr ': {category: 'network', level: 'warn'},
' call ': {category: 'webdev', level: 'log'},
' ret ': {category: 'webdev', level: 'log'},
' auth ': {category: 'server', level: 'log'},
' cust1 ': {category: 'js', level: 'warn'},
' cust2 ': {category: 'server', level: 'warn'},
' cust3 ': {category: 'webdev', level: 'log'},
' cust4 ': {category: 'webdev', level: 'log'},
' rotat ': {category: 'webdev', level: 'log'},
' dddER ': {category: 'webdev', level: 'log'},
' dddIN ': {category: 'webdev', level: 'log'},
' mon ': {category: 'webdev', level: 'log'}
};
level = logLevelMap[logLevel].level;
category = logLevelMap[logLevel].category;
} else {
timestamp = Date.now();
category = 'webdev';
level = 'log';
}
return {level: level, category: category, msg: msg, timeStamp: timestamp}
});

View File

@@ -0,0 +1,34 @@
program SpiderMonkey45Binding;
uses
FastMM4,
Forms,
ufrmSM45Demo in 'ufrmSM45Demo.pas' {frmSM45Demo},
NSPRAPI in '..\..\NSPRAPI.pas',
SpiderMonkey in '..\..\SpiderMonkey.pas',
SyNode in '..\..\SyNode.pas',
SyNodeBinding_fs in '..\..\SyNodeBinding_fs.pas',
SyNodeBinding_HTTPClient in '..\..\SyNodeBinding_HTTPClient.pas',
SyNodeProto in '..\..\SyNodeProto.pas',
SyNodeRemoteDebugger in '..\..\SyNodeRemoteDebugger.pas',
SyNodeSimpleProto in '..\..\SyNodeSimpleProto.pas',
SyNodeBinding_worker in '..\..\SyNodeBinding_worker.pas',
SyNodeBinding_const in '..\..\SyNodeBinding_const.pas',
SyNodeBinding_buffer in '..\..\SyNodeBinding_buffer.pas',
SyNodeBinding_util in '..\..\SyNodeBinding_util.pas',
SyNodeBinding_uv in '..\..\SyNodeBinding_uv.pas',
SyNodeReadWrite in '..\..\SyNodeReadWrite.pas';
{$R *.res}
begin
InitJS;
try
Application.Initialize;
Application.CreateForm(TfrmSM45Demo, frmSM45Demo);
Application.Run;
finally
frmSM45Demo.Free;
ShutDownJS;
end;
end.

View File

@@ -0,0 +1,160 @@
 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{CF53FAB5-8ADD-444D-A0C2-ACC4AF9E90D6}</ProjectGuid>
<MainSource>SpiderMonkey45Binding.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>13.4</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_UnitSearchPath>..\..\..\..\FastMM4;..\..\..;..\..\..\SQLite3;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_F>false</DCC_F>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>SpiderMonkey45Binding_Icon1.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_DcuOutput>obj\win32</DCC_DcuOutput>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Icon_MainIcon>SpiderMonkey45Binding_Icon1.ico</Icon_MainIcon>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_Define>SM52;$(DCC_Define)</DCC_Define>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="ufrmSM45Demo.pas">
<Form>frmSM45Demo</Form>
</DCCReference>
<DCCReference Include="..\..\NSPRAPI.pas"/>
<DCCReference Include="..\..\SpiderMonkey.pas"/>
<DCCReference Include="..\..\SyNode.pas"/>
<DCCReference Include="..\..\SyNodeBinding_fs.pas"/>
<DCCReference Include="..\..\SyNodeBinding_HTTPClient.pas"/>
<DCCReference Include="..\..\SyNodeProto.pas"/>
<DCCReference Include="..\..\SyNodeRemoteDebugger.pas"/>
<DCCReference Include="..\..\SyNodeSimpleProto.pas"/>
<DCCReference Include="..\..\SyNodeBinding_worker.pas"/>
<DCCReference Include="..\..\SyNodeBinding_const.pas"/>
<DCCReference Include="..\..\SyNodeBinding_buffer.pas"/>
<DCCReference Include="..\..\SyNodeBinding_util.pas"/>
<DCCReference Include="..\..\SyNodeBinding_uv.pas"/>
<DCCReference Include="..\..\SyNodeReadWrite.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">SpiderMonkey45Binding.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="Win64">False</Platform>
<Platform value="Win32">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
</Project>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="10"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="SpiderMonkey45Binding"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="SpiderMonkey45Binding.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="ufrmSM45Demo.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="frmSM45Demo"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="SpiderMonkey45Binding"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);../../..;../.."/>
<OtherUnitFiles Value="../../..;../..;../../../SQLite3"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Conditionals Value="if TargetOS='darwin' then
CustomOptions := ' -Cg-';"/>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CustomOptions Value="-dSM52"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,31 @@
program SpiderMonkey45Binding;
uses
{$I SynDprUses.inc}
Forms,
{$ifdef FPC}
Interfaces,
{$endif}
ufrmSM45Demo in 'ufrmSM45Demo.pas' {frmSM45Demo},
NSPRApi in '..\..\NSPRAPI.pas',
SpiderMonkey in '..\..\SpiderMonkey.pas',
SyNode in '..\..\SyNode.pas',
SyNodeBinding_fs in '..\..\SyNodeBinding_fs.pas',
SyNodeBinding_HTTPClient in '..\..\SyNodeBinding_HTTPClient.pas',
SyNodeProto in '..\..\SyNodeProto.pas',
SyNodeRemoteDebugger in '..\..\SyNodeRemoteDebugger.pas',
SyNodeSimpleProto in '..\..\SyNodeSimpleProto.pas';
{$R *.res}
begin
InitJS;
try
Application.Initialize;
Application.CreateForm(TfrmSM45Demo, frmSM45Demo);
Application.Run;
finally
frmSM45Demo.Free;
ShutDownJS;
end;
end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

View File

@@ -0,0 +1,81 @@
object frmSM45Demo: TfrmSM45Demo
Left = 362
Height = 516
Top = 176
Width = 771
Caption = 'SyNode (Synopse SpiderMonkey with NodeJS modules) demo'
ClientHeight = 516
ClientWidth = 771
Color = clBtnFace
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
OnCreate = FormCreate
OnDestroy = FormDestroy
LCLVersion = '2.0.0.2'
object mSource: TMemo
Left = 16
Height = 414
Top = 24
Width = 442
Lines.Strings = (
'/*'
'1) We define a property global.mainForm = binding to this Deplhi form'
'2) JavaScript debugger is listeninng on the localhost:6000'
' - to debug run Firefox with -chrome flag as below'
' "C:\Program Files\Firefox Developer Edition\firefox.exe" -chrome chrome://devtools/content/framework/connect/connect.xhtml'
'OR'
' - enable a remote debugger: https://developer.mozilla.org/ru/docs/Tools/Remote_Debugging#On_the_desktop_2'
' - go to chrome://devtools/content/framework/connect/connect.xhtml'
'FF58 for windows has known bug with remote debugger - use either FF57 or FF59 (developer edition)'
'*/'
''
'mainForm.caption = new Date().toLocaleString();'
'mainForm.top = 10;'
''
'const fs = require(''fs'');'
'const path = require(''path'');'
'let content = fs.readFileSync(path.join(process.cwd(), ''ExtendDebuggerConsole.js''), ''utf8'');'
'mainForm.toLog(content);'
'/*'
' * You can evaluate script below if you compiled math-module sample'
' * to SyNode\Samples\01 - Dll Modules\math-module\build\mathModule.dll'
' */'
''
'/*'
'const mathModule = require(''''../../Samples/01 - Dll Modules/math-module'''');'
'mainForm.toLog(''''PI='''' + mathModule.pi);'
'mainForm.toLog(`(1+ 2)=${mathModule.add(1, 2)}`);'
'mainForm.toLog(`16/3=${mathModule.div(16, 3)}`);'
'*/'
''
'const http = require(''http'');'
'const assert = require(''assert'');'
'// set global proxy settings if client is behind a proxy'
'// http.setGlobalProxyConfiguration(''''proxy.main:3249'''', ''''localhost'''');'
'let resp = http.get(''https://synopse.info/fossil/wiki/Synopse+OpenSource'');'
'// check we are actually behind a proxy'
'// assert.ok(resp.headers(''''via'''').startsWith(''''1.1 proxy.main''''), ''''proxy used'''');'
'let index = resp.read();'
'mainForm.toLog(index);'
)
TabOrder = 0
WordWrap = False
end
object mResult: TMemo
Left = 464
Height = 414
Top = 24
Width = 249
TabOrder = 1
end
object btnEvaluate: TButton
Left = 16
Height = 25
Top = 444
Width = 129
Caption = 'Evaluate selected'
OnClick = btnEvaluateClick
TabOrder = 2
end
end

View File

@@ -0,0 +1,255 @@
unit ufrmSM45Demo;
interface
uses
{$IFNDEF LCL}Windows,{$ELSE}LclIntf, LMessages, LclType, LResources,{$ENDIF}
Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls,
SynCommons,
SpiderMonkey,
SyNode,
SyNodeProto,
SyNodeSimpleProto;
const
WM_DEBUG_INTERRUPT = WM_USER + 1;
type
{ TfrmSM45Demo }
TfrmSM45Demo = class(TForm)
mSource: TMemo;
mResult: TMemo;
btnEvaluate: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnEvaluateClick(Sender: TObject);
private
procedure cmd_Itenterupt(var aMessage: TMessage); message WM_DEBUG_INTERRUPT;
protected
FSMManager: TSMEngineManager;
FEngine: TSMEngine;
procedure DoOnCreateNewEngine(const aEngine: TSMEngine);
function DoOnGetEngineName(const aEngine: TSMEngine): RawUTF8;
// a handler, called from a debugger thread to interrupt a current thread
// in this example will send a WM_DEBUG_INTERRUPT message to a main window
// main application thread catch a message and call FEngine.InterruptCallback
procedure doInteruptInOwnThread;
/// here we add features to debugger console
// type ? in firefox console to get a feature help
procedure DoOnJSDebuggerInit(const aEngine: TSMEngine);
published
property sources: TMemo read mSource;
property results: TMemo read mResult;
property evaluateButton: TButton read btnEvaluate;
function toLog(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean;
end;
var
frmSM45Demo: TfrmSM45Demo;
implementation
{$R *.dfm}
{$I Synopse.inc}
{$I SynSM.inc} // define SM_DEBUG JS_THREADSAFE CONSIDER_TIME_IN_Z
{$I SyNode.inc} // define SM_DEBUG CONSIDER_TIME_IN_Z
procedure TfrmSM45Demo.FormCreate(Sender: TObject);
begin
// create a JavaScript angine manager
FSMManager := TSMEngineManager.Create(
{$IFDEF CORE_MODULES_IN_RES}''{$ELSE}StringToUTF8(RelToAbs(ExeVersion.ProgramFilePath, '../../core_modules')){$ENDIF});
// optionaly increase a max engine memory
FSMManager.MaxPerEngineMemory := 512 * 1024 * 1024;
// add a handler called every time new engine is created
// inside a handler we can add a binding's to a native functions (implemented in Delphi)
// and evaluate some initial JavaScripts
FSMManager.OnNewEngine := DoOnCreateNewEngine;
FSMManager.OnGetName := DoOnGetEngineName;
FSMManager.OnDebuggerInit := DoOnJSDebuggerInit;
// start a JavaScript debugger on the localhost:6000
FSMManager.startDebugger('6000');
// debugger can see engines created after startDebugger() call,
// so we create a main engine after debugger is started
// in this example we need only one engine (we are single-thread)
FEngine := FSMManager.ThreadSafeEngine(nil);
end;
procedure TfrmSM45Demo.FormDestroy(Sender: TObject);
begin
FSMManager.ReleaseCurrentThreadEngine;
FSMManager.Free;
end;
procedure TfrmSM45Demo.btnEvaluateClick(Sender: TObject);
var
res: jsval;
begin
if FEngine = nil then
raise Exception.Create('JS engine not initialized');
// evaluate a text from mSource memo
if mSource.SelText <> '' then
FEngine.Evaluate(mSource.SelText, 'mSourceSelected.js', 1, res)
else
FEngine.Evaluate(mSource.lines.Text, 'mSource.js', 1, res);
end;
procedure TfrmSM45Demo.cmd_Itenterupt(var aMessage: TMessage);
begin
if FEngine = nil then
raise Exception.Create('JS engine not initialized');
{$IFDEF SM52}
FEngine.cx.RequestInterruptCallback;
FEngine.cx.CheckForInterrupt;
{$ELSE}
FEngine.rt.InterruptCallback(FEngine.cx);
{$ENDIF}
end;
procedure TfrmSM45Demo.doInteruptInOwnThread;
begin
PostMessage(Self.Handle, WM_DEBUG_INTERRUPT, 0, 0);
{$IFNDEF FPC}
Application.ProcessMessages;
{$ENDIF}
end;
function TfrmSM45Demo.toLog(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean;
begin
try
if (vp.argv[0].isString) then
mResult.lines.add(vp.argv[0].asJSString.ToString(cx))
else
raise ESMException.Create('toLog accept only String type of arg');
result := true;
except
on E: Exception do
begin
Result := False;
JSError(cx, E);
end;
end;
end;
type
TStringsProto = class(TSMSimpleRTTIProtoObject)
protected
procedure InitObject(aParent: PJSRootedObject); override;
end;
procedure TfrmSM45Demo.DoOnCreateNewEngine(const aEngine: TSMEngine);
begin
// for main thread only. Worker threads do not need this
if GetCurrentThreadId = MainThreadID then begin
aEngine.doInteruptInOwnThread := doInteruptInOwnThread;
// in XE actual class of TMemo.lines is TMemoStrings - let's force it to be a TStrings like
aEngine.defineClass(mSource.lines.ClassType, TStringsProto, aEngine.GlobalObject);
// define a propery mainForm in the JavaScript
aEngine.GlobalObject.ptr.DefineProperty(aEngine.cx, 'mainForm',
// proeprty value is a wrapper around the Self
CreateJSInstanceObjForSimpleRTTI(aEngine.cx, Self, aEngine.GlobalObject),
// we can enumerate this property, it read-only and can not be deleted
JSPROP_ENUMERATE or JSPROP_READONLY or JSPROP_PERMANENT
);
end;
end;
function TfrmSM45Demo.DoOnGetEngineName(const aEngine: TSMEngine): RawUTF8;
begin
if GetCurrentThreadId = MainThreadID then
result := 'FormEngine';
end;
procedure TfrmSM45Demo.DoOnJSDebuggerInit(const aEngine: TSMEngine);
begin
// aEngine.EvaluateModule(
// {$IFDEF MSWINDOWS}
// '..\..\..\..\DebuggerInit.js'
// {$ELSE}
// '../../../../DebuggerInit.js'
// {$ENDIF}
// );
end;
{ TStringsProto }
function TStringsTextWrite(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
var
this: PJSObject;
proto: TSMCustomProtoObject;
Instance: PSMInstanceRecord;
begin
try
this := vp.thisObject[cx];
if IsProtoObject(cx, this, proto) then begin
vp.rval := JSVAL_NULL;
Result := True;
exit;
end;
if not IsInstanceObject(cx, this, Instance) then
raise ESMException.Create('No privat data!');
TStrings(Instance.instance).Text := vp.argv[0].asJSString.ToString(cx);
Result := True;
except
on E: Exception do
begin
Result := False;
JSError(cx, E);
end;
end;
end;
function TStringsTextRead(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean; cdecl;
var
this: PJSObject;
proto: TSMCustomProtoObject;
Instance: PSMInstanceRecord;
begin
try
this := vp.thisObject[cx];
if IsProtoObject(cx, this, proto) then begin
vp.rval := JSVAL_NULL;
Result := True;
exit;
end;
if not IsInstanceObject(cx, this, Instance) then
raise ESMException.Create('No privat data!');
vp.rval := SimpleVariantToJSval(cx, TStrings(Instance.instance).Text);
Result := True;
except
on E: Exception do
begin
Result := False;
JSError(cx, E);
end;
end;
end;
procedure TStringsProto.InitObject(aParent: PJSRootedObject);
var
idx: Integer;
begin
inherited;
idx := Length(FJSProps);
SetLength(FJSProps, idx + 1);
FJSProps[idx].flags := JSPROP_ENUMERATE or JSPROP_PERMANENT or JSPROP_SHARED;
FJSProps[idx].Name := 'text';
FJSProps[idx].setter.native.info := nil;
FJSProps[idx].setter.native.op := TStringsTextWrite;
FJSProps[idx].getter.native.info := nil;
FJSProps[idx].getter.native.op := TStringsTextRead;
end;
end.

View File

@@ -0,0 +1,6 @@
program HelloSpiderMonkey52;
uses
SpiderMonkey;
begin
// TODO: implementation for Delphi
end.

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="10"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="HelloSpiderMonkey52"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="HelloSpiderMonkey52.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="HelloSpiderMonkey52"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);../..;../../.."/>
<Libraries Value="../../mozjs"/>
<OtherUnitFiles Value="../..;../../.."/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Other>
<CustomOptions Value="-dSM52"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,100 @@
program HelloSpiderMonkey52;
{
This example has translated from C++ hello world example taken on
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/How_to_embed_the_JavaScript_engine
}
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes,
SysUtils,
SpiderMonkey;
const
script = '''Hello '' + ''world, it is ''+new Date()';
filename = 'noname';
var
global_ops: JSClassOps = (
addProperty: nil;
delProperty: nil;
getProperty: nil;
setProperty: nil;
enumerate: nil;
resolve: nil;
mayResolve: nil;
finalize: nil;
call: nil;
hasInstance: nil;
construct: nil;
trace: nil;//@JS_GlobalObjectTraceHook;
);
// The class of the global object.
global_class: JSClass = (
name: 'global';
flags: JSCLASS_GLOBAL_FLAGS;
cOps: @global_ops;
);
cx: PJSContext;
options: JS_CompartmentOptions;
global: PJSRootedObject;
val: jsval;
rval: PJSRootedValue;
oldCprt: PJSCompartment;
lineno: Integer = 1;
opts: PJSCompileOptions;
ok: Boolean;
str: PJSString;
I: Integer;
Frames: PPointer;
begin
try
JS_Init();
cx := JSContext.CreateNew(8 * 1024 * 1024);
try
cx^.BeginRequest(); // In practice, you would want to exit this any
try // time you're spinning the event loop
// Scope for our various stack objects (JSAutoRequest, RootedObject), so they all go
// out of scope before we JS_DestroyContext.
global := cx^.NewRootedObject(cx^.NewGlobalObject(@global_class));
if (global = nil) then
Halt(1);
rval := cx^.NewRootedValue(val);
oldCprt := cx^.EnterCompartment(global^.ptr);
try // Scope for JSAutoCompartment
cx^.InitStandardClasses(global^.ptr);
opts := cx^.NewCompileOptions();
opts^.filename := filename;
//opts^.?? := lineno;
ok := cx^.EvaluateScript(opts, script, Length(script), rval^.ptr);
if (not ok) then
Halt(1);
finally
cx^.LeaveCompartment(oldCprt);
end;
str := rval^.ptr.asJSString;
WriteLn(str^.ToAnsi(cx));
finally
cx^.EndRequest();
end;
finally
cx^.Destroy();
JS_ShutDown();
end;
Halt(0);
except
on E: Exception do begin
Writeln(E.Message);
Writeln(BackTraceStrFunc(ExceptAddr));
Frames := ExceptFrames;
for I := 0 to ExceptFrameCount - 1 do
Writeln(BackTraceStrFunc(Frames[I]));
end;
end;
end.

View File

@@ -0,0 +1,23 @@
#------------------------------------------------------------------------------
VERSION = BWS.01
#------------------------------------------------------------------------------
!ifndef ROOT
ROOT = $(MAKEDIR)\..
!endif
#------------------------------------------------------------------------------
MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
DCC = $(ROOT)\bin\dcc32.exe $**
BRCC = $(ROOT)\bin\brcc32.exe $**
#------------------------------------------------------------------------------
PROJECTS = SpiderMonkey45Binding.exe mathModule.dll
#------------------------------------------------------------------------------
default: $(PROJECTS)
#------------------------------------------------------------------------------
SpiderMonkey45Binding.exe: 02 - Bindings\SpiderMonkey45Binding.dpr
$(DCC)
mathModule.dll: 01 - Dll Modules\math-module\src\mathModule.dpr
$(DCC)