├── .gitattributes ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── Dockerfile ├── EdgeJs.sln ├── LICENSE ├── README.md ├── appveyor.yml ├── binding.gyp ├── edge-js.d.ts ├── lib ├── bootstrap │ ├── .gitignore │ ├── Dummy.cs │ └── bootstrap.csproj ├── double_edge.js ├── edge.js └── native │ └── win32 │ ├── ia32 │ ├── 10.14.0 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 11.3.0 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 12.13.0 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 13.0.1 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 14.3.0 │ │ ├── concrt140.dll │ │ ├── edge_coreclr.node │ │ ├── edge_nativeclr.node │ │ ├── msvcp140.dll │ │ ├── vccorlib140.dll │ │ └── vcruntime140.dll │ ├── 6.15.0 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 7.10.1 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 8.14.0 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 9.11.2 │ │ ├── .gitignore │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll │ └── x64 │ ├── 10.14.0 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 11.3.0 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 12.13.0 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 13.0.1 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 14.3.0 │ ├── concrt140.dll │ ├── edge_coreclr.node │ ├── edge_nativeclr.node │ ├── msvcp140.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll │ ├── 6.15.0 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 7.10.1 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 8.14.0 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 9.11.2 │ ├── .gitignore │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll ├── package.json ├── performance ├── .gitignore ├── BookService │ ├── App.config │ ├── BookService.csproj │ ├── BookService.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── compile.sh │ └── packages.config ├── latency.js ├── marshal_clr2v8.js └── performance.cs ├── samples ├── 101_hello_lambda.js ├── 102_hello_function.js ├── 103_hello_file.csx ├── 103_hello_file.js ├── 104_add7_class.js ├── 105_add7_dll.js ├── 106_marshal_v82clr.js ├── 107_marshal_clr2v8.js ├── 108_func.js ├── 108_lambda.js ├── 109_sync.js ├── 110_clr_instance.js ├── 111_clr_listener.js ├── 201_worker.js ├── 202_sql.csx ├── 202_sql.js ├── 203_x509store.js ├── 204_event_log.js ├── 205_soap.csx ├── 205_soap.js ├── 206_registry_read.js ├── 206_registry_write.js ├── 207_unzip.js ├── 207_zip.js ├── 208_convertImage.js ├── 209_websocket.js ├── 210_windows_authentication.js ├── 211_events.js ├── 301_cspyfsps.js ├── edge.png └── readme.txt ├── src ├── CoreCLREmbedding │ ├── coreclrembedding.cpp │ ├── coreclrfunc.cpp │ ├── coreclrfuncinvokecontext.cpp │ ├── coreclrnodejsfunc.cpp │ ├── coreclrnodejsfuncinvokecontext.cpp │ ├── cpprest │ │ └── include │ │ │ ├── asyncrt_utils.h │ │ │ └── json.h │ ├── deps │ │ ├── deps_entry.cpp │ │ ├── deps_entry.h │ │ ├── deps_format.cpp │ │ ├── deps_format.h │ │ ├── deps_resolver.cpp │ │ └── deps_resolver.h │ ├── edge.h │ ├── fxr │ │ ├── fx_muxer.cpp │ │ ├── fx_muxer.h │ │ ├── fx_ver.cpp │ │ └── fx_ver.h │ ├── host │ │ ├── args.cpp │ │ ├── args.h │ │ ├── coreclr.cpp │ │ ├── coreclr.h │ │ ├── error_codes.h │ │ ├── libhost.cpp │ │ ├── libhost.h │ │ ├── runtime_config.cpp │ │ └── runtime_config.h │ ├── json │ │ └── casablanca │ │ │ ├── LICENSE.txt │ │ │ ├── include │ │ │ ├── cpprest │ │ │ │ ├── asyncrt_utils.h │ │ │ │ ├── details │ │ │ │ │ ├── SafeInt3.hpp │ │ │ │ │ ├── basic_types.h │ │ │ │ │ ├── cpprest_compat.h │ │ │ │ │ └── nosal.h │ │ │ │ └── json.h │ │ │ └── stdafx.h │ │ │ └── src │ │ │ ├── json │ │ │ ├── json.cpp │ │ │ ├── json_parsing.cpp │ │ │ └── json_serialization.cpp │ │ │ └── utilities │ │ │ └── asyncrt_utils.cpp │ └── pal │ │ ├── pal.h │ │ ├── pal.unix.cpp │ │ ├── pal.windows.cpp │ │ ├── pal_utils.cpp │ │ ├── pal_utils.h │ │ ├── trace.cpp │ │ └── trace.h ├── common │ ├── callbackhelper.cpp │ ├── clrfuncreflectionwrap.cs │ ├── edge.cpp │ ├── edge_common.h │ ├── utils.cpp │ └── v8synchronizationcontext.cpp ├── dotnet │ ├── clractioncontext.cpp │ ├── clrfunc.cpp │ ├── clrfuncinvokecontext.cpp │ ├── clrfuncreflectionwrap.cpp │ ├── edge.h │ ├── nodejsfunc.cpp │ ├── nodejsfuncinvokecontext.cpp │ ├── persistentdisposecontext.cpp │ └── utils.cpp ├── double │ ├── Edge.js.CSharp │ │ ├── Edge.js.CSharp.csproj │ │ └── EdgeCompiler.cs │ └── Edge.js │ │ ├── Edge.js.csproj │ │ ├── dotnet │ │ └── EdgeJs.cs │ │ └── dotnetcore │ │ ├── coreclrembedding.cs │ │ ├── nodejsfunc.cs │ │ ├── nodejsfuncinvokecontext.cs │ │ └── semversion.cs └── mono │ ├── clractioncontext.cpp │ ├── clrfunc.cpp │ ├── clrfuncinvokecontext.cpp │ ├── clrfuncinvokecontext.cs │ ├── dictionary.cpp │ ├── edge.h │ ├── monoembedding.cpp │ ├── monoembedding.cs │ ├── nodejsfunc.cpp │ ├── nodejsfunc.cs │ ├── nodejsfuncinvokecontext.cpp │ ├── nodejsfuncinvokecontext.cs │ ├── task.cpp │ └── utils.cpp ├── stress └── test.js ├── test ├── 101_edge_func.js ├── 102_node2net.js ├── 103_net2node.js ├── 104_csx.js ├── 105_node2net_sync.js ├── 201_patterns.js ├── 202_serialization.js ├── build.bat ├── build.sh ├── double │ ├── .gitignore │ ├── double_stress │ │ ├── App.config │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── double_stress.csproj │ │ ├── double_stress.sln │ │ └── packages.config │ └── double_test │ │ ├── DoubleEdge.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── double_test.csproj │ │ ├── double_test.sln │ │ └── packages.config ├── hello_class.cs ├── hello_class.csx ├── hello_lambda.csx ├── test.bat ├── test.csproj ├── testall.bat └── tests.cs ├── tools ├── build.bat ├── build_double.bat ├── build_double_new.bat ├── buildall.bat ├── checkplatform.js ├── coverage.js ├── download.cs ├── download.js ├── install.js ├── nuget │ ├── edge.nuspec │ └── tools │ │ └── install.ps1 ├── repl.cs ├── runJsHint.js ├── test.js ├── unzip.cs ├── unzip.vbs └── whereis.js └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | *.lock.json 10 | *.tgz 11 | 12 | publish 13 | .vscode 14 | .idea 15 | .vs 16 | 17 | pids 18 | logs 19 | results 20 | 21 | node_modules 22 | npm-debug.log 23 | build 24 | 25 | bin/ 26 | obj/ 27 | *.user 28 | *.suo 29 | packages/* 30 | _ReSharper* 31 | src/*.sln 32 | src/EdgeJs.vcxproj 33 | 34 | Edge.Tests.* 35 | node.exe 36 | Sample105.* 37 | 38 | .DS_Store 39 | *.sublime-project 40 | *.sublime-workspace 41 | 42 | .cproject 43 | .project 44 | .metadata/ 45 | .settings/ 46 | 47 | adhoc/ 48 | 49 | *cmake* 50 | 51 | package/ 52 | tools/build 53 | 54 | /src/double/Edge.js/obj/ 55 | /src/double/Edge.js/bin/ 56 | /src/double/Edge.js.CSharp/obj/ 57 | /src/double/Edge.js.CSharp/bin/ 58 | /src/double/Edge.js/*.sln 59 | /src/double/Edge.js.CSharp/*.sln 60 | /src/Debug/ 61 | 62 | /test/obj/ 63 | /test/bin/ 64 | /test/Properties/ 65 | /test/test.nuget.cache 66 | 67 | package-lock.json 68 | 69 | tools/nuget/content 70 | tools/nuget/lib 71 | tools/nuget/*.nupkg 72 | tools/nuget/*.zip 73 | tools/*.nupkg 74 | tools/*.zip 75 | 76 | test-results*.* 77 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "_": true, 4 | "after": true, 5 | "async": true, 6 | "afterEach": true, 7 | "afterEach": true, 8 | "Backbone": true, 9 | "before": true, 10 | "beforeEach": true, 11 | "describe": true, 12 | "expect": true, 13 | "iit": true, 14 | "it": true, 15 | "jasmine": true, 16 | "moment": true, 17 | "runs": true, 18 | "sinon": true, 19 | "spyOn": true, 20 | "waits": true, 21 | "waitsFor": true, 22 | "xit": true, 23 | "xdescribe": true 24 | }, 25 | 26 | "options": { 27 | "asi" : false, 28 | "bitwise" : true, 29 | "boss" : false, 30 | "browser" : true, 31 | "curly" : true, 32 | "debug": false, 33 | "devel": false, 34 | "eqeqeq": true, 35 | "evil": false, 36 | "expr": true, 37 | "forin": false, 38 | "immed": true, 39 | "jquery" : true, 40 | "latedef" : false, 41 | "laxbreak": false, 42 | "multistr": true, 43 | "newcap": true, 44 | "noarg": true, 45 | "node" : true, 46 | "noempty": false, 47 | "nonew": true, 48 | "onevar": false, 49 | "plusplus": false, 50 | "regexp": false, 51 | "strict": false, 52 | "sub": false, 53 | "trailing" : true, 54 | "undef": true 55 | } 56 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .gitattributes 2 | appveyor.yml 3 | .travis.yml 4 | Dockerfile 5 | .gitignore 6 | node_modules/ 7 | .vscode 8 | build/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | os: 4 | - osx 5 | 6 | node_js: 7 | - "14.3.0" 8 | - "13.0.1" 9 | - "12.13.0" 10 | - "11.3.0" 11 | - "10.14.0" 12 | 13 | install: 14 | - curl -sSL -k -o osx-net-core.pkg https://download.visualstudio.microsoft.com/download/pr/59a7b78f-4e86-473b-b230-c84d15505cec/766e3e5f35e7bb9677dd785071c5fbf7/dotnet-sdk-2.1.500-osx-x64.pkg 15 | - sudo installer -pkg osx-net-core.pkg -target / 16 | - export PATH=/usr/local/share/dotnet:$PATH 17 | - npm install -q 18 | 19 | script: 20 | - dotnet --version 21 | - EDGE_USE_CORECLR=1 npm test 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | 3 | # update apt-get 4 | RUN apt-get -y update > /dev/null 5 | RUN apt-get -y upgrade > /dev/null 6 | 7 | # install curl, sudo, wget 8 | RUN apt-get install -y curl sudo wget > /dev/null 9 | 10 | RUN mkdir /devvol 11 | VOLUME /devvol 12 | 13 | RUN apt-get -y update > /dev/null 14 | 15 | # install dependencies 16 | RUN apt-get install -y apt-transport-https build-essential libgconf-2-4 python git libglib2.0-dev > /dev/null 17 | 18 | # install node 19 | 20 | RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - 21 | RUN apt-get install -y nodejs > /dev/null 22 | 23 | # install net core 24 | 25 | RUN wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg 26 | RUN sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/ 27 | RUN wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list 28 | RUN sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list 29 | RUN sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg 30 | RUN sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list 31 | 32 | RUN apt-get -y update > /dev/null 33 | RUN apt-get install -y dotnet-sdk-2.1 > /dev/null 34 | 35 | RUN npm i -g node-gyp -------------------------------------------------------------------------------- /EdgeJs.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Edge.js", "src\double\Edge.js\Edge.js.csproj", "{D232E683-ED16-4B7B-BD76-44A9DE96F79E}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{E94194B3-965D-4CC5-8080-C897A9B607E9}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Edge.js.CSharp", "src\double\Edge.js.CSharp\Edge.js.CSharp.csproj", "{18C88EB2-F3C0-463A-A07B-6CA3570C7FAD}" 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bootstrap", "lib\bootstrap\bootstrap.csproj", "{9AF3DB99-E51A-463F-896A-A9F6123C6999}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Any CPU = Debug|Any CPU 14 | Release|Any CPU = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Release|Any CPU.Build.0 = Release|Any CPU 21 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {18C88EB2-F3C0-463A-A07B-6CA3570C7FAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {18C88EB2-F3C0-463A-A07B-6CA3570C7FAD}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {18C88EB2-F3C0-463A-A07B-6CA3570C7FAD}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {18C88EB2-F3C0-463A-A07B-6CA3570C7FAD}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Release|Any CPU.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: 2 | - Visual Studio 2015 3 | - Ubuntu 4 | 5 | environment: 6 | matrix: 7 | # node.js 8 | - nodejs: "14" 9 | - nodejs: "13" 10 | - nodejs: "12" 11 | - nodejs: "11" 12 | - nodejs: "10" 13 | 14 | install: 15 | - cmd: powershell Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs) x64 16 | - sh: sudo apt-get -qq update 17 | - sh: sudo apt-get -y -qq install build-essential libgconf-2-4 python libglib2.0-dev 18 | - sh: nvm install $nodejs 19 | - node -p "[process.version,process.arch].join(' ')" 20 | - dotnet --version 21 | - npm install -q 22 | - cmd: npm i -q xunit-viewer >nul 23 | - sh: npm i xunit-viewer --silent &> /dev/null 24 | 25 | test_script: 26 | 27 | - cmd: npm test 28 | - cmd: node tools/coverage.js 29 | - cmd: SET EDGE_USE_CORECLR=1 & npm test 30 | - cmd: SET EDGE_USE_CORECLR=1 & node tools/coverage.js 31 | - sh: EDGE_USE_CORECLR=1 npm test 32 | - sh: EDGE_USE_CORECLR=1 node tools/coverage.js 33 | 34 | after_test: 35 | - ps: | 36 | $url = "https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)" 37 | $file = '.\test-results.xml' 38 | (New-Object 'System.Net.WebClient').UploadFile($url, (Resolve-Path '.\test-results.xml')) 39 | Push-AppveyorArtifact (Resolve-Path '.\test-results.xml') 40 | Push-AppveyorArtifact (Resolve-Path '.\test-results-xunit-viewer.xml') 41 | Push-AppveyorArtifact (Resolve-Path '.\test-results-xunit-viewer.html') 42 | 43 | skip_commits: 44 | files: 45 | - samples/* 46 | - stress/* 47 | - performance/* 48 | - '**/*.md' 49 | - '**/*.d.ts' 50 | - '**/*.bat' 51 | - '.travis.yml' 52 | - 'Dockerfile' 53 | 54 | build: off -------------------------------------------------------------------------------- /edge-js.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@neo-one/edge' { 2 | function func(params: string | Function | Params | Source | TSQL): Func 3 | function func(language: string, params: string | Function | Params | Source | TSQL): Func 4 | interface Params { 5 | assemblyFile: string 6 | typeName?: string 7 | methodName?: string 8 | } 9 | 10 | interface Source { 11 | source: string | Function 12 | references?: string[] 13 | } 14 | 15 | interface TSQL { 16 | source: string 17 | connectionString?: string 18 | commandTimeout?: number 19 | } 20 | 21 | interface Func { 22 | (payload: TInput, callback: (error: Error, result: TOutput) => void): void; 23 | (payload: TInput, sync: true): TOutput; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/bootstrap/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ -------------------------------------------------------------------------------- /lib/bootstrap/Dummy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class Dummy 4 | { 5 | } -------------------------------------------------------------------------------- /lib/bootstrap/bootstrap.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net5.0 5 | true 6 | bootstrap 7 | bootstrap 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lib/double_edge.js: -------------------------------------------------------------------------------- 1 | // Fix #176 for GUI applications on Windows 2 | try { 3 | var stdout = process.stdout; 4 | } 5 | catch (e) { 6 | // This is a Windows GUI application without stdout and stderr defined. 7 | // Define process.stdout and process.stderr so that all output is discarded. 8 | (function () { 9 | var stream = require('stream'); 10 | var NullStream = function (o) { 11 | stream.Writable.call(this); 12 | this._write = function (c, e, cb) { cb && cb(); }; 13 | } 14 | require('util').inherits(NullStream, stream.Writable); 15 | var nullStream = new NullStream(); 16 | process.__defineGetter__('stdout', function () { return nullStream; }); 17 | process.__defineGetter__('stderr', function () { return nullStream; }); 18 | })(); 19 | } 20 | 21 | process.env['EDGE_NATIVE'] = process.env['EDGE_NATIVE'] || 22 | __dirname + (process.arch === 'x64' ? '\\x64\\edge_nativeclr.node' : '\\x86\\edge_nativeclr.node'); 23 | 24 | var edge = require('./edge.js'); 25 | 26 | 27 | var assemblyFile = __dirname + '\\..\\EdgeJs.dll'; 28 | const edgeSwitch = "-EdgeJs:"; 29 | process.argv.forEach(e => { 30 | if(e.startsWith(edgeSwitch)) { 31 | const path = e.substring(edgeSwitch.length); 32 | assemblyFile = path; 33 | } 34 | }) 35 | 36 | var initialize = edge.func({ 37 | assemblyFile, 38 | typeName: 'EdgeJs.Edge', 39 | methodName: 'InitializeInternal' 40 | }); 41 | 42 | var compileFunc = function (data, callback) { 43 | var wrapper = '(function () { ' + data + ' })'; 44 | var funcFactory = eval(wrapper); 45 | var func = funcFactory(); 46 | if (typeof func !== 'function') { 47 | throw new Error('Node.js code must return an instance of a JavaScript function. ' 48 | + 'Please use `return` statement to return a function.'); 49 | } 50 | 51 | callback(null, func); 52 | }; 53 | 54 | initialize(compileFunc, function (error, data) { 55 | if (error) throw error; 56 | }); 57 | 58 | // prevent the V8 thread from exiting for the lifetime of the CLR application 59 | setInterval(function () {}, 3600000); 60 | -------------------------------------------------------------------------------- /lib/native/win32/ia32/10.14.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/10.14.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/10.14.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/10.14.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/10.14.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/11.3.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/11.3.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/11.3.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/11.3.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/11.3.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/12.13.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/12.13.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/12.13.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/12.13.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/12.13.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/13.0.1/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/13.0.1/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/13.0.1/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/13.0.1/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/13.0.1/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/14.3.0/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/14.3.0/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/14.3.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/14.3.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/14.3.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/14.3.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/14.3.0/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/14.3.0/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/14.3.0/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/14.3.0/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/14.3.0/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/14.3.0/vcruntime140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/6.15.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/6.15.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/6.15.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/6.15.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/6.15.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/7.10.1/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/7.10.1/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/7.10.1/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/7.10.1/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/7.10.1/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/8.14.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/8.14.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/8.14.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/8.14.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/8.14.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/9.11.2/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/9.11.2/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/9.11.2/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/9.11.2/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/9.11.2/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/ia32/vcruntime140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/10.14.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/10.14.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/10.14.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/10.14.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/10.14.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/11.3.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/11.3.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/11.3.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/11.3.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/11.3.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/12.13.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/12.13.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/12.13.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/12.13.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/12.13.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/13.0.1/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/13.0.1/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/13.0.1/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/13.0.1/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/13.0.1/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/14.3.0/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/14.3.0/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/14.3.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/14.3.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/14.3.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/14.3.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/14.3.0/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/14.3.0/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/14.3.0/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/14.3.0/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/14.3.0/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/14.3.0/vcruntime140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/6.15.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/6.15.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/6.15.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/6.15.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/6.15.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/7.10.1/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/7.10.1/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/7.10.1/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/7.10.1/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/7.10.1/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/8.14.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/8.14.0/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/8.14.0/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/8.14.0/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/8.14.0/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/9.11.2/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/9.11.2/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/9.11.2/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/9.11.2/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/9.11.2/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/lib/native/win32/x64/vcruntime140.dll -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo-one/edge", 3 | "author": "Spencer Corwin ", 4 | "version": "16.0.4", 5 | "description": "Edge.js: run .NET and Node.js in-process on Windows, Mac OS, and Linux", 6 | "tags": [ 7 | "owin", 8 | "edge", 9 | "net", 10 | "clr", 11 | "coreclr", 12 | "c#", 13 | "mono", 14 | "managed", 15 | ".net" 16 | ], 17 | "keywords": [ 18 | "owin", 19 | "edge", 20 | "net", 21 | "clr", 22 | "coreclr", 23 | "c#", 24 | "mono", 25 | "managed", 26 | ".net" 27 | ], 28 | "main": "./lib/edge.js", 29 | "types": "edge-js.d.ts", 30 | "engines": { 31 | "node": ">= 6" 32 | }, 33 | "license": "Apache-2.0", 34 | "dependencies": { 35 | "edge-cs": "1.2.1", 36 | "nan": "^2.14.0" 37 | }, 38 | "devDependencies": { 39 | "junit-report-merger": "0.0.6", 40 | "mocha": "5.1.1", 41 | "mocha-junit-reporter": "^1.17.0" 42 | }, 43 | "homepage": "https://github.com/neo-one-suite/edge", 44 | "repository": { 45 | "type": "git", 46 | "url": "git@github.com:neo-one-suite/edge.git" 47 | }, 48 | "bugs": { 49 | "url": "http://github.com/neo-one-suite/edge/issues" 50 | }, 51 | "scripts": { 52 | "install": "node tools/install.js", 53 | "test": "node tools/test.js" 54 | } 55 | } -------------------------------------------------------------------------------- /performance/.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | BookService/packages/ -------------------------------------------------------------------------------- /performance/BookService/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /performance/BookService/BookService.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {860AE049-3944-4CAB-A087-1CDEAEEFCC14} 8 | Exe 9 | Properties 10 | BookService 11 | BookService 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | packages\Newtonsoft.Json.5.0.5\lib\net45\Newtonsoft.Json.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /performance/BookService/BookService.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookService", "BookService.csproj", "{860AE049-3944-4CAB-A087-1CDEAEEFCC14}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {860AE049-3944-4CAB-A087-1CDEAEEFCC14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {860AE049-3944-4CAB-A087-1CDEAEEFCC14}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {860AE049-3944-4CAB-A087-1CDEAEEFCC14}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {860AE049-3944-4CAB-A087-1CDEAEEFCC14}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /performance/BookService/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | using System.Net.Http.Headers; 4 | using System.ServiceModel; 5 | using System.Web.Http; 6 | using System.Web.Http.SelfHost; 7 | 8 | namespace BookService 9 | { 10 | public class Book 11 | { 12 | public string title = "Run .NET and node.js in-process with edge.js"; 13 | public object author = new { first = "Tomasz", last = "Janczuk" }; 14 | public int year = 2013; 15 | public double price = 24.99; 16 | public bool available = true; 17 | public string description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus posuere tincidunt felis, et mattis mauris ultrices quis. Cras molestie, quam varius tincidunt tincidunt, mi magna imperdiet lacus, quis elementum ante nibh quis orci. In posuere erat sed tellus lacinia luctus. Praesent sodales tellus mauris, et egestas justo. In blandit, metus non congue adipiscing, est orci luctus odio, non sagittis erat orci ac sapien. Proin ut est id enim mattis volutpat. Vivamus ultrices dapibus feugiat. In dictum tincidunt eros, non pretium nisi rhoncus in. Duis a lacus et elit feugiat ullamcorper. Mauris tempor turpis nulla. Nullam nec facilisis elit."; 18 | public byte[] picture = new byte[16000]; 19 | public object[] tags = new object[] { ".NET", "node.js", "CLR", "V8", "interop" }; 20 | } 21 | 22 | public class BookController : ApiController 23 | { 24 | static readonly Uri baseAddress = new Uri("http://localhost:31415/"); 25 | 26 | public Book Get() 27 | { 28 | return new Book(); 29 | } 30 | 31 | static void Main(string[] args) 32 | { 33 | HttpSelfHostServer server = null; 34 | try 35 | { 36 | HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress); 37 | config.HostNameComparisonMode = HostNameComparisonMode.Exact; 38 | 39 | // Register default route 40 | config.Routes.MapHttpRoute( 41 | name: "DefaultApi", 42 | routeTemplate: "api/{controller}" 43 | ); 44 | 45 | server = new HttpSelfHostServer(config); 46 | server.OpenAsync().Wait(); 47 | Console.WriteLine("Listening on " + baseAddress); 48 | Console.WriteLine("Hit ENTER to exit..."); 49 | Console.ReadLine(); 50 | } 51 | catch (Exception e) 52 | { 53 | Console.WriteLine("Could not start server: {0}", e.GetBaseException().Message); 54 | Console.WriteLine("Hit ENTER to exit..."); 55 | Console.ReadLine(); 56 | } 57 | finally 58 | { 59 | if (server != null) 60 | { 61 | server.CloseAsync().Wait(); 62 | } 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /performance/BookService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BookService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("BookService")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("00b715fc-f588-4964-8edc-6d9665df29b6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /performance/BookService/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mcs -sdk:4.5 Program.cs /r:System.Net.Http.dll /r:System.ServiceModel.dll /r:System.Web.Http.dll /r:System.Web.Http.SelfHost.dll 3 | -------------------------------------------------------------------------------- /performance/BookService/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /performance/latency.js: -------------------------------------------------------------------------------- 1 | function help() { 2 | console.log('Usage: node latency.js i|x '); 3 | console.log(' i - 1 compilation, in-process loop of N calls'); 4 | console.log(' c - in-process loop of N compilations and calls'); 5 | console.log(' x - child process loop of N iterations'); 6 | console.log('e.g. node latency.js i 1000'); 7 | process.exit(1); 8 | } 9 | 10 | if (process.argv.length !== 4) 11 | help(); 12 | 13 | if (isNaN(process.argv[3])) 14 | help(); 15 | 16 | var N = +process.argv[3]; 17 | 18 | if (N < 1) 19 | help(); 20 | 21 | if (process.argv[2] === 'i') { 22 | var func = require('../lib/edge').func(function () {/* 23 | async (input) => { 24 | return ".NET welcomes " + input.ToString(); 25 | } 26 | */}); 27 | var M = N; 28 | var start = Date.now(); 29 | one_i(); 30 | function one_i() { 31 | func('Node.js', function (error, result) { 32 | if (error) throw error; 33 | if (--M <= 0) { 34 | var delta = Date.now() - start; 35 | console.log(delta, delta / N); 36 | } 37 | else 38 | setImmediate(one_i); 39 | }); 40 | } 41 | }else if (process.argv[2] === 'c') { 42 | var csharp = 'async (input) => { return ".NET welcomes " + input.ToString(); } /*'; 43 | 44 | var edge = require('../lib/edge'); 45 | var M = N; 46 | var start = Date.now(); 47 | one_c(); 48 | function one_c() { 49 | var code = csharp + M + '*/'; // force cache miss and recompile 50 | var func = edge.func(code); 51 | func('Node.js', function (error, result) { 52 | if (error) throw error; 53 | if (--M <= 0) { 54 | var delta = Date.now() - start; 55 | console.log(delta, delta / N); 56 | } 57 | else 58 | setImmediate(one_c); 59 | }); 60 | } 61 | } 62 | else if (process.argv[2] === 'x') { 63 | var child_process = require('child_process'); 64 | var cmd = [process.argv[0], process.argv[1], 'i', '1'].join(' '); 65 | var M = N; 66 | var start = Date.now(); 67 | one_x(); 68 | function one_x() { 69 | child_process.exec(cmd, function (error) { 70 | if (error) throw error; 71 | if (--M <= 0) { 72 | var delta = Date.now() - start; 73 | console.log(delta, delta / N); 74 | } 75 | else 76 | setImmediate(one_x); 77 | }); 78 | } 79 | } 80 | else 81 | help(); 82 | -------------------------------------------------------------------------------- /performance/marshal_clr2v8.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var callCount = process.env.EDGE_CALL_COUNT || 10000; 4 | var edgePerformanceDll = path.join(__dirname, 'Edge.Performance.dll'); 5 | 6 | var measure = function (func) { 7 | var start = Date.now(); 8 | var i = 0; 9 | 10 | function one() { 11 | func({ 12 | title: 'Run .NET and node.js in-process with edge.js', 13 | author: { 14 | first: 'Tomasz', 15 | last: 'Janczuk' 16 | }, 17 | year: 2013, 18 | price: 24.99, 19 | available: true, 20 | description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus posuere tincidunt felis, et mattis mauris ultrices quis. Cras molestie, quam varius tincidunt tincidunt, mi magna imperdiet lacus, quis elementum ante nibh quis orci. In posuere erat sed tellus lacinia luctus. Praesent sodales tellus mauris, et egestas justo. In blandit, metus non congue adipiscing, est orci luctus odio, non sagittis erat orci ac sapien. Proin ut est id enim mattis volutpat. Vivamus ultrices dapibus feugiat. In dictum tincidunt eros, non pretium nisi rhoncus in. Duis a lacus et elit feugiat ullamcorper. Mauris tempor turpis nulla. Nullam nec facilisis elit.', 21 | picture: new Buffer(16000), 22 | tags: [ '.NET', 'node.js', 'CLR', 'V8', 'interop'] 23 | }, function (error, callbck) { 24 | if (error) throw error; 25 | if (++i < callCount) setImmediate(one); 26 | else finish(); 27 | }); 28 | } 29 | 30 | function finish() { 31 | var delta = Date.now() - start; 32 | var result = process.memoryUsage(); 33 | result.latency = delta / callCount; 34 | console.log(result); 35 | } 36 | 37 | one(); 38 | }; 39 | 40 | var baseline = function () { 41 | measure(function (input, callback) { 42 | var book = { 43 | title: 'Run .NET and node.js in-process with edge.js', 44 | author: { 45 | first: 'Tomasz', 46 | last: 'Janczuk' 47 | }, 48 | year: 2013, 49 | price: 24.99, 50 | available: true, 51 | description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus posuere tincidunt felis, et mattis mauris ultrices quis. Cras molestie, quam varius tincidunt tincidunt, mi magna imperdiet lacus, quis elementum ante nibh quis orci. In posuere erat sed tellus lacinia luctus. Praesent sodales tellus mauris, et egestas justo. In blandit, metus non congue adipiscing, est orci luctus odio, non sagittis erat orci ac sapien. Proin ut est id enim mattis volutpat. Vivamus ultrices dapibus feugiat. In dictum tincidunt eros, non pretium nisi rhoncus in. Duis a lacus et elit feugiat ullamcorper. Mauris tempor turpis nulla. Nullam nec facilisis elit.', 52 | picture: new Buffer(16000), 53 | tags: [ '.NET', 'node.js', 'CLR', 'V8', 'interop'] 54 | } 55 | callback(null, book); 56 | }); 57 | }; 58 | 59 | var clr2v8 = function () { 60 | measure(require('../lib/edge').func({ 61 | assemblyFile: edgePerformanceDll, 62 | methodName: 'Invoke' 63 | })); 64 | }; 65 | 66 | var crossProcess = function () { 67 | var http = require('http'); 68 | measure(function (input, callback) { 69 | http.get("http://localhost:31415/api/book", function(res) { 70 | if (res.statusCode !== 200) { 71 | return callback(new Error('Status code: ' + res.statusCode)); 72 | } 73 | 74 | var body = ''; 75 | res.on('data', function (chunk) { body += chunk; }); 76 | res.on('end', function () { 77 | callback(null, JSON.parse(body)); 78 | }) 79 | }).on('error', callback); 80 | }); 81 | }; 82 | 83 | var cases = { 84 | js: baseline, 85 | edge: clr2v8, 86 | xproc: crossProcess 87 | }; 88 | 89 | if (!cases[process.argv[2]]) { 90 | console.log('Usage: marshal_clr2v8.js ' + Object.getOwnPropertyNames(cases).join('|')); 91 | process.exit(1); 92 | } 93 | else { 94 | cases[process.argv[2]](); 95 | } 96 | -------------------------------------------------------------------------------- /performance/performance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Dynamic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | #pragma warning disable 1998 8 | 9 | namespace Edge.Performance 10 | { 11 | public class Startup 12 | { 13 | public async Task Invoke(dynamic input) 14 | { 15 | var book = new 16 | { 17 | title = "Run .NET and node.js in-process with edge.js", 18 | author = new { 19 | first = "Tomasz", 20 | last = "Janczuk" 21 | }, 22 | year = 2013, 23 | price = 24.99, 24 | available = true, 25 | description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus posuere tincidunt felis, et mattis mauris ultrices quis. Cras molestie, quam varius tincidunt tincidunt, mi magna imperdiet lacus, quis elementum ante nibh quis orci. In posuere erat sed tellus lacinia luctus. Praesent sodales tellus mauris, et egestas justo. In blandit, metus non congue adipiscing, est orci luctus odio, non sagittis erat orci ac sapien. Proin ut est id enim mattis volutpat. Vivamus ultrices dapibus feugiat. In dictum tincidunt eros, non pretium nisi rhoncus in. Duis a lacus et elit feugiat ullamcorper. Mauris tempor turpis nulla. Nullam nec facilisis elit.", 26 | picture = new byte[16000], 27 | tags = new object[] { ".NET", "node.js", "CLR", "V8", "interop" } 28 | }; 29 | 30 | return book; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /samples/101_hello_lambda.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func('async (input) => { return ".NET welcomes " + input.ToString(); }'); 6 | 7 | hello('Node.js', function (error, result) { 8 | if (error) throw error; 9 | console.log(result); 10 | }); -------------------------------------------------------------------------------- /samples/102_hello_function.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func(function () {/* 6 | async (input) => 7 | { 8 | return ".NET welcomes " + input.ToString(); 9 | } 10 | */}); 11 | 12 | hello('Node.js', function (error, result) { 13 | if (error) throw error; 14 | console.log(result); 15 | }); -------------------------------------------------------------------------------- /samples/103_hello_file.csx: -------------------------------------------------------------------------------- 1 | async (input) => 2 | { 3 | return ".NET welcomes " + input.ToString(); 4 | } -------------------------------------------------------------------------------- /samples/103_hello_file.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func('103_hello_file.csx'); 6 | 7 | hello('Node.js', function (error, result) { 8 | if (error) throw error; 9 | console.log(result); 10 | }); -------------------------------------------------------------------------------- /samples/104_add7_class.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var add7 = edge.func(function () {/* 6 | using System.Threading.Tasks; 7 | 8 | public class Startup 9 | { 10 | public async Task Invoke(object input) 11 | { 12 | return this.Add7((int)input); 13 | } 14 | 15 | int Add7(int v) 16 | { 17 | return Helper.Add7(v); 18 | } 19 | } 20 | 21 | static class Helper 22 | { 23 | public static int Add7(int v) 24 | { 25 | return v + 7; 26 | } 27 | } 28 | */}); 29 | 30 | add7(12, function (error, result) { 31 | if (error) throw error; 32 | console.log(result); 33 | }); -------------------------------------------------------------------------------- /samples/105_add7_dll.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | // Compile Sample105.dll with 4 | // - on Windows (.NET Framework): 5 | // csc.exe /target:library /debug Sample105.cs 6 | // - on MacOS/Linux (Mono): 7 | // mcs -sdk:4.5 Sample105.cs -target:library 8 | 9 | var edge = require('../lib/edge'); 10 | 11 | var add7 = edge.func('Sample105.dll'); 12 | 13 | add7(12, function (error, result) { 14 | if (error) throw error; 15 | console.log(result); 16 | }); -------------------------------------------------------------------------------- /samples/106_marshal_v82clr.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func(function () {/* 6 | using System.Collections.Generic; 7 | 8 | async (data) => 9 | { 10 | Console.WriteLine("-----> In .NET:"); 11 | foreach (var kv in (IDictionary)data) 12 | { 13 | Console.WriteLine(kv.Key + ": " + kv.Value.GetType()); 14 | } 15 | 16 | return null; 17 | } 18 | */}); 19 | 20 | var payload = { 21 | anInteger: 1, 22 | aNumber: 3.1415, 23 | aString: 'foobar', 24 | aBool: true, 25 | anObject: {}, 26 | anArray: [ 'a', 1, true ], 27 | aBuffer: new Buffer(1024) 28 | } 29 | 30 | console.log('-----> In node.js:'); 31 | console.log(payload); 32 | 33 | hello(payload, function (error, result) { 34 | if (error) throw error; 35 | }); 36 | -------------------------------------------------------------------------------- /samples/107_marshal_clr2v8.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func(function () {/* 6 | async (input) => 7 | { 8 | var result = new { 9 | anInteger = 1, 10 | aNumber = 3.1415, 11 | aString = "foobar", 12 | aBool = true, 13 | anObject = new { a = "b", c = 12 }, 14 | anArray = new object[] { "a", 1, true }, 15 | aBuffer = new byte[1024] 16 | }; 17 | 18 | return result; 19 | } 20 | */}); 21 | 22 | hello(null, function (error, result) { 23 | if (error) throw error; 24 | console.log('-----> In node.js:'); 25 | console.log(result); 26 | }); 27 | -------------------------------------------------------------------------------- /samples/108_func.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var addAndMultiplyBy2 = edge.func(function () {/* 6 | using System.Collections.Generic; 7 | 8 | async (dynamic data) => 9 | { 10 | int sum = (int)data.a + (int)data.b; 11 | var multiplyBy2 = (Func>)data.multiplyBy2; 12 | return await multiplyBy2(sum); 13 | } 14 | */}); 15 | 16 | var payload = { 17 | a: 2, 18 | b: 3, 19 | multiplyBy2: function(input, callback) { 20 | callback(null, input * 2); 21 | } 22 | }; 23 | 24 | addAndMultiplyBy2(payload, function (error, result) { 25 | if (error) throw error; 26 | console.log(result); 27 | }); 28 | -------------------------------------------------------------------------------- /samples/108_lambda.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var createCounter = edge.func(function () {/* 6 | async (start) => 7 | { 8 | var k = (int)start; 9 | return (Func>)( 10 | async (i) => 11 | { 12 | return k++; 13 | } 14 | ); 15 | } 16 | */}); 17 | 18 | var nextNumber = createCounter(12, true); 19 | console.log(nextNumber(null, true)); 20 | console.log(nextNumber(null, true)); 21 | console.log(nextNumber(null, true)); 22 | -------------------------------------------------------------------------------- /samples/109_sync.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func('async (input) => { return ".NET welcomes " + input.ToString(); }'); 6 | 7 | // call the function synchronously 8 | var result = hello('Node.js', true); 9 | console.log(result); 10 | 11 | // call the same function asynchronously 12 | hello('JavaScript', function (error, result) { 13 | if (error) throw error; 14 | console.log(result); 15 | }); 16 | -------------------------------------------------------------------------------- /samples/110_clr_instance.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var createPerson = edge.func(function () {/* 6 | using System; 7 | using System.Threading.Tasks; 8 | 9 | public class Startup 10 | { 11 | public async Task Invoke(int startingSalary) 12 | { 13 | var person = new Person(startingSalary); 14 | return new { 15 | getSalary = (Func>)( 16 | async (i) => 17 | { 18 | return person.Salary; 19 | } 20 | ), 21 | giveRaise = (Func>)( 22 | async (amount) => 23 | { 24 | person.GiveRaise((int)amount); 25 | return person.Salary; 26 | } 27 | ) 28 | }; 29 | } 30 | } 31 | 32 | public class Person 33 | { 34 | public int Salary { get; private set; } 35 | 36 | public Person(int startingSalary) 37 | { 38 | this.Salary = startingSalary; 39 | } 40 | 41 | public void GiveRaise(int amount) 42 | { 43 | this.Salary += amount; 44 | } 45 | } 46 | */}); 47 | 48 | var person = createPerson(120, true); 49 | console.log(person.getSalary(null, true)); 50 | console.log(person.giveRaise(20, true)); 51 | console.log(person.getSalary(null, true)); 52 | -------------------------------------------------------------------------------- /samples/111_clr_listener.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var createController = edge.func(function () {/* 6 | using System; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | public class Startup 11 | { 12 | static TaskCompletionSource tcs; 13 | 14 | public async Task Invoke(object input) 15 | { 16 | return new { 17 | yieldControl = (Func>)((i) => { 18 | return Startup.AcquireControl(); 19 | }), 20 | regainControl = (Func>)(async (i) => { 21 | Startup.ReleaseControl(); 22 | return null; 23 | }) 24 | }; 25 | } 26 | 27 | static Task AcquireControl() 28 | { 29 | // single threaded; always called on V8 thread 30 | 31 | if (tcs != null) 32 | { 33 | throw new InvalidOperationException("CLR already controls the lifetime of the process."); 34 | } 35 | 36 | TaskCompletionSource tmp = new TaskCompletionSource(); 37 | tcs = tmp; 38 | return tmp.Task; 39 | } 40 | 41 | public static void ReleaseControl() 42 | { 43 | // multi-threaded; can be called from V8 or one of many CLR threads 44 | 45 | TaskCompletionSource tmp = Interlocked.Exchange(ref tcs, null); 46 | if (tmp != null) 47 | { 48 | tmp.SetResult(null); 49 | } 50 | } 51 | } 52 | */}); 53 | 54 | // yield control over process lifetime to CLR 55 | var controller = createController(null, true); 56 | controller.yieldControl(); 57 | console.log('Control over process lifetime yielded to CLR, the process will not exit...'); 58 | 59 | // at this point, the process will not exit until one of the following happens: 60 | // - node.js calls controller.regainControl(), or 61 | // - CLR calls Startup.ReleaseControl() 62 | 63 | // controller.regainControl(); -------------------------------------------------------------------------------- /samples/201_worker.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var hello = edge.func(function () {/* 6 | async (input) => 7 | { 8 | // we are on V8 thread here 9 | 10 | return await Task.Run(async () => { 11 | 12 | // we are on CLR thread pool thread here 13 | 14 | // simulate long running operation 15 | await Task.Delay(5000); 16 | 17 | return ".NET welcomes " + input.ToString(); 18 | }); 19 | } 20 | */}); 21 | 22 | console.log('Starting CPU bound operation...'); 23 | hello('Node.js', function (error, result) { 24 | if (error) throw error; 25 | console.log(result); 26 | }); 27 | 28 | setInterval(function() { 29 | console.log('Node.js event loop is alive'); 30 | }, 1000); 31 | -------------------------------------------------------------------------------- /samples/202_sql.csx: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | //#r "System.dll" 4 | //#r "System.Data.dll" 5 | //#r "System.Web.Extensions.dll" 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Data; 10 | using System.Data.SqlClient; 11 | using System.IO; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using System.Web.Script.Serialization; 15 | 16 | public class Startup 17 | { 18 | public async Task Invoke(string command) 19 | { 20 | string connectionString = Environment.GetEnvironmentVariable("OWIN_SQL_CONNECTION_STRING"); 21 | 22 | if (command.StartsWith("select ", StringComparison.InvariantCultureIgnoreCase)) 23 | { 24 | return await this.ExecuteQuery(connectionString, command); 25 | } 26 | else if (command.StartsWith("insert ", StringComparison.InvariantCultureIgnoreCase) 27 | || command.StartsWith("update ", StringComparison.InvariantCultureIgnoreCase) 28 | || command.StartsWith("delete ", StringComparison.InvariantCultureIgnoreCase)) 29 | { 30 | return await this.ExecuteNonQuery(connectionString, command); 31 | } 32 | else 33 | { 34 | throw new InvalidOperationException("Unsupported type of SQL command. Only select, insert, update, and delete are supported."); 35 | } 36 | } 37 | 38 | async Task ExecuteQuery(string connectionString, string commandString) 39 | { 40 | List rows = new List(); 41 | 42 | using (SqlConnection connection = new SqlConnection(connectionString)) 43 | { 44 | using (SqlCommand command = new SqlCommand(commandString, connection)) 45 | { 46 | await connection.OpenAsync(); 47 | using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection)) 48 | { 49 | object[] fieldNames = new object[reader.FieldCount]; 50 | for (int i = 0; i < reader.FieldCount; i++) 51 | { 52 | fieldNames[i] = reader.GetName(i); 53 | } 54 | rows.Add(fieldNames); 55 | 56 | IDataRecord record = (IDataRecord)reader; 57 | while (await reader.ReadAsync()) 58 | { 59 | object[] resultRecord = new object[record.FieldCount]; 60 | record.GetValues(resultRecord); 61 | for (int i = 0; i < record.FieldCount; i++) 62 | { 63 | Type type = record.GetFieldType(i); 64 | if (type == typeof(byte[]) || type == typeof(char[])) 65 | { 66 | resultRecord[i] = Convert.ToBase64String((byte[])resultRecord[i]); 67 | } 68 | else if (type == typeof(Guid) || type == typeof(DateTime)) 69 | { 70 | resultRecord[i] = resultRecord[i].ToString(); 71 | } 72 | else if (type == typeof(IDataReader)) 73 | { 74 | resultRecord[i] = ""; 75 | } 76 | } 77 | 78 | rows.Add(resultRecord); 79 | } 80 | } 81 | } 82 | } 83 | 84 | return rows; 85 | } 86 | 87 | async Task ExecuteNonQuery(string connectionString, string commandString) 88 | { 89 | using (SqlConnection connection = new SqlConnection(connectionString)) 90 | { 91 | using (SqlCommand command = new SqlCommand(commandString, connection)) 92 | { 93 | await connection.OpenAsync(); 94 | return await command.ExecuteNonQueryAsync(); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /samples/202_sql.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var sql = edge.func('202_sql.csx'); 6 | 7 | sql('select top 2 * from Products', function (error, result) { 8 | if (error) throw error; 9 | console.log(result); 10 | }); 11 | -------------------------------------------------------------------------------- /samples/203_x509store.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var listCertificates = edge.func(function() {/* 6 | #r "System.dll" 7 | 8 | using System.Collections.Generic; 9 | using System.Security.Cryptography.X509Certificates; 10 | 11 | async (dynamic data) => 12 | { 13 | X509Store store = new X509Store( 14 | (string)data.storeName, 15 | (StoreLocation)Enum.Parse(typeof(StoreLocation), (string)data.storeLocation)); 16 | store.Open(OpenFlags.ReadOnly); 17 | try 18 | { 19 | List result = new List(); 20 | foreach (X509Certificate2 certificate in store.Certificates) 21 | { 22 | result.Add(certificate.Subject); 23 | } 24 | 25 | return result; 26 | } 27 | finally 28 | { 29 | store.Close(); 30 | } 31 | } 32 | */}); 33 | 34 | var result = listCertificates({ storeName: 'My', storeLocation: 'LocalMachine' }, true); 35 | console.log(result); 36 | -------------------------------------------------------------------------------- /samples/204_event_log.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var writeEventLog = edge.func(function() {/* 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | 9 | async (dynamic parameters) => 10 | { 11 | var source = (string)parameters.source; 12 | var log = (string)parameters.log; 13 | if (!EventLog.SourceExists(source)) 14 | { 15 | EventLog.CreateEventSource(source, log); 16 | } 17 | 18 | EventLog.WriteEntry( 19 | source, 20 | (string)parameters.message, 21 | (EventLogEntryType)Enum.Parse( 22 | typeof(EventLogEntryType), (string)parameters.type), 23 | (int)parameters.id 24 | ); 25 | 26 | return null; 27 | } 28 | */}); 29 | 30 | writeEventLog({ 31 | source: 'Edge.js sample application', 32 | log: 'Application', 33 | type: 'Information', 34 | message: 'Hello from node.js. The time is ' + new Date(), 35 | id: 31415 36 | }, true); 37 | 38 | console.log('Success. Check EventViewer.'); 39 | -------------------------------------------------------------------------------- /samples/205_soap.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var convertKilograms = edge.func('205_soap.csx'); 6 | 7 | convertKilograms(123, function (error, result) { 8 | if (error) throw error; 9 | console.log(result); 10 | }); 11 | -------------------------------------------------------------------------------- /samples/206_registry_read.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge'); 2 | 3 | var readRegistery = edge.func(function () {/* 4 | using Microsoft.Win32; 5 | 6 | async (dynamic input) => 7 | { 8 | return Registry.GetValue((string) input.keyName, (string) input.valueName, null); 9 | } 10 | */}); 11 | 12 | readRegistery({ 13 | keyName: 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\4.0', 14 | valueName: 'MSBuildOverrideTasksPath' 15 | }, function (err, result) { 16 | if (err) { 17 | throw err; 18 | } 19 | 20 | console.log(result); 21 | }); -------------------------------------------------------------------------------- /samples/206_registry_write.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge'); 2 | 3 | var writeRegistery = edge.func(function () {/* 4 | using Microsoft.Win32; 5 | 6 | async (dynamic input) => 7 | { 8 | Registry.SetValue((string)input.keyName, (string)input.valueName, input.value); 9 | return null; 10 | } 11 | */}); 12 | 13 | writeRegistery({ 14 | keyName: 'HKEY_CURRENT_USER\\Environment', 15 | valueName: 'MyCustomValue', 16 | value: 1050 17 | }, function (err) { 18 | if (err) { 19 | throw err; 20 | } 21 | 22 | console.log('Done!'); 23 | }); -------------------------------------------------------------------------------- /samples/207_unzip.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge') 4 | , path = require('path'); 5 | 6 | var unzipDirectory = edge.func(function() {/* 7 | #r "System.IO.Compression.FileSystem.dll" 8 | 9 | using System.IO.Compression; 10 | 11 | async (dynamic input) => 12 | { 13 | await Task.Run(async () => { 14 | ZipFile.ExtractToDirectory((string)input.source, (string)input.destination); 15 | }); 16 | 17 | return null; 18 | } 19 | */}); 20 | 21 | var params = { 22 | source: path.join(__dirname, '..', 'samples.zip'), 23 | destination: path.join(__dirname, '..', 'samples_tmp') 24 | }; 25 | 26 | unzipDirectory(params, function (error) { 27 | if (error) throw error; 28 | console.log('The ..\\samples.zip archive has been decompressed to ..\\samples_tmp directory.'); 29 | }); 30 | -------------------------------------------------------------------------------- /samples/207_zip.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge') 4 | , path = require('path'); 5 | 6 | var zipDirectory = edge.func(function() {/* 7 | #r "System.IO.Compression.FileSystem.dll" 8 | 9 | using System.IO.Compression; 10 | 11 | async (dynamic input) => 12 | { 13 | await Task.Run(async () => { 14 | ZipFile.CreateFromDirectory((string)input.source, (string)input.destination); 15 | }); 16 | 17 | return null; 18 | } 19 | */}); 20 | 21 | var params = { 22 | source: path.join(__dirname, '..', 'samples'), 23 | destination: path.join(__dirname, '..', 'samples.zip') 24 | }; 25 | 26 | zipDirectory(params, function (error) { 27 | if (error) throw error; 28 | console.log('The samples directory has been compressed to ..\\samples.zip file.'); 29 | }); 30 | -------------------------------------------------------------------------------- /samples/208_convertImage.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge') 4 | , path = require('path'); 5 | 6 | var convertImage = edge.func(function() {/* 7 | #r "System.Drawing.dll" 8 | 9 | using System; 10 | using System.Threading.Tasks; 11 | using System.Collections.Generic; 12 | using System.Drawing; 13 | using System.Drawing.Imaging; 14 | 15 | class Startup 16 | { 17 | static IDictionary formats = new Dictionary 18 | { 19 | { "jpg", ImageFormat.Jpeg }, 20 | { "bmp", ImageFormat.Bmp }, 21 | { "gif", ImageFormat.Gif }, 22 | { "tiff", ImageFormat.Tiff }, 23 | { "png", ImageFormat.Png } 24 | }; 25 | 26 | public async Task Invoke(IDictionary input) 27 | { 28 | await Task.Run(async () => { 29 | using (Image image = Image.FromFile((string)input["source"])) 30 | { 31 | image.Save((string)input["destination"], formats[(string)input["toType"]]); 32 | } 33 | }); 34 | 35 | return null; 36 | } 37 | } 38 | */}); 39 | 40 | var params = { 41 | source: path.join(__dirname, 'edge.png'), 42 | destination: path.join(__dirname, 'edge.jpg'), 43 | toType: 'jpg' 44 | }; 45 | 46 | convertImage(params, function (error) { 47 | if (error) throw error; 48 | console.log('The edge.png has been asynchronously converted to edge.jpg.'); 49 | }); 50 | -------------------------------------------------------------------------------- /samples/210_windows_authentication.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge') 4 | , http = require('http'); 5 | 6 | var authenticate = edge.func(function() {/* 7 | using System; 8 | using System.Threading.Tasks; 9 | using System.Runtime.InteropServices; 10 | using System.Security.Principal; 11 | 12 | class Startup 13 | { 14 | 15 | [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 16 | public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, 17 | int dwLogonType, int dwLogonProvider, out IntPtr phToken); 18 | 19 | [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 20 | public extern static bool CloseHandle(IntPtr handle); 21 | 22 | public async Task Invoke(dynamic input) 23 | { 24 | return await Task.Run(() => { 25 | IntPtr token; 26 | if (!Startup.LogonUser(input.user, null, input.password, 3, 0, out token)) 27 | { 28 | throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); 29 | } 30 | 31 | try { 32 | using (WindowsIdentity id = new WindowsIdentity(token)) 33 | { 34 | return new { 35 | name = id.Name, 36 | sid = id.User.ToString() 37 | }; 38 | } 39 | } 40 | finally { 41 | Startup.CloseHandle(token); 42 | } 43 | }); 44 | } 45 | } 46 | */}); 47 | 48 | http.createServer(function (req, res) { 49 | function challange() { 50 | res.writeHead(401, { 'WWW-Authenticate': 'Basic realm=""' }); 51 | res.end(); 52 | } 53 | 54 | if (req.headers.authorization && req.headers.authorization.indexOf('Basic ') === 0) { 55 | var tokens = new Buffer(req.headers.authorization.substring(6), 'base64').toString('utf8').split(':'); 56 | if (!tokens || tokens.length !== 2 || tokens[0] === 'noone' && tokens[1] === 'noone') { 57 | challange(); 58 | } 59 | else { 60 | authenticate({ user: tokens[0], password: tokens[1] }, function (error, result) { 61 | if (error) { 62 | console.log(error); 63 | challange(); 64 | } 65 | else { 66 | res.writeHead(200, { 'Content-Type': 'text/html' }); 67 | res.write('

Welcome ' + result.name + ' (' + result.sid + ')'); 68 | res.end('

Logout'); 69 | } 70 | }) 71 | } 72 | } 73 | else { 74 | challange(); 75 | } 76 | }).listen(process.env.PORT || 8080); 77 | -------------------------------------------------------------------------------- /samples/211_events.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge'); 4 | 5 | var subscribe = edge.func(function() {/* 6 | async (dynamic input) => 7 | { 8 | // Create a timer with the specifed interval. 9 | // Conceptually this can be any event source. 10 | 11 | var timer = new System.Timers.Timer(input.interval); 12 | 13 | // Hook up the Elapsed event for the timer and delegate 14 | // the call to a Node.js event handler. 15 | // Depending on the EventArgs, the data may need to be transformed 16 | // if it cannot be directly marshaled by Edge.js. 17 | 18 | timer.Elapsed += (Object source, System.Timers.ElapsedEventArgs e) => { 19 | ((Func>)input.event_handler)(e).Start(); 20 | }; 21 | 22 | // Start the timer 23 | 24 | timer.Enabled = true; 25 | 26 | // Return a function that can be used by Node.js to 27 | // unsubscribe from the event source. 28 | 29 | return (Func>)(async (dynamic data) => { 30 | timer.Enabled = false; 31 | return null; 32 | }); 33 | } 34 | */}); 35 | 36 | subscribe({ 37 | interval: 2000, 38 | event_handler: function (data, cb) { 39 | console.log('Received event', data); 40 | cb(); 41 | } 42 | }, function (error, unsubscribe) { 43 | if (error) throw error; 44 | console.log('Subscribed to .NET events. Unsubscribing in 7 seconds...'); 45 | setTimeout(function () { 46 | unsubscribe(null, function (error) { 47 | if (error) throw error; 48 | console.log('Unsubscribed from .NET events.'); 49 | console.log('Waiting 5 seconds before exit to show that no more events are generated...') 50 | setTimeout(function () {}, 5000); 51 | }); 52 | }, 7000); 53 | }); 54 | -------------------------------------------------------------------------------- /samples/301_cspyfsps.js: -------------------------------------------------------------------------------- 1 | // Overview of edge.js: http://tjanczuk.github.com/edge 2 | 3 | var edge = require('../lib/edge') 4 | , async = require('async'); 5 | 6 | var helloCs = edge.func(function () {/* 7 | async (input) => 8 | { 9 | return "C# welcomes " + input.ToString(); 10 | } 11 | */}); 12 | 13 | var helloPy = edge.func('py', function () {/* 14 | def hello(input): 15 | return "Python welcomes " + input 16 | 17 | lambda x: hello(x) 18 | */}); 19 | 20 | var helloFs = edge.func('fs', function () {/* 21 | fun input -> async { 22 | return "F# welcomes " + input.ToString() 23 | } 24 | */}); 25 | 26 | var helloPs = edge.func('ps', function () {/* 27 | "PowerShell welcomes $inputFromJS" 28 | */}); 29 | 30 | async.waterfall([ 31 | function (cb) { cb(null, 'Node.js'); }, 32 | 33 | helloFs, 34 | helloCs, 35 | helloPy, 36 | helloPs 37 | ], function (error, result) { 38 | console.log(error || result[0]); 39 | }); -------------------------------------------------------------------------------- /samples/edge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epicchainlabs/epicchain-edge-js-api/43844107b013b4f6d5e79261a29cdf4b4d2a1ccc/samples/edge.png -------------------------------------------------------------------------------- /samples/readme.txt: -------------------------------------------------------------------------------- 1 | Foundations: 2 | 3 | 101_hello_lambda.js - prescriptive interface pattern 4 | 102_hello_function.js - multiline function comment 5 | 103_hello_file.js - separate file 6 | 104_add7_class.js - entire class instead of lambda 7 | 105_add7_dll.js - pre-compiled DLL 8 | On Windows: 9 | csc.exe /target:library /debug Sample105.cs 10 | On Mono (MacOS, Linux): 11 | mcs -sdk:4.5 Sample105.cs -target:library 12 | start repl, attach VS, call func, show debugging 13 | 106_marshal_v82cls.js - data from V8 to CLR 14 | 107_marshal_clr2v8.js - data from CLR to V8 15 | 108_func.js - marshal func from v8 to CLR and call node from .NET 16 | 109_sync.js - async and sync calling conventions 17 | 18 | Scenarios: 19 | 20 | 201_worker.js - CPU bound operation 21 | 202_sql.js - access SQL with async ADO.NET 22 | set OWIN_SQL_CONNECTION_STRING=Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True 23 | reference assemblies 24 | 206_registery - read/write registery operations 25 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/coreclrfuncinvokecontext.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | CoreClrFuncInvokeContext::CoreClrFuncInvokeContext(v8::Local callback, void* task) : task(task), uv_edge_async(NULL), resultData(NULL), resultType(0) 4 | { 5 | DBG("CoreClrFuncInvokeContext::CoreClrFuncInvokeContext"); 6 | 7 | this->callback = new Nan::Callback(v8::Local::Cast(callback)); 8 | } 9 | 10 | CoreClrFuncInvokeContext::~CoreClrFuncInvokeContext() 11 | { 12 | DBG("CoreClrFuncInvokeContext::~CoreClrFuncInvokeContext"); 13 | 14 | if (this->callback) 15 | { 16 | this->callback->Reset(); 17 | delete this->callback; 18 | this->callback = NULL; 19 | } 20 | 21 | if (this->task) 22 | { 23 | CoreClrEmbedding::FreeHandle(this->task); 24 | this->task = NULL; 25 | } 26 | 27 | if (this->resultData) 28 | { 29 | CoreClrEmbedding::FreeMarshalData(this->resultData, this->resultType); 30 | this->resultData = NULL; 31 | } 32 | } 33 | 34 | void CoreClrFuncInvokeContext::InitializeAsyncOperation() 35 | { 36 | DBG("CoreClrFuncInvokeContext::InitializeAsyncOperation"); 37 | this->uv_edge_async = V8SynchronizationContext::RegisterAction(CoreClrFuncInvokeContext::InvokeCallback, this); 38 | } 39 | 40 | void CoreClrFuncInvokeContext::TaskComplete(void* result, int resultType, int taskState, CoreClrFuncInvokeContext* context) 41 | { 42 | DBG("CoreClrFuncInvokeContext::TaskComplete"); 43 | 44 | context->resultData = result; 45 | context->resultType = resultType; 46 | context->taskState = taskState; 47 | 48 | V8SynchronizationContext::ExecuteAction(context->uv_edge_async); 49 | } 50 | 51 | void CoreClrFuncInvokeContext::TaskCompleteSynchronous(void* result, int resultType, int taskState, v8::Local callback) 52 | { 53 | DBG("CoreClrFuncInvokeContext::TaskCompleteSynchronous"); 54 | 55 | CoreClrFuncInvokeContext* context = new CoreClrFuncInvokeContext(callback, NULL); 56 | 57 | context->resultData = result; 58 | context->resultType = resultType; 59 | context->taskState = taskState; 60 | 61 | InvokeCallback(context); 62 | } 63 | 64 | void CoreClrFuncInvokeContext::InvokeCallback(void* data) 65 | { 66 | DBG("CoreClrFuncInvokeContext::InvokeCallback"); 67 | 68 | CoreClrFuncInvokeContext* context = (CoreClrFuncInvokeContext*)data; 69 | v8::Local callbackData = Nan::Null(); 70 | v8::Local errors = Nan::Null(); 71 | 72 | if (context->taskState == TaskStatusFaulted) 73 | { 74 | errors = CoreClrFunc::MarshalCLRToV8(context->resultData, context->resultType); 75 | } 76 | 77 | else 78 | { 79 | callbackData = CoreClrFunc::MarshalCLRToV8(context->resultData, context->resultType); 80 | } 81 | 82 | DBG("CoreClrFuncInvokeContext::InvokeCallback - Marshalling complete"); 83 | 84 | v8::Local argv[] = { errors, callbackData }; 85 | int argc = 2; 86 | 87 | Nan::TryCatch tryCatch; 88 | 89 | DBG("CoreClrFuncInvokeContext::InvokeCallback - calling JS callback"); 90 | 91 | Nan::AsyncResource resource("CoreClrFuncInvokeContext::InvokeCallback"); 92 | context->callback->Call(argc, argv, &resource); 93 | delete context; 94 | if (tryCatch.HasCaught()) 95 | { 96 | DBG("CoreClrFuncInvokeContext::InvokeCallback - exception in callback"); 97 | Nan::FatalException(tryCatch); 98 | } 99 | 100 | DBG("CoreClrFuncInvokeContext::InvokeCallback - Complete"); 101 | } 102 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/coreclrnodejsfunc.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | CoreClrNodejsFunc::CoreClrNodejsFunc(v8::Local function) 4 | { 5 | DBG("CoreClrNodejsFunc::CoreClrNodejsFunc"); 6 | 7 | this->Func = new Nan::Persistent; 8 | this->Func->Reset(function); 9 | } 10 | 11 | CoreClrNodejsFunc::~CoreClrNodejsFunc() 12 | { 13 | DBG("CoreClrNodejsFunc::~CoreClrNodejsFunc"); 14 | this->Func->Reset(); 15 | delete this->Func; 16 | this->Func = NULL; 17 | } 18 | 19 | void CoreClrNodejsFunc::Release(CoreClrNodejsFunc* function) 20 | { 21 | DBG("CoreClrNodejsFunc::Release"); 22 | delete function; 23 | } 24 | 25 | void CoreClrNodejsFunc::Call(void* payload, int payloadType, CoreClrNodejsFunc* functionContext, CoreClrGcHandle callbackContext, NodejsFuncCompleteFunction callbackFunction) 26 | { 27 | DBG("CoreClrNodejsFunc::Call"); 28 | 29 | CoreClrNodejsFuncInvokeContext* invokeContext = new CoreClrNodejsFuncInvokeContext(payload, payloadType, functionContext, callbackContext, callbackFunction); 30 | invokeContext->Invoke(); 31 | } 32 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/deps/deps_entry.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef __DEPS_ENTRY_H_ 5 | #define __DEPS_ENTRY_H_ 6 | 7 | #if EDGE_PLATFORM_NIX 8 | #include "../edge.h" 9 | #endif 10 | #include 11 | #include 12 | #include 13 | #include "../pal/pal.h" 14 | 15 | struct deps_entry_t 16 | { 17 | enum asset_types 18 | { 19 | runtime = 0, 20 | resources, 21 | native, 22 | count 23 | }; 24 | 25 | static const std::array s_known_asset_types; 26 | 27 | pal::string_t library_type; 28 | pal::string_t library_name; 29 | pal::string_t library_version; 30 | pal::string_t library_hash; 31 | asset_types asset_type; 32 | pal::string_t asset_name; 33 | pal::string_t relative_path; 34 | bool is_serviceable; 35 | bool is_rid_specific; 36 | 37 | 38 | // Given a "base" dir, yield the filepath within this directory or relative to this directory based on "look_in_base" 39 | bool to_path(const pal::string_t& base, bool look_in_base, pal::string_t* str) const; 40 | 41 | // Given a "base" dir, yield the file path within this directory. 42 | bool to_dir_path(const pal::string_t& base, pal::string_t* str) const; 43 | 44 | // Given a "base" dir, yield the relative path in the package layout. 45 | bool to_rel_path(const pal::string_t& base, pal::string_t* str) const; 46 | 47 | // Given a "base" dir, yield the relative path with package name, version in the package layout. 48 | bool to_full_path(const pal::string_t& root, pal::string_t* str) const; 49 | 50 | // Given a "base" dir, yield the relative path with package name, version in the package layout only if 51 | // the hash matches contents of the hash file. 52 | bool to_hash_matched_path(const pal::string_t& root, pal::string_t* str) const; 53 | }; 54 | 55 | #endif // __DEPS_ENTRY_H_ 56 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/deps/deps_format.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef __DEPS_FORMAT_H_ 5 | #define __DEPS_FORMAT_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../pal/pal.h" 12 | #include "deps_entry.h" 13 | #include "cpprest/json.h" 14 | 15 | void set_own_rid(pal::string_t set_rid); 16 | 17 | class deps_json_t 18 | { 19 | typedef web::json::value json_value; 20 | struct vec_t { std::vector vec; }; 21 | struct assets_t { std::array by_type; }; 22 | struct deps_assets_t { std::unordered_map libs; }; 23 | struct rid_assets_t { std::unordered_map rid_assets; }; 24 | struct rid_specific_assets_t { std::unordered_map libs; }; 25 | 26 | typedef std::unordered_map> str_to_vector_map_t; 27 | typedef str_to_vector_map_t rid_fallback_graph_t; 28 | 29 | 30 | public: 31 | deps_json_t() 32 | : m_valid(false) 33 | , m_file_exists(false) 34 | { 35 | } 36 | 37 | deps_json_t(bool portable, const pal::string_t& deps_path) 38 | : deps_json_t(portable, deps_path, m_rid_fallback_graph /* dummy */) 39 | { 40 | } 41 | 42 | deps_json_t(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& graph) 43 | : deps_json_t() 44 | { 45 | m_valid = load(portable, deps_path, graph); 46 | } 47 | 48 | const std::vector& get_entries(deps_entry_t::asset_types type) 49 | { 50 | assert(type < deps_entry_t::asset_types::count); 51 | return m_deps_entries[type]; 52 | } 53 | 54 | bool has_package(const pal::string_t& name, const pal::string_t& ver) const; 55 | 56 | bool exists() 57 | { 58 | return m_file_exists; 59 | } 60 | 61 | bool is_valid() 62 | { 63 | return m_valid; 64 | } 65 | 66 | const rid_fallback_graph_t& get_rid_fallback_graph() 67 | { 68 | return m_rid_fallback_graph; 69 | } 70 | 71 | const deps_entry_t& try_ni(const deps_entry_t& entry) const; 72 | 73 | private: 74 | bool load_standalone(const json_value& json, const pal::string_t& target_name); 75 | bool load_portable(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph); 76 | bool load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph); 77 | bool process_runtime_targets(const json_value& json, const pal::string_t& target_name, const rid_fallback_graph_t& rid_fallback_graph, rid_specific_assets_t* p_assets); 78 | bool process_targets(const json_value& json, const pal::string_t& target_name, deps_assets_t* p_assets); 79 | 80 | void reconcile_libraries_with_targets( 81 | const json_value& json, 82 | const std::function& library_exists_fn, 83 | const std::function&(const pal::string_t&, int, bool*)>& get_rel_paths_by_asset_type_fn); 84 | 85 | bool perform_rid_fallback(rid_specific_assets_t* portable_assets, const rid_fallback_graph_t& rid_fallback_graph); 86 | 87 | std::vector m_deps_entries[deps_entry_t::asset_types::count]; 88 | 89 | deps_assets_t m_assets; 90 | rid_specific_assets_t m_rid_assets; 91 | 92 | std::unordered_map m_ni_entries; 93 | rid_fallback_graph_t m_rid_fallback_graph; 94 | bool m_file_exists; 95 | bool m_valid; 96 | }; 97 | 98 | #endif // __DEPS_FORMAT_H_ 99 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/fxr/fx_muxer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | class corehost_init_t; 5 | class runtime_config_t; 6 | struct fx_ver_t; 7 | 8 | #include "../host/libhost.h" 9 | 10 | int execute_app( 11 | const pal::string_t& impl_dll_dir, 12 | corehost_init_t* init, 13 | const int argc, 14 | const pal::char_t* argv[]); 15 | 16 | class fx_muxer_t 17 | { 18 | public: 19 | static int execute(const int argc, const pal::char_t* argv[]); 20 | static pal::string_t resolve_fx_dir(host_mode_t mode, const pal::string_t& own_dir, const runtime_config_t& config, const pal::string_t& specified_fx_version); 21 | static bool resolve_sdk_dotnet_path(const pal::string_t& own_dir, pal::string_t* cli_sdk); 22 | private: 23 | static int read_config_and_execute( 24 | const pal::string_t& own_dir, 25 | const pal::string_t& app_candidate, 26 | const std::unordered_map>& opts, 27 | int new_argc, const pal::char_t** new_argv, host_mode_t mode); 28 | static int parse_args_and_execute(const pal::string_t& own_dir, const pal::string_t& own_dll, int argoff, int argc, const pal::char_t* argv[], bool exec_mode, host_mode_t mode, bool* can_execute); 29 | static bool resolve_hostpolicy_dir(host_mode_t mode, 30 | const pal::string_t& own_dir, 31 | const pal::string_t& fx_dir, 32 | const pal::string_t& app_or_deps_dir, 33 | const pal::string_t& specified_deps_file, 34 | const pal::string_t& specified_fx_version, 35 | const std::vector& probe_realpaths, 36 | const runtime_config_t& config, 37 | pal::string_t* impl_dir); 38 | static pal::string_t resolve_cli_version(const pal::string_t& global); 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/fxr/fx_ver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef __FX_VER_H__ 5 | #define __FX_VER_H__ 6 | 7 | #include "../pal/pal.h" 8 | 9 | // Note: This is not SemVer (esp., in comparing pre-release part, fx_ver_t does not 10 | // compare multiple dot separated identifiers individually.) ex: 1.0.0-beta.2 vs. 1.0.0-beta.11 11 | struct fx_ver_t 12 | { 13 | fx_ver_t(int major, int minor, int patch); 14 | fx_ver_t(int major, int minor, int patch, const pal::string_t& pre); 15 | fx_ver_t(int major, int minor, int patch, const pal::string_t& pre, const pal::string_t& build); 16 | 17 | int get_major() const { return m_major; } 18 | int get_minor() const { return m_minor; } 19 | int get_patch() const { return m_patch; } 20 | 21 | void set_major(int m) { m_major = m; } 22 | void set_minor(int m) { m_minor = m; } 23 | void set_patch(int p) { m_patch = p; } 24 | 25 | bool is_prerelease() const { return !m_pre.empty(); } 26 | 27 | pal::string_t as_str() const; 28 | pal::string_t prerelease_glob() const; 29 | pal::string_t patch_glob() const; 30 | 31 | bool operator ==(const fx_ver_t& b) const; 32 | bool operator !=(const fx_ver_t& b) const; 33 | bool operator <(const fx_ver_t& b) const; 34 | bool operator >(const fx_ver_t& b) const; 35 | 36 | static bool parse(const pal::string_t& ver, fx_ver_t* fx_ver, bool parse_only_production = false); 37 | 38 | private: 39 | int m_major; 40 | int m_minor; 41 | int m_patch; 42 | pal::string_t m_pre; 43 | pal::string_t m_build; 44 | 45 | static int compare(const fx_ver_t&a, const fx_ver_t& b); 46 | }; 47 | 48 | #endif // __FX_VER_H__ -------------------------------------------------------------------------------- /src/CoreCLREmbedding/host/args.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #include "args.h" 5 | #include "../pal/pal_utils.h" 6 | #include "coreclr.h" 7 | #include "libhost.h" 8 | 9 | arguments_t::arguments_t() : 10 | managed_application(_X("")), 11 | own_path(_X("")), 12 | app_dir(_X("")), 13 | app_argc(0), 14 | app_argv(nullptr), 15 | dotnet_packages_cache(_X("")), 16 | core_servicing(_X("")), 17 | deps_path(_X("")) 18 | { 19 | } 20 | 21 | bool parse_arguments( 22 | const pal::string_t& deps_path, 23 | const std::vector& probe_paths, 24 | host_mode_t mode, 25 | const int argc, const pal::char_t* argv[], arguments_t* arg_out) 26 | { 27 | arguments_t& args = *arg_out; 28 | // Get the full name of the application 29 | if (!pal::get_own_executable_path(&args.own_path) || !pal::realpath(&args.own_path)) 30 | { 31 | trace::error(_X("Failed to resolve full path of the current executable [%s]"), args.own_path.c_str()); 32 | return false; 33 | } 34 | 35 | auto own_name = get_filename(args.own_path); 36 | auto own_dir = get_directory(args.own_path); 37 | 38 | if (mode != host_mode_t::standalone) 39 | { 40 | // corerun mode. First argument is managed app 41 | if (argc < 2) 42 | { 43 | return false; 44 | } 45 | args.managed_application = pal::string_t(argv[1]); 46 | if (!pal::realpath(&args.managed_application)) 47 | { 48 | trace::error(_X("Failed to locate managed application [%s]"), args.managed_application.c_str()); 49 | return false; 50 | } 51 | args.app_dir = get_directory(args.managed_application); 52 | args.app_argc = argc - 2; 53 | args.app_argv = &argv[2]; 54 | } 55 | else 56 | { 57 | // coreconsole mode. Find the managed app in the same directory 58 | pal::string_t managed_app(own_dir); 59 | managed_app.push_back(DIR_SEPARATOR); 60 | managed_app.append(get_executable(own_name)); 61 | managed_app.append(_X(".dll")); 62 | args.managed_application = managed_app; 63 | if (!pal::realpath(&args.managed_application)) 64 | { 65 | trace::error(_X("Failed to locate managed application [%s]"), args.managed_application.c_str()); 66 | return false; 67 | } 68 | args.app_dir = own_dir; 69 | args.app_argv = &argv[1]; 70 | args.app_argc = argc - 1; 71 | } 72 | 73 | if (!deps_path.empty()) 74 | { 75 | args.deps_path = deps_path; 76 | args.app_dir = get_directory(args.deps_path); 77 | } 78 | 79 | for (const auto& probe : probe_paths) 80 | { 81 | args.probe_paths.push_back(probe); 82 | } 83 | 84 | if (args.deps_path.empty()) 85 | { 86 | const auto& app_base = args.app_dir; 87 | auto app_name = get_filename(args.managed_application); 88 | 89 | args.deps_path.reserve(app_base.length() + 1 + app_name.length() + 5); 90 | args.deps_path.append(app_base); 91 | args.deps_path.push_back(DIR_SEPARATOR); 92 | args.deps_path.append(app_name, 0, app_name.find_last_of(_X("."))); 93 | args.deps_path.append(_X(".deps.json")); 94 | } 95 | 96 | pal::getenv(_X("DOTNET_HOSTING_OPTIMIZATION_CACHE"), &args.dotnet_packages_cache); 97 | pal::get_default_servicing_directory(&args.core_servicing); 98 | 99 | return true; 100 | } 101 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/host/args.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef ARGS_H 5 | #define ARGS_H 6 | 7 | #include "../pal/pal_utils.h" 8 | #include "../pal/pal.h" 9 | #include "../pal/trace.h" 10 | #include "../deps/deps_format.h" 11 | #include "libhost.h" 12 | 13 | struct probe_config_t 14 | { 15 | pal::string_t probe_dir; 16 | bool match_hash; 17 | bool patch_roll_fwd; 18 | bool prerelease_roll_fwd; 19 | const deps_json_t* probe_deps_json; 20 | 21 | bool only_runtime_assets; 22 | bool only_serviceable_assets; 23 | 24 | void print() const 25 | { 26 | trace::verbose(_X("probe_config_t: probe=[%s] match-hash=[%d] patch-roll-forward=[%d] prerelease-roll-forward=[%d] deps-json=[%p]"), 27 | probe_dir.c_str(), match_hash, patch_roll_fwd, prerelease_roll_fwd, probe_deps_json); 28 | } 29 | bool is_roll_fwd_set() const 30 | { 31 | return patch_roll_fwd || prerelease_roll_fwd; 32 | } 33 | 34 | probe_config_t( 35 | const pal::string_t& probe_dir, 36 | bool match_hash, 37 | bool patch_roll_fwd, 38 | bool prerelease_roll_fwd, 39 | const deps_json_t* probe_deps_json, 40 | bool only_serviceable_assets, 41 | bool only_runtime_assets) 42 | : probe_dir(probe_dir) 43 | , match_hash(match_hash) 44 | , patch_roll_fwd(patch_roll_fwd) 45 | , prerelease_roll_fwd(prerelease_roll_fwd) 46 | , probe_deps_json(probe_deps_json) 47 | , only_serviceable_assets(only_serviceable_assets) 48 | , only_runtime_assets(only_runtime_assets) 49 | { 50 | // Cannot roll forward and also match hash. 51 | assert(!is_roll_fwd_set() || !match_hash); 52 | // Will not roll forward within a deps json. 53 | assert(!is_roll_fwd_set() || probe_deps_json == nullptr); 54 | // Will not do hash match when probing a deps json. 55 | assert(!match_hash || probe_deps_json == nullptr); 56 | } 57 | 58 | static probe_config_t svc_ni(const pal::string_t& dir, bool patch_roll_fwd, bool prerelease_roll_fwd) 59 | { 60 | return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, true); 61 | } 62 | 63 | static probe_config_t svc(const pal::string_t& dir, bool patch_roll_fwd, bool prerelease_roll_fwd) 64 | { 65 | return probe_config_t(dir, false, patch_roll_fwd, prerelease_roll_fwd, nullptr, true, false); 66 | } 67 | 68 | static probe_config_t cache_ni(const pal::string_t& dir) 69 | { 70 | return probe_config_t(dir, true, false, false, nullptr, false, true); 71 | } 72 | 73 | static probe_config_t cache(const pal::string_t& dir) 74 | { 75 | return probe_config_t(dir, true, false, false, nullptr, false, false); 76 | } 77 | 78 | static probe_config_t fx(const pal::string_t& dir, const deps_json_t* deps) 79 | { 80 | return probe_config_t(dir, false, false, false, deps, false, false); 81 | } 82 | 83 | static probe_config_t additional(const pal::string_t& dir) 84 | { 85 | return probe_config_t(dir, false, false, false, nullptr, false, false); 86 | } 87 | }; 88 | 89 | struct arguments_t 90 | { 91 | pal::string_t own_path; 92 | pal::string_t app_dir; 93 | pal::string_t deps_path; 94 | pal::string_t core_servicing; 95 | std::vector probe_paths; 96 | pal::string_t dotnet_packages_cache; 97 | pal::string_t managed_application; 98 | 99 | int app_argc; 100 | const pal::char_t** app_argv; 101 | 102 | arguments_t(); 103 | 104 | inline void print() 105 | { 106 | if (trace::is_enabled()) 107 | { 108 | trace::verbose(_X("-- arguments_t: own_path=%s app_dir=%s deps=%s core_svc=%s packages_cache=%s mgd_app=%s"), 109 | own_path.c_str(), app_dir.c_str(), deps_path.c_str(), core_servicing.c_str(), dotnet_packages_cache.c_str(), managed_application.c_str()); 110 | for (const auto& probe : probe_paths) 111 | { 112 | trace::verbose(_X("-- arguments_t: probe dir: [%s]"), probe.c_str()); 113 | } 114 | } 115 | } 116 | }; 117 | 118 | bool parse_arguments(const pal::string_t& deps_path, const std::vector& probe_paths, host_mode_t mode, const int argc, const pal::char_t* argv[], arguments_t* args); 119 | 120 | #endif // ARGS_H 121 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/host/coreclr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #include 5 | 6 | #include "coreclr.h" 7 | #include "../pal/pal_utils.h" 8 | 9 | // Prototype of the coreclr_initialize function from coreclr.dll 10 | typedef pal::hresult_t(STDMETHODCALLTYPE *coreclr_initialize_fn)( 11 | const char* exePath, 12 | const char* appDomainFriendlyName, 13 | int propertyCount, 14 | const char** propertyKeys, 15 | const char** propertyValues, 16 | coreclr::host_handle_t* hostHandle, 17 | unsigned int* domainId); 18 | 19 | // Prototype of the coreclr_shutdown function from coreclr.dll 20 | typedef pal::hresult_t(STDMETHODCALLTYPE *coreclr_shutdown_fn)( 21 | coreclr::host_handle_t hostHandle, 22 | unsigned int domainId); 23 | 24 | // Prototype of the coreclr_execute_assembly function from coreclr.dll 25 | typedef pal::hresult_t(STDMETHODCALLTYPE *coreclr_execute_assembly_fn)( 26 | coreclr::host_handle_t hostHandle, 27 | unsigned int domainId, 28 | int argc, 29 | const char** argv, 30 | const char* managedAssemblyPath, 31 | unsigned int* exitCode); 32 | 33 | // Prototype of the coreclr_create_delegate function from coreclr.dll 34 | typedef pal::hresult_t(STDMETHODCALLTYPE *coreclr_create_delegate_fn)( 35 | coreclr::host_handle_t hostHandle, 36 | unsigned int domainId, 37 | const char* assemblyName, 38 | const char* typeName, 39 | const char* methodName, 40 | void** delegate); 41 | 42 | static coreclr_shutdown_fn coreclr_shutdown = nullptr; 43 | static coreclr_initialize_fn coreclr_initialize = nullptr; 44 | static coreclr_execute_assembly_fn coreclr_execute_assembly = nullptr; 45 | static coreclr_create_delegate_fn coreclr_create_delegate = nullptr; 46 | 47 | bool coreclr::bind(const pal::string_t& libcoreclr_path) 48 | { 49 | assert(g_coreclr == nullptr); 50 | 51 | pal::string_t coreclr_dll_path(libcoreclr_path); 52 | append_path(&coreclr_dll_path, LIBCORECLR_NAME); 53 | 54 | if (!pal::load_library(coreclr_dll_path.c_str(), &g_coreclr)) 55 | { 56 | return false; 57 | } 58 | 59 | coreclr_initialize = (coreclr_initialize_fn)pal::get_symbol(g_coreclr, "coreclr_initialize"); 60 | coreclr_shutdown = (coreclr_shutdown_fn)pal::get_symbol(g_coreclr, "coreclr_shutdown"); 61 | coreclr_execute_assembly = (coreclr_execute_assembly_fn)pal::get_symbol(g_coreclr, "coreclr_execute_assembly"); 62 | coreclr_create_delegate = (coreclr_create_delegate_fn)pal::get_symbol(g_coreclr, "coreclr_create_delegate"); 63 | 64 | return true; 65 | } 66 | 67 | void coreclr::unload() 68 | { 69 | assert(g_coreclr != nullptr && coreclr_initialize != nullptr); 70 | 71 | pal::unload_library(g_coreclr); 72 | } 73 | 74 | pal::hresult_t coreclr::initialize( 75 | const char* exe_path, 76 | const char* app_domain_friendly_name, 77 | const char** property_keys, 78 | const char** property_values, 79 | int property_count, 80 | host_handle_t* host_handle, 81 | domain_id_t* domain_id) 82 | { 83 | assert(g_coreclr != nullptr && coreclr_initialize != nullptr); 84 | 85 | return coreclr_initialize( 86 | exe_path, 87 | app_domain_friendly_name, 88 | property_count, 89 | property_keys, 90 | property_values, 91 | host_handle, 92 | domain_id); 93 | } 94 | 95 | pal::hresult_t coreclr::shutdown(host_handle_t host_handle, domain_id_t domain_id) 96 | { 97 | assert(g_coreclr != nullptr && coreclr_shutdown != nullptr); 98 | 99 | return coreclr_shutdown(host_handle, domain_id); 100 | } 101 | 102 | pal::hresult_t coreclr::execute_assembly( 103 | host_handle_t host_handle, 104 | domain_id_t domain_id, 105 | int argc, 106 | const char** argv, 107 | const char* managed_assembly_path, 108 | unsigned int* exit_code) 109 | { 110 | assert(g_coreclr != nullptr && coreclr_execute_assembly != nullptr); 111 | 112 | return coreclr_execute_assembly( 113 | host_handle, 114 | domain_id, 115 | argc, 116 | argv, 117 | managed_assembly_path, 118 | exit_code); 119 | } 120 | 121 | pal::hresult_t coreclr::create_delegate( 122 | coreclr::host_handle_t hostHandle, 123 | unsigned int domainId, 124 | const char* assemblyName, 125 | const char* typeName, 126 | const char* methodName, 127 | void** delegate) 128 | { 129 | return coreclr_create_delegate(hostHandle, domainId, assemblyName, typeName, methodName, delegate); 130 | } -------------------------------------------------------------------------------- /src/CoreCLREmbedding/host/coreclr.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef CLR_H 5 | #define CLR_H 6 | 7 | #include "../pal/pal.h" 8 | #include "../pal/trace.h" 9 | 10 | namespace coreclr 11 | { 12 | typedef void* host_handle_t; 13 | typedef unsigned int domain_id_t; 14 | 15 | static pal::dll_t g_coreclr = nullptr; 16 | 17 | bool bind(const pal::string_t& libcoreclr_path); 18 | 19 | void unload(); 20 | 21 | pal::hresult_t initialize( 22 | const char* exe_path, 23 | const char* app_domain_friendly_name, 24 | const char** property_keys, 25 | const char** property_values, 26 | int property_count, 27 | host_handle_t* host_handle, 28 | domain_id_t* domain_id); 29 | 30 | pal::hresult_t shutdown(host_handle_t host_handle, domain_id_t domain_id); 31 | 32 | pal::hresult_t execute_assembly( 33 | host_handle_t host_handle, 34 | domain_id_t domain_id, 35 | int argc, 36 | const char** argv, 37 | const char* managed_assembly_path, 38 | unsigned int* exit_code); 39 | 40 | pal::hresult_t create_delegate( 41 | coreclr::host_handle_t hostHandle, 42 | unsigned int domainId, 43 | const char* assemblyName, 44 | const char* typeName, 45 | const char* methodName, 46 | void** delegate); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/host/error_codes.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef __ERROR_CODES_H__ 5 | #define __ERROR_CODES_H__ 6 | enum StatusCode 7 | { 8 | Success = 0, 9 | InvalidArgFailure = 0x80008081, 10 | CoreHostLibLoadFailure = 0x80008082, 11 | CoreHostLibMissingFailure = 0x80008083, 12 | CoreHostEntryPointFailure = 0x80008084, 13 | CoreHostCurExeFindFailure = 0x80008085, 14 | CoreHostResolveModeFailure = 0x80008086, 15 | CoreClrResolveFailure = 0x80008087, 16 | CoreClrBindFailure = 0x80008088, 17 | CoreClrInitFailure = 0x80008089, 18 | CoreClrExeFailure = 0x8000808a, 19 | ResolverInitFailure = 0x8000808b, 20 | ResolverResolveFailure = 0x8000808c, 21 | LibHostCurExeFindFailure = 0x8000808d, 22 | LibHostInitFailure = 0x8000808e, 23 | LibHostMuxFailure = 0x8000808f, 24 | LibHostExecModeFailure = 0x80008090, 25 | LibHostSdkFindFailure = 0x80008091, 26 | LibHostInvalidArgs = 0x80008092, 27 | InvalidConfigFile = 0x80008093, 28 | AppArgNotRunnable = 0x80008094 29 | }; 30 | #endif // __ERROR_CODES_H__ 31 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/host/runtime_config.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef __RUNTIME_CONFIG_H__ 5 | #define __RUNTIME_CONFIG_H__ 6 | 7 | #include 8 | 9 | #include "../pal/pal.h" 10 | #include "cpprest/json.h" 11 | 12 | typedef web::json::value json_value; 13 | 14 | class runtime_config_t 15 | { 16 | public: 17 | runtime_config_t(const pal::string_t& path, const pal::string_t& dev_path); 18 | bool is_valid() { return m_valid; } 19 | const pal::string_t& get_path() { return m_path; } 20 | const pal::string_t& get_dev_path() { return m_dev_path; } 21 | const pal::string_t& get_gc_server() const; 22 | const pal::string_t& get_fx_version() const; 23 | const pal::string_t& get_fx_name() const; 24 | const std::list& get_probe_paths() const; 25 | bool get_patch_roll_fwd() const; 26 | bool get_prerelease_roll_fwd() const; 27 | bool get_portable() const; 28 | bool parse_opts(const json_value& opts); 29 | void config_kv(std::vector*, std::vector*) const; 30 | 31 | private: 32 | bool ensure_parsed(); 33 | bool ensure_dev_config_parsed(); 34 | 35 | std::unordered_map m_properties; 36 | std::vector m_prop_keys; 37 | std::vector m_prop_values; 38 | std::list m_probe_paths; 39 | pal::string_t m_fx_name; 40 | pal::string_t m_fx_ver; 41 | bool m_patch_roll_fwd; 42 | bool m_prerelease_roll_fwd; 43 | 44 | pal::string_t m_dev_path; 45 | pal::string_t m_path; 46 | bool m_portable; 47 | bool m_valid; 48 | }; 49 | #endif // __RUNTIME_CONFIG_H__ -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/LICENSE.txt: -------------------------------------------------------------------------------- 1 | https://github.com/Microsoft/cpprestsdk 2 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/cpprest/details/basic_types.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * ==++== 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * ==--== 17 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 18 | * 19 | * Platform-dependent type definitions 20 | * 21 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 22 | * 23 | * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 24 | ****/ 25 | 26 | #pragma once 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "cpprest/details/cpprest_compat.h" 33 | 34 | #ifndef _WIN32 35 | # define __STDC_LIMIT_MACROS 36 | # include 37 | #else 38 | #include 39 | #endif 40 | 41 | #include "cpprest/details/SafeInt3.hpp" 42 | 43 | namespace utility 44 | { 45 | 46 | #ifdef _WIN32 47 | #define _UTF16_STRINGS 48 | #endif 49 | 50 | // We should be using a 64-bit size type for most situations that do 51 | // not involve specifying the size of a memory allocation or buffer. 52 | typedef uint64_t size64_t; 53 | 54 | #ifndef _WIN32 55 | typedef uint32_t HRESULT; // Needed for PPLX 56 | #endif 57 | 58 | #ifdef _UTF16_STRINGS 59 | // 60 | // On Windows, all strings are wide 61 | // 62 | typedef wchar_t char_t ; 63 | typedef std::wstring string_t; 64 | #define _XPLATSTR(x) L ## x 65 | typedef std::wostringstream ostringstream_t; 66 | typedef std::wofstream ofstream_t; 67 | typedef std::wostream ostream_t; 68 | typedef std::wistream istream_t; 69 | typedef std::wifstream ifstream_t; 70 | typedef std::wistringstream istringstream_t; 71 | typedef std::wstringstream stringstream_t; 72 | #define ucout std::wcout 73 | #define ucin std::wcin 74 | #define ucerr std::wcerr 75 | #else 76 | // 77 | // On POSIX platforms, all strings are narrow 78 | // 79 | typedef char char_t; 80 | typedef std::string string_t; 81 | #define _XPLATSTR(x) x 82 | typedef std::ostringstream ostringstream_t; 83 | typedef std::ofstream ofstream_t; 84 | typedef std::ostream ostream_t; 85 | typedef std::istream istream_t; 86 | typedef std::ifstream ifstream_t; 87 | typedef std::istringstream istringstream_t; 88 | typedef std::stringstream stringstream_t; 89 | #define ucout std::cout 90 | #define ucin std::cin 91 | #define ucerr std::cerr 92 | #endif // endif _UTF16_STRINGS 93 | 94 | #ifndef _TURN_OFF_PLATFORM_STRING 95 | #define U(x) _XPLATSTR(x) 96 | #endif // !_TURN_OFF_PLATFORM_STRING 97 | 98 | }// namespace utility 99 | 100 | typedef char utf8char; 101 | typedef std::string utf8string; 102 | typedef std::stringstream utf8stringstream; 103 | typedef std::ostringstream utf8ostringstream; 104 | typedef std::ostream utf8ostream; 105 | typedef std::istream utf8istream; 106 | typedef std::istringstream utf8istringstream; 107 | 108 | #ifdef _UTF16_STRINGS 109 | typedef wchar_t utf16char; 110 | typedef std::wstring utf16string; 111 | typedef std::wstringstream utf16stringstream; 112 | typedef std::wostringstream utf16ostringstream; 113 | typedef std::wostream utf16ostream; 114 | typedef std::wistream utf16istream; 115 | typedef std::wistringstream utf16istringstream; 116 | #else 117 | typedef char16_t utf16char; 118 | typedef std::u16string utf16string; 119 | typedef std::basic_stringstream utf16stringstream; 120 | typedef std::basic_ostringstream utf16ostringstream; 121 | typedef std::basic_ostream utf16ostream; 122 | typedef std::basic_istream utf16istream; 123 | typedef std::basic_istringstream utf16istringstream; 124 | #endif 125 | 126 | 127 | #if defined(_WIN32) 128 | // Include on everything except Windows Desktop ARM, unless explicitly excluded. 129 | #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) 130 | #if defined(WINAPI_FAMILY) 131 | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_M_ARM) 132 | #define CPPREST_EXCLUDE_WEBSOCKETS 133 | #endif 134 | #else 135 | #if defined(_M_ARM) 136 | #define CPPREST_EXCLUDE_WEBSOCKETS 137 | #endif 138 | #endif 139 | #endif 140 | #endif 141 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/cpprest/details/cpprest_compat.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * ==++== 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * ==--== 17 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 18 | * 19 | * Standard macros and definitions. 20 | * This header has minimal dependency on windows headers and is safe for use in the public API 21 | * 22 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 23 | * 24 | * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 25 | ****/ 26 | 27 | #pragma once 28 | 29 | #if defined(_WIN32) // Settings specific to Windows 30 | 31 | #if _MSC_VER >= 1900 32 | #define CPPREST_NOEXCEPT noexcept 33 | #else 34 | #define CPPREST_NOEXCEPT 35 | #endif 36 | 37 | #define CASABLANCA_UNREFERENCED_PARAMETER(x) (x) 38 | 39 | #include 40 | 41 | #else // End settings specific to Windows 42 | 43 | // Settings common to all but Windows 44 | 45 | #define __declspec(x) __attribute__ ((x)) 46 | #define dllimport 47 | #define novtable /* no novtable equivalent */ 48 | #define __assume(x) do { if (!(x)) __builtin_unreachable(); } while (false) 49 | #define CASABLANCA_UNREFERENCED_PARAMETER(x) (void)x 50 | #define CPPREST_NOEXCEPT noexcept 51 | 52 | #include 53 | #define _ASSERTE(x) assert(x) 54 | 55 | // No SAL on non Windows platforms 56 | #include "cpprest/details/nosal.h" 57 | 58 | #if not defined __cdecl 59 | #if defined cdecl 60 | #define __cdecl __attribute__ ((cdecl)) 61 | #else 62 | #define __cdecl 63 | #endif 64 | 65 | #if defined(__ANDROID__) 66 | // This is needed to disable the use of __thread inside the boost library. 67 | // Android does not support thread local storage -- if boost is included 68 | // without this macro defined, it will create references to __tls_get_addr 69 | // which (while able to link) will not be available at runtime and prevent 70 | // the .so from loading. 71 | #define BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION 72 | #endif 73 | 74 | #ifdef __clang__ 75 | #include 76 | #endif 77 | 78 | #endif // defined(__APPLE__) 79 | 80 | #endif 81 | 82 | 83 | #ifdef _NO_ASYNCRTIMP 84 | #define _ASYNCRTIMP 85 | #else 86 | #ifdef _ASYNCRT_EXPORT 87 | #define _ASYNCRTIMP __declspec(dllexport) 88 | #else 89 | #define _ASYNCRTIMP __declspec(dllimport) 90 | #endif 91 | #endif 92 | 93 | #ifdef CASABLANCA_DEPRECATION_NO_WARNINGS 94 | #define CASABLANCA_DEPRECATED(x) 95 | #else 96 | #define CASABLANCA_DEPRECATED(x) __declspec(deprecated(x)) 97 | #endif 98 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/cpprest/details/nosal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * ==++== 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * ==--== 17 | * 18 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 19 | * 20 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 21 | ***/ 22 | 23 | #pragma once 24 | // selected MS SAL annotations 25 | 26 | #ifdef _In_ 27 | #undef _In_ 28 | #endif 29 | #define _In_ 30 | 31 | #ifdef _Inout_ 32 | #undef _Inout_ 33 | #endif 34 | #define _Inout_ 35 | 36 | #ifdef _Out_ 37 | #undef _Out_ 38 | #endif 39 | #define _Out_ 40 | 41 | #ifdef _In_z_ 42 | #undef _In_z_ 43 | #endif 44 | #define _In_z_ 45 | 46 | #ifdef _Out_z_ 47 | #undef _Out_z_ 48 | #endif 49 | #define _Out_z_ 50 | 51 | #ifdef _Inout_z_ 52 | #undef _Inout_z_ 53 | #endif 54 | #define _Inout_z_ 55 | 56 | #ifdef _In_opt_ 57 | #undef _In_opt_ 58 | #endif 59 | #define _In_opt_ 60 | 61 | #ifdef _Out_opt_ 62 | #undef _Out_opt_ 63 | #endif 64 | #define _Out_opt_ 65 | 66 | #ifdef _Inout_opt_ 67 | #undef _Inout_opt_ 68 | #endif 69 | #define _Inout_opt_ 70 | 71 | #ifdef _Out_writes_ 72 | #undef _Out_writes_ 73 | #endif 74 | #define _Out_writes_(x) 75 | 76 | #ifdef _Out_writes_opt_ 77 | #undef _Out_writes_opt_ 78 | #endif 79 | #define _Out_writes_opt_(x) 80 | 81 | #ifdef _In_reads_ 82 | #undef _In_reads_ 83 | #endif 84 | #define _In_reads_(x) 85 | 86 | #ifdef _Inout_updates_bytes_ 87 | #undef _Inout_updates_bytes_ 88 | #endif 89 | #define _Inout_updates_bytes_(x) -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/stdafx.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * ==++== 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * ==--== 17 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 18 | * 19 | * Pre-compiled headers 20 | * 21 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 22 | * 23 | * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 24 | ****/ 25 | 26 | #pragma once 27 | 28 | #if defined(__clang__) 29 | #pragma clang diagnostic push 30 | #pragma clang diagnostic ignored "-Wunused-local-typedef" 31 | #endif 32 | 33 | #include 34 | #include 35 | #ifdef _WIN32 36 | #ifdef CPPREST_TARGET_XP 37 | #include 38 | #ifndef _WIN32_WINNT 39 | #define _WIN32_WINNT _WIN32_WINNT_WS03 //Windows XP with SP2 40 | #endif 41 | #endif 42 | #include 43 | // use the debug version of the CRT if _DEBUG is defined 44 | #ifdef _DEBUG 45 | #define _CRTDBG_MAP_ALLOC 46 | #include 47 | #include 48 | #endif 49 | 50 | #ifndef WIN32_LEAN_AND_MEAN 51 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 52 | // Windows Header Files: 53 | #define NOMINMAX 54 | #endif 55 | 56 | #include 57 | #include 58 | 59 | // Windows Header Files: 60 | #if !defined(__cplusplus_winrt) 61 | #include 62 | 63 | #endif // #if !defined(__cplusplus_winrt) 64 | #else // LINUX or APPLE 65 | #define __STDC_LIMIT_MACROS 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include "pthread.h" 74 | #include 75 | #include 76 | #include 77 | #include 78 | #endif // _WIN32 79 | 80 | // Macro indicating the C++ Rest SDK product itself is being built. 81 | // This is to help track how many developers are directly building from source themselves. 82 | #define _CASA_BUILD_FROM_SRC 83 | 84 | #include 85 | #include 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | 96 | // json 97 | #include "cpprest/json.h" 98 | 99 | #if defined(max) 100 | #error: max macro defined -- make sure to #define NOMINMAX before including windows.h 101 | #endif 102 | #if defined(min) 103 | #error: min macro defined -- make sure to #define NOMINMAX before including windows.h 104 | #endif 105 | 106 | #if defined(__clang__) 107 | #pragma clang diagnostic pop 108 | #endif 109 | 110 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/pal/pal_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef UTILS_H 5 | #define UTILS_H 6 | 7 | #include "pal.h" 8 | 9 | #define _STRINGIFY(s) _X(s) 10 | 11 | bool ends_with(const pal::string_t& value, const pal::string_t& suffix, bool match_case); 12 | bool starts_with(const pal::string_t& value, const pal::string_t& prefix, bool match_case); 13 | pal::string_t get_executable(const pal::string_t& filename); 14 | pal::string_t get_directory(const pal::string_t& path); 15 | pal::string_t strip_file_ext(const pal::string_t& path); 16 | pal::string_t get_filename(const pal::string_t& path); 17 | pal::string_t get_filename_without_ext(const pal::string_t& path); 18 | void append_path(pal::string_t* path1, const pal::char_t* path2); 19 | bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_lib_path); 20 | bool coreclr_exists_in_dir(const pal::string_t& candidate); 21 | void replace_char(pal::string_t* path, pal::char_t match, pal::char_t repl); 22 | const pal::char_t* get_arch(); 23 | pal::string_t get_last_known_arg( 24 | const std::unordered_map>& opts, 25 | const pal::string_t& opt_key, 26 | const pal::string_t& de_fault); 27 | bool parse_known_args( 28 | const int argc, 29 | const pal::char_t* argv[], 30 | const std::vector& known_opts, 31 | std::unordered_map>* opts, 32 | int* num_args); 33 | bool skip_utf8_bom(pal::ifstream_t* stream); 34 | #endif 35 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/pal/trace.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #include "trace.h" 5 | 6 | static bool g_enabled = false; 7 | 8 | // 9 | // Turn on tracing for the corehost based on "COREHOST_TRACE" env. 10 | // 11 | void trace::setup() 12 | { 13 | // Read trace environment variable 14 | pal::string_t trace_str; 15 | if (!pal::getenv(_X("COREHOST_TRACE"), &trace_str)) 16 | { 17 | return; 18 | } 19 | 20 | auto trace_val = pal::xtoi(trace_str.c_str()); 21 | if (trace_val > 0) 22 | { 23 | trace::enable(); 24 | trace::info(_X("Tracing enabled")); 25 | } 26 | } 27 | 28 | void trace::enable() 29 | { 30 | g_enabled = true; 31 | } 32 | 33 | bool trace::is_enabled() 34 | { 35 | return g_enabled; 36 | } 37 | 38 | void trace::verbose(const pal::char_t* format, ...) 39 | { 40 | if (g_enabled) 41 | { 42 | va_list args; 43 | va_start(args, format); 44 | pal::err_vprintf(format, args); 45 | va_end(args); 46 | } 47 | } 48 | 49 | void trace::info(const pal::char_t* format, ...) 50 | { 51 | if (g_enabled) 52 | { 53 | va_list args; 54 | va_start(args, format); 55 | pal::err_vprintf(format, args); 56 | va_end(args); 57 | } 58 | } 59 | 60 | void trace::error(const pal::char_t* format, ...) 61 | { 62 | // Always print errors 63 | va_list args; 64 | va_start(args, format); 65 | pal::err_vprintf(format, args); 66 | va_end(args); 67 | } 68 | 69 | void trace::println(const pal::char_t* format, ...) 70 | { 71 | va_list args; 72 | va_start(args, format); 73 | pal::out_vprintf(format, args); 74 | va_end(args); 75 | } 76 | 77 | void trace::println() 78 | { 79 | println(_X("")); 80 | } 81 | 82 | void trace::warning(const pal::char_t* format, ...) 83 | { 84 | if (g_enabled) 85 | { 86 | va_list args; 87 | va_start(args, format); 88 | pal::err_vprintf(format, args); 89 | va_end(args); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/pal/trace.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #ifndef TRACE_H 5 | #define TRACE_H 6 | 7 | #include "pal.h" 8 | 9 | namespace trace 10 | { 11 | void setup(); 12 | void enable(); 13 | bool is_enabled(); 14 | void verbose(const pal::char_t* format, ...); 15 | void info(const pal::char_t* format, ...); 16 | void warning(const pal::char_t* format, ...); 17 | void error(const pal::char_t* format, ...); 18 | void println(const pal::char_t* format, ...); 19 | void println(); 20 | }; 21 | 22 | #endif // TRACE_H 23 | -------------------------------------------------------------------------------- /src/common/callbackhelper.cpp: -------------------------------------------------------------------------------- 1 | #include "edge_common.h" 2 | 3 | // The Callback to use to force the next tick to happen 4 | Nan::Callback* CallbackHelper::tickCallback; 5 | 6 | static void NoOpFunction(const Nan::FunctionCallbackInfo& info) 7 | { 8 | // Do nothing, this is a no-op function 9 | } 10 | 11 | // Initialize the callback 12 | void CallbackHelper::Initialize() 13 | { 14 | DBG("CallbackHelper::Initialize"); 15 | 16 | tickCallback = new Nan::Callback(Nan::New(NoOpFunction, Nan::Null())); 17 | } 18 | 19 | // Make the no-op callback, forcing the next tick to execute 20 | void CallbackHelper::KickNextTick() 21 | { 22 | Nan::HandleScope scope; 23 | Nan::AsyncResource resource("CallbackHelper::KickNextTick"); 24 | tickCallback->Call(0, 0, &resource); 25 | } -------------------------------------------------------------------------------- /src/common/clrfuncreflectionwrap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Reflection; 4 | 5 | public class ClrFuncReflectionWrap 6 | { 7 | Object instance; 8 | MethodInfo invokeMethod; 9 | 10 | public static ClrFuncReflectionWrap Create(Assembly assembly, String typeName, String methodName) 11 | { 12 | Type startupType = assembly.GetType(typeName); 13 | 14 | if (startupType == null) 15 | { 16 | throw new TypeLoadException("Could not load type '" + typeName + "'"); 17 | } 18 | 19 | ClrFuncReflectionWrap wrap = new ClrFuncReflectionWrap(); 20 | wrap.instance = System.Activator.CreateInstance(startupType); 21 | wrap.invokeMethod = startupType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public); 22 | if (wrap.invokeMethod == null) 23 | { 24 | throw new System.InvalidOperationException( 25 | "Unable to access the CLR method to wrap through reflection. Make sure it is a public instance method."); 26 | } 27 | 28 | return wrap; 29 | } 30 | 31 | public Task Call(Object payload) 32 | { 33 | return (Task)this.invokeMethod.Invoke(this.instance, new object[] { payload }); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /src/common/edge.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(HAVE_CORECLR) && !defined(HAVE_NATIVECLR) 2 | #error "CoreCLR and/or a native .NET runtime (native .NET on Windows or Mono on Linux) must be installed in order for Edge.js to compile." 3 | #endif 4 | 5 | #include "edge_common.h" 6 | 7 | #ifdef HAVE_CORECLR 8 | #include "../CoreCLREmbedding/edge.h" 9 | #endif 10 | #ifdef HAVE_NATIVECLR 11 | #ifdef EDGE_PLATFORM_WINDOWS 12 | #include "../dotnet/edge.h" 13 | #else 14 | #include "../mono/edge.h" 15 | #endif 16 | #endif 17 | 18 | BOOL debugMode; 19 | BOOL enableScriptIgnoreAttribute; 20 | BOOL enableMarshalEnumAsInt; 21 | 22 | NAN_METHOD(initializeClrFunc) 23 | { 24 | #ifdef HAVE_NATIVECLR 25 | #ifdef HAVE_CORECLR 26 | if (HasEnvironmentVariable("EDGE_USE_CORECLR")) 27 | { 28 | CoreClrFunc::Initialize(info); 29 | } 30 | 31 | #endif 32 | ClrFunc::Initialize(info); 33 | #else 34 | CoreClrFunc::Initialize(info); 35 | #endif 36 | } 37 | 38 | #ifdef EDGE_PLATFORM_WINDOWS 39 | #pragma unmanaged 40 | #endif 41 | NAN_MODULE_INIT(init) 42 | { 43 | debugMode = HasEnvironmentVariable("EDGE_DEBUG"); 44 | DBG("edge::init"); 45 | 46 | V8SynchronizationContext::Initialize(); 47 | CallbackHelper::Initialize(); 48 | 49 | #ifdef HAVE_CORECLR 50 | if (FAILED(CoreClrEmbedding::Initialize(debugMode))) 51 | { 52 | DBG("Error occurred during CoreCLR initialization"); 53 | return; 54 | } 55 | #else 56 | #ifndef EDGE_PLATFORM_WINDOWS 57 | MonoEmbedding::Initialize(); 58 | #endif 59 | #endif 60 | 61 | enableScriptIgnoreAttribute = HasEnvironmentVariable("EDGE_ENABLE_SCRIPTIGNOREATTRIBUTE"); 62 | enableMarshalEnumAsInt = HasEnvironmentVariable("EDGE_MARSHAL_ENUM_AS_INT"); 63 | Nan::Set(target, 64 | Nan::New("initializeClrFunc").ToLocalChecked(), 65 | Nan::GetFunction(Nan::New(initializeClrFunc)).ToLocalChecked()); 66 | } 67 | 68 | #ifdef EDGE_PLATFORM_WINDOWS 69 | #pragma unmanaged 70 | #endif 71 | bool HasEnvironmentVariable(const char* variableName) 72 | { 73 | #ifdef EDGE_PLATFORM_WINDOWS 74 | return 0 < GetEnvironmentVariable(variableName, NULL, 0); 75 | #else 76 | return getenv(variableName) != NULL; 77 | #endif 78 | } 79 | 80 | #ifdef EDGE_PLATFORM_WINDOWS 81 | #pragma unmanaged 82 | #endif 83 | #ifdef HAVE_CORECLR 84 | NODE_MODULE(edge_coreclr, init); 85 | #else 86 | NODE_MODULE(edge_nativeclr, init); 87 | #endif 88 | 89 | // vim: ts=4 sw=4 et: 90 | -------------------------------------------------------------------------------- /src/common/edge_common.h: -------------------------------------------------------------------------------- 1 | #ifndef __EDGE_COMMON_H 2 | #define __EDGE_COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace v8; 13 | 14 | // From http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor 15 | #ifdef _WIN64 16 | // Windows 64 17 | #define EDGE_PLATFORM_WINDOWS 1 18 | #elif _WIN32 19 | // Windows 32 20 | #define EDGE_PLATFORM_WINDOWS 1 21 | #elif __APPLE__ 22 | // OSX 23 | #define EDGE_PLATFORM_APPLE 1 24 | #elif __linux 25 | // linux 26 | #define EDGE_PLATFORM_NIX 1 27 | #elif __unix // all unices not caught above 28 | // Unix 29 | #define EDGE_PLATFORM_NIX 1 30 | #elif __posix 31 | // POSIX 32 | #define EDGE_PLATFORM_NIX 1 33 | #endif 34 | 35 | #ifndef EDGE_PLATFORM_WINDOWS 36 | #include 37 | #include 38 | #define __cdecl 39 | #endif 40 | 41 | #ifndef EDGE_PLATFORM_WINDOWS 42 | #ifdef FALSE 43 | #undef FALSE 44 | #endif 45 | #define FALSE 0 46 | #ifdef TRUE 47 | #undef TRUE 48 | #endif 49 | #define TRUE 1 50 | typedef int BOOL; 51 | #endif 52 | 53 | #ifdef EDGE_PLATFORM_WINDOWS 54 | #define ABORT_TODO() do { printf("%s (%d): %s\n", __FILE__, __LINE__, __FUNCTION__); abort(); } while (0) 55 | #elif EDGE_PLATFORM_APPLE 56 | #define ABORT_TODO() do { printf("%s (%d): %s\n", __FILE__, __LINE__, __func__); abort(); } while (0) 57 | #else 58 | #define ABORT_TODO() do { printf("%s (%d): %s\n", __FILE__, __LINE__, __func__); exit(1); } while (0) 59 | #endif 60 | 61 | extern BOOL debugMode; 62 | extern BOOL enableScriptIgnoreAttribute; 63 | extern BOOL enableMarshalEnumAsInt; 64 | 65 | #define DBG(...) if (debugMode) { printf(__VA_ARGS__); printf("\n"); } 66 | 67 | typedef void (*uv_async_edge_cb)(void* data); 68 | 69 | typedef struct uv_edge_async_s { 70 | uv_async_t uv_async; 71 | uv_async_edge_cb action; 72 | void* data; 73 | bool singleton; 74 | } uv_edge_async_t; 75 | 76 | class V8SynchronizationContext { 77 | private: 78 | 79 | static unsigned long v8ThreadId; 80 | static unsigned long GetCurrentThreadId(); 81 | 82 | public: 83 | 84 | // The node process will not exit until ExecuteAction or CancelAction had been called for all actions 85 | // registered by calling RegisterAction on V8 thread. Actions registered by calling RegisterAction 86 | // on CLR thread do not prevent the process from exiting. 87 | // Calls from JavaScript to .NET always call RegisterAction on V8 thread before invoking .NET code. 88 | // Calls from .NET to JavaScript call RegisterAction either on CLR or V8 thread, depending on 89 | // whether .NET code executes synchronously on V8 thread it strarted running on. 90 | // This means that if any call of a .NET function from JavaScript is in progress, the process won't exit. 91 | // It also means that existence of .NET proxies to JavaScript functions in the CLR does not prevent the 92 | // process from exiting. 93 | // In this model, JavaScript owns the lifetime of the process. 94 | 95 | static uv_edge_async_t* uv_edge_async; 96 | static uv_sem_t* funcWaitHandle; 97 | 98 | static void Initialize(); 99 | static uv_edge_async_t* RegisterAction(uv_async_edge_cb action, void* data); 100 | static void ExecuteAction(uv_edge_async_t* uv_edge_async); 101 | static void CancelAction(uv_edge_async_t* uv_edge_async); 102 | static void Unref(uv_edge_async_t* uv_edge_async); 103 | }; 104 | 105 | class CallbackHelper { 106 | private: 107 | static Nan::Callback* tickCallback; 108 | 109 | public: 110 | static void Initialize(); 111 | static void KickNextTick(); 112 | }; 113 | 114 | typedef enum taskStatus 115 | { 116 | TaskStatusCreated = 0, 117 | TaskStatusWaitingForActivation = 1, 118 | TaskStatusWaitingToRun = 2, 119 | TaskStatusRunning = 3, 120 | TaskStatusWaitingForChildrenToComplete = 4, 121 | TaskStatusRanToCompletion = 5, 122 | TaskStatusCanceled = 6, 123 | TaskStatusFaulted = 7 124 | } TaskStatus; 125 | 126 | v8::Local throwV8Exception(v8::Local exception); 127 | v8::Local throwV8Exception(const char* format, ...); 128 | 129 | bool HasEnvironmentVariable(const char* variableName); 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /src/common/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "edge_common.h" 2 | 3 | v8::Local throwV8Exception(v8::Local exception) 4 | { 5 | Nan::EscapableHandleScope scope; 6 | Nan::ThrowError(exception); 7 | return scope.Escape(exception); 8 | } 9 | 10 | v8::Local throwV8Exception(const char* format, ...) 11 | { 12 | va_list args; 13 | va_start(args, format); 14 | 15 | size_t size = vsnprintf(NULL, 0, format, args); 16 | char* message = new char[size + 1]; 17 | 18 | va_start(args, format); 19 | vsnprintf(message, size + 1, format, args); 20 | 21 | Nan::EscapableHandleScope scope; 22 | 23 | v8::Local exception = Nan::New(); 24 | exception->SetPrototype(Nan::GetCurrentContext(), v8::Exception::Error(Nan::New(message).ToLocalChecked())); 25 | 26 | v8::Local exceptionValue = exception; 27 | Nan::ThrowError(exceptionValue); 28 | 29 | return scope.Escape(exception); 30 | } 31 | -------------------------------------------------------------------------------- /src/dotnet/clractioncontext.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | void ClrActionContext::ActionCallback(void* data) 4 | { 5 | ClrActionContext* context = (ClrActionContext*)data; 6 | System::Action^ action = context->action; 7 | delete context; 8 | action(); 9 | } 10 | -------------------------------------------------------------------------------- /src/dotnet/clrfuncreflectionwrap.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | ClrFuncReflectionWrap::ClrFuncReflectionWrap() 4 | { 5 | // empty 6 | } 7 | 8 | ClrFuncReflectionWrap^ ClrFuncReflectionWrap::Create( 9 | Assembly^ assembly, System::String^ typeName, System::String^ methodName) 10 | { 11 | System::Type^ startupType = assembly->GetType(typeName, true, true); 12 | ClrFuncReflectionWrap^ wrap = gcnew ClrFuncReflectionWrap(); 13 | wrap->instance = System::Activator::CreateInstance(startupType, false); 14 | wrap->invokeMethod = startupType->GetMethod(methodName, BindingFlags::Instance | BindingFlags::Public); 15 | if (wrap->invokeMethod == nullptr) 16 | { 17 | throw gcnew System::InvalidOperationException( 18 | System::String::Format("Unable to access the CLR method to wrap through reflection. Make sure it is a public instance method.\r\nType: {0}, Method: {1}, Assembly: {2}", 19 | typeName, methodName, assembly->GetName()->FullName)); 20 | } 21 | 22 | return wrap; 23 | } 24 | 25 | System::Threading::Tasks::Task^ ClrFuncReflectionWrap::Call(System::Object^ payload) 26 | { 27 | return (System::Threading::Tasks::Task^)this->invokeMethod->Invoke( 28 | this->instance, gcnew array { payload }); 29 | } 30 | -------------------------------------------------------------------------------- /src/dotnet/nodejsfunc.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Portions Copyright (c) Microsoft Corporation. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS 10 | * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 11 | * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 12 | * PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 13 | * 14 | * See the Apache Version 2.0 License for specific language governing 15 | * permissions and limitations under the License. 16 | */ 17 | #include "edge.h" 18 | 19 | NodejsFunc::NodejsFunc(v8::Local function) 20 | { 21 | DBG("NodejsFunc::NodejsFunc"); 22 | this->Func = new Nan::Persistent; 23 | this->Func->Reset(function); 24 | } 25 | 26 | NodejsFunc::~NodejsFunc() 27 | { 28 | this->!NodejsFunc(); 29 | } 30 | 31 | NodejsFunc::!NodejsFunc() 32 | { 33 | DBG("NodejsFunc::!NodejsFunc"); 34 | PersistentDisposeContext^ context = gcnew PersistentDisposeContext((Nan::Persistent*)this->Func); 35 | ClrActionContext* data = new ClrActionContext; 36 | data->action = gcnew System::Action(context, &PersistentDisposeContext::CallDisposeOnV8Thread); 37 | uv_edge_async_t* uv_edge_async = V8SynchronizationContext::RegisterAction(ClrActionContext::ActionCallback, data); 38 | V8SynchronizationContext::ExecuteAction(uv_edge_async); 39 | } 40 | 41 | System::Threading::Tasks::Task^ NodejsFunc::FunctionWrapper(System::Object^ payload) 42 | { 43 | DBG("NodejsFunc::FunctionWrapper"); 44 | NodejsFuncInvokeContext^ context = gcnew NodejsFuncInvokeContext(this, payload); 45 | ClrActionContext* data = new ClrActionContext; 46 | data->action = gcnew System::Action(context, &NodejsFuncInvokeContext::CallFuncOnV8Thread); 47 | uv_edge_async_t* uv_edge_async = V8SynchronizationContext::RegisterAction(ClrActionContext::ActionCallback, data); 48 | V8SynchronizationContext::ExecuteAction(uv_edge_async); 49 | 50 | return context->TaskCompletionSource->Task; 51 | } 52 | -------------------------------------------------------------------------------- /src/dotnet/persistentdisposecontext.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS 10 | * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 11 | * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 12 | * PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 13 | * 14 | * See the Apache Version 2.0 License for specific language governing 15 | * permissions and limitations under the License. 16 | */ 17 | #include "edge.h" 18 | 19 | PersistentDisposeContext::PersistentDisposeContext(Nan::Persistent* handle) 20 | : ptr((void*)handle) 21 | { 22 | DBG("PersistentDisposeContext::PersistentDisposeContext"); 23 | } 24 | 25 | void PersistentDisposeContext::CallDisposeOnV8Thread() { 26 | DBG("PersistentDisposeContext::CallDisposeOnV8Thread"); 27 | 28 | Nan::Persistent* handle = (Nan::Persistent*)ptr.ToPointer(); 29 | handle->Reset(); 30 | delete handle; 31 | } -------------------------------------------------------------------------------- /src/dotnet/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | v8::Local stringCLR2V8(System::String^ text) 4 | { 5 | Nan::EscapableHandleScope scope; 6 | if (text->Length > 0) 7 | { 8 | array^ utf8 = System::Text::Encoding::UTF8->GetBytes(text); 9 | pin_ptr ch = &utf8[0]; 10 | return scope.Escape(Nan::New((char*)ch, utf8->Length).ToLocalChecked()); 11 | } 12 | else 13 | { 14 | return scope.Escape(Nan::New("").ToLocalChecked()); 15 | } 16 | } 17 | 18 | System::String^ stringV82CLR(v8::Local text) 19 | { 20 | Nan::HandleScope scope; 21 | Nan::Utf8String utf8text(text); 22 | if (*utf8text) 23 | { 24 | return gcnew System::String( 25 | *utf8text, 0, utf8text.length(), System::Text::Encoding::UTF8); 26 | } 27 | else 28 | { 29 | return System::String::Empty; 30 | } 31 | } 32 | 33 | System::String^ stringV82CLR(Nan::Utf8String& utf8text) 34 | { 35 | Nan::HandleScope scope; 36 | if (*utf8text) 37 | { 38 | return gcnew System::String( 39 | *utf8text, 0, utf8text.length(), System::Text::Encoding::UTF8); 40 | } 41 | else 42 | { 43 | return System::String::Empty; 44 | } 45 | } 46 | System::String^ exceptionV82stringCLR(v8::Local exception) 47 | { 48 | v8::Isolate *isolate = v8::Isolate::GetCurrent(); 49 | v8::Local context = isolate->GetCurrentContext(); 50 | Nan::HandleScope scope; 51 | if (exception->IsObject()) 52 | { 53 | v8::Local stack = exception->ToObject(context).ToLocalChecked()->Get(Nan::GetCurrentContext(), Nan::New("stack").ToLocalChecked()).ToLocalChecked(); 54 | if (stack->IsString()) 55 | { 56 | return gcnew System::String(stringV82CLR(stack->ToString(context).ToLocalChecked())); 57 | } 58 | } 59 | 60 | return gcnew System::String(stringV82CLR(v8::Local::Cast(exception))); 61 | } 62 | -------------------------------------------------------------------------------- /src/double/Edge.js.CSharp/Edge.js.CSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Edge.js enables scripting CLR languages from Node.js. This package is a dependency of Edge.js and supports scripting C# from Node. 4 | C# compiler for Edge.js 5 | 1.2.0 6 | net5.0 7 | Edge.js.CSharp 8 | Edge.js.CSharp 9 | https://github.com/tjanczuk/edge 10 | https://github.com/tjanczuk/edge-cs/blob/master/LICENSE.txt 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/double/Edge.js/Edge.js.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | With Edge.js you can script Node.js in a .NET application. Edge.js allows you to run Node.js and .NET code in one process. You can call Node.js functions from .NET and .NET functions from Node.js. Edge.js takes care of marshalling data between CLR and V8. Edge.js also reconciles threading models of single threaded V8 and multi-threaded CLR. Edge.js ensures correct lifetime of objects on V8 and CLR heaps. This Edge.js NuGet package supports scripting Node.js v6.5.0. 4 | Copyright 2015 Tomasz Janczuk 5 | 9.3.0 6 | net5.0 7 | EdgeJs 8 | Edge.js 9 | node.js;node;.net;edge;edge.js;v8;clr;coreclr;mono;interop;javascript 10 | https://raw.githubusercontent.com/neo-one-suite/edge/master/LICENSE 11 | false 12 | 13 | 14 | 15 | content/edge/x64/ 16 | true 17 | 18 | 19 | content/edge/x86/ 20 | true 21 | 22 | 23 | content/edge/ 24 | true 25 | 26 | 27 | tools/ 28 | true 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | true 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/double/Edge.js/dotnetcore/nodejsfunc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Runtime.CompilerServices; 4 | 5 | public class NodejsFunc 6 | { 7 | public IntPtr Context 8 | { 9 | get; 10 | private set; 11 | } 12 | 13 | public NodejsFunc(IntPtr context) 14 | { 15 | Context = context; 16 | } 17 | 18 | ~NodejsFunc() 19 | { 20 | // TODO: implement release 21 | } 22 | 23 | public Func> GetFunc() 24 | { 25 | return new Func>(FunctionWrapper); 26 | } 27 | 28 | private Task FunctionWrapper(object payload) 29 | { 30 | CoreCLREmbedding.DebugMessage("NodejsFunc::FunctionWrapper (CLR) - Started"); 31 | 32 | NodejsFuncInvokeContext invokeContext = new NodejsFuncInvokeContext(this, payload); 33 | invokeContext.CallFunc(); 34 | 35 | CoreCLREmbedding.DebugMessage("NodejsFunc::FunctionWrapper (CLR) - Node.js function invoked on the V8 thread, returning the task completion source"); 36 | 37 | return invokeContext.TaskCompletionSource.Task; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/double/Edge.js/dotnetcore/nodejsfuncinvokecontext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | public delegate void NodejsFuncCompleteDelegate(IntPtr context, int taskStatus, IntPtr result, int resultType); 7 | 8 | public class NodejsFuncInvokeContext 9 | { 10 | private NodejsFunc functionContext; 11 | private object payload; 12 | private static IntPtr NodejsFuncCompleteCallback; 13 | private static NodejsFuncCompleteDelegate NodeJsFuncCompleteInstance; 14 | 15 | static NodejsFuncInvokeContext() 16 | { 17 | NodeJsFuncCompleteInstance = new NodejsFuncCompleteDelegate(NodejsFuncComplete); 18 | NodejsFuncCompleteCallback = Marshal.GetFunctionPointerForDelegate(NodeJsFuncCompleteInstance); 19 | } 20 | 21 | internal static CallV8FunctionDelegate CallV8Function 22 | { 23 | get; 24 | set; 25 | } 26 | 27 | public TaskCompletionSource TaskCompletionSource 28 | { 29 | get; 30 | private set; 31 | } 32 | 33 | public NodejsFuncInvokeContext(NodejsFunc functionContext, object payload) 34 | { 35 | this.functionContext = functionContext; 36 | this.payload = payload; 37 | this.TaskCompletionSource = new TaskCompletionSource(); 38 | } 39 | 40 | internal void CallFunc() 41 | { 42 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::CallFunc (CLR) - Starting"); 43 | 44 | V8Type v8PayloadType; 45 | IntPtr v8Payload = CoreCLREmbedding.MarshalCLRToV8(payload, out v8PayloadType); 46 | 47 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::CallFunc (CLR) - Marshalled payload data for V8"); 48 | 49 | IntPtr callbackContext = GCHandle.ToIntPtr(GCHandle.Alloc(this)); 50 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::CallFunc (CLR) - Getting a GCHandle for this context object"); 51 | 52 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::CallFunc (CLR) - Invoking the unmanaged V8 function to invoke the Node.js function on the V8 thread"); 53 | CallV8Function(v8Payload, (int)v8PayloadType, functionContext.Context, callbackContext, NodejsFuncCompleteCallback); 54 | } 55 | 56 | public static void NodejsFuncComplete(IntPtr context, int taskStatus, IntPtr result, int resultType) 57 | { 58 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Starting"); 59 | 60 | GCHandle gcHandle = GCHandle.FromIntPtr(context); 61 | NodejsFuncInvokeContext actualContext = (NodejsFuncInvokeContext)gcHandle.Target; 62 | 63 | gcHandle.Free(); 64 | 65 | V8Type v8ResultType = (V8Type)resultType; 66 | object marshalledResult = CoreCLREmbedding.MarshalV8ToCLR(result, v8ResultType); 67 | 68 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Marshalled result data back to the CLR"); 69 | 70 | if (taskStatus == (int)TaskStatus.Faulted) 71 | { 72 | actualContext.TaskCompletionSource.SetException((Exception)marshalledResult); 73 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Set the exception received from Node.js: {0}", ((Exception)marshalledResult).Message); 74 | } 75 | 76 | else 77 | { 78 | actualContext.TaskCompletionSource.SetResult(marshalledResult); 79 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Set result data"); 80 | } 81 | 82 | CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Finished"); 83 | } 84 | } -------------------------------------------------------------------------------- /src/mono/clractioncontext.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | void ClrActionContext::ActionCallback(void* data) 4 | { 5 | static MonoMethod* actionInvoke; 6 | if (!actionInvoke) 7 | { 8 | MonoClass* actionClass = mono_class_from_name(mono_get_corlib(), "System", "Action"); 9 | actionInvoke = mono_class_get_method_from_name(actionClass, "Invoke", -1); 10 | } 11 | 12 | ClrActionContext* context = (ClrActionContext*)data; 13 | MonoObject* action = mono_gchandle_get_target(context->action); 14 | MonoException* exc = NULL; 15 | mono_runtime_invoke(actionInvoke, action, NULL, (MonoObject**)&exc); 16 | mono_gchandle_free(context->action); 17 | delete context; 18 | if (exc) 19 | ABORT_TODO(); 20 | } 21 | -------------------------------------------------------------------------------- /src/mono/clrfuncinvokecontext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Runtime.CompilerServices; 4 | 5 | class ClrFuncInvokeContext 6 | { 7 | #pragma warning disable 649 // assigned from clrfuncinvokecontext.cpp through embedding APIs 8 | IntPtr native; 9 | #pragma warning disable 169 // assigned from clrfuncinvokecontext.cpp through embedding APIs 10 | Object Payload; 11 | Task Task; 12 | bool Sync; 13 | #pragma warning restore 169 14 | #pragma warning restore 649 15 | 16 | [MethodImplAttribute(MethodImplOptions.InternalCall)] 17 | static extern void CompleteOnCLRThreadICall(IntPtr ptr, Task task); 18 | 19 | internal void CompleteOnCLRThread(Task task) 20 | { 21 | CompleteOnCLRThreadICall(native, task); 22 | } 23 | 24 | [MethodImplAttribute(MethodImplOptions.InternalCall)] 25 | static extern void CompleteOnV8ThreadAsynchronousICall(IntPtr ptr); 26 | 27 | void CompleteOnV8ThreadAsynchronous() 28 | { 29 | CompleteOnV8ThreadAsynchronousICall(native); 30 | } 31 | 32 | public Action GetCompleteOnV8ThreadAsynchronousAction() 33 | { 34 | return new Action(CompleteOnV8ThreadAsynchronous); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /src/mono/dictionary.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | //void Dictionary::Add(MonoObject* _this, const char* name, MonoObject* value) 4 | //{ 5 | // static MonoMethod* add; 6 | // 7 | // if(!add) { 8 | // add = mono_class_get_method_from_name(mono_object_get_class(_this), 9 | // "System.Collections.Generic.IDictionary.Add", -1); 10 | // } 11 | // 12 | // void* params[2]; 13 | // params[0] = mono_string_new(mono_domain_get(), name); 14 | // params[1] = value; 15 | // 16 | // mono_runtime_invoke(add, _this, params, NULL); 17 | //} 18 | 19 | void Dictionary::Add(MonoObject* _this, const char* name, MonoObject* value) 20 | { 21 | static MonoMethod* add; 22 | 23 | if(!add) { 24 | add = mono_class_get_method_from_name(MonoEmbedding::GetClass(), "AddPropertyToObject", -1); 25 | } 26 | 27 | void* params[3]; 28 | params[0] = _this; //dict 29 | params[1] = mono_string_new(mono_domain_get(), name); // key 30 | params[2] = value; // value 31 | 32 | mono_runtime_invoke(add, _this, params, NULL); 33 | } 34 | -------------------------------------------------------------------------------- /src/mono/nodejsfunc.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | static MonoClass* GetNodejsFuncClass() 4 | { 5 | static MonoClass* klass; 6 | 7 | if (!klass) 8 | klass = mono_class_from_name(MonoEmbedding::GetImage(), "", "NodejsFunc"); 9 | 10 | return klass; 11 | } 12 | 13 | NodejsFunc::NodejsFunc(v8::Local function) 14 | { 15 | DBG("NodejsFunc::NodejsFunc"); 16 | 17 | static MonoMethod* ctor; 18 | if (!ctor) 19 | ctor = mono_class_get_method_from_name(GetNodejsFuncClass(), ".ctor", -1); 20 | 21 | this->Func = new Nan::Persistent; 22 | (this->Func)->Reset(function); 23 | 24 | MonoObject* thisObj = mono_object_new(mono_domain_get(), GetNodejsFuncClass()); 25 | MonoException* exc = NULL; 26 | void *thisPtr = this; 27 | void *args[] = { &thisPtr }; 28 | mono_runtime_invoke(ctor, thisObj, args, (MonoObject**)&exc); 29 | _this = mono_gchandle_new_weakref(thisObj, FALSE); 30 | } 31 | 32 | NodejsFunc::~NodejsFunc() 33 | { 34 | DBG("NodejsFunc::~NodejsFunc"); 35 | this->Func->Reset(); 36 | delete this->Func; 37 | this->Func = NULL; 38 | } 39 | 40 | void NodejsFunc::Release(NodejsFunc* _this) 41 | { 42 | delete _this; 43 | } 44 | 45 | MonoObject* NodejsFunc::GetFunc() 46 | { 47 | static MonoMethod* method; 48 | 49 | if (!method) 50 | method = mono_class_get_method_from_name(GetNodejsFuncClass(), "GetFunc", -1); 51 | 52 | MonoException* exc = NULL; 53 | MonoObject* func = mono_runtime_invoke(method, mono_gchandle_get_target(_this), NULL, (MonoObject**)&exc); 54 | 55 | return func; 56 | } 57 | 58 | void NodejsFunc::ExecuteActionOnV8Thread(MonoObject* action) 59 | { 60 | ClrActionContext* data = new ClrActionContext; 61 | data->action = mono_gchandle_new(action, FALSE); // released in ClrActionContext::ActionCallback 62 | uv_edge_async_t* uv_edge_async = V8SynchronizationContext::RegisterAction(ClrActionContext::ActionCallback, data); 63 | V8SynchronizationContext::ExecuteAction(uv_edge_async); 64 | } 65 | -------------------------------------------------------------------------------- /src/mono/nodejsfunc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Runtime.CompilerServices; 4 | 5 | class NodejsFunc 6 | { 7 | public IntPtr NativeNodejsFunc { get; set; } 8 | 9 | public NodejsFunc(IntPtr native) 10 | { 11 | this.NativeNodejsFunc = native; 12 | } 13 | 14 | ~NodejsFunc() 15 | { 16 | IntPtr native = this.NativeNodejsFunc; 17 | ExecuteActionOnV8Thread(() => { 18 | Release(native); 19 | }); 20 | } 21 | 22 | [MethodImplAttribute(MethodImplOptions.InternalCall)] 23 | static extern void Release(IntPtr nativeNodejsFunc); 24 | 25 | Func> GetFunc() 26 | { 27 | return new Func>(this.FunctionWrapper); 28 | } 29 | 30 | Task FunctionWrapper(object payload) 31 | { 32 | NodejsFuncInvokeContext ctx = new NodejsFuncInvokeContext(this, payload); 33 | ExecuteActionOnV8Thread(ctx.CallFuncOnV8Thread); 34 | 35 | return ctx.TaskCompletionSource.Task; 36 | } 37 | 38 | [MethodImplAttribute(MethodImplOptions.InternalCall)] 39 | static extern void ExecuteActionOnV8Thread(Action action); 40 | }; 41 | -------------------------------------------------------------------------------- /src/mono/nodejsfuncinvokecontext.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | NAN_METHOD(v8FuncCallback) 4 | { 5 | DBG("v8FuncCallback"); 6 | Nan::HandleScope scope; 7 | v8::Local correlator = v8::Local::Cast(info[2]); 8 | NodejsFuncInvokeContext* context = (NodejsFuncInvokeContext*)(correlator->Value()); 9 | if (!info[0]->IsUndefined() && !info[0]->IsNull()) 10 | { 11 | context->Complete((MonoObject*)exceptionV82stringCLR(info[0]), NULL); 12 | } 13 | else 14 | { 15 | // TODO add support for exceptions during marshaling: 16 | MonoObject* result = ClrFunc::MarshalV8ToCLR(info[1]); 17 | context->Complete(NULL, result); 18 | } 19 | info.GetReturnValue().SetUndefined(); 20 | } 21 | 22 | 23 | NodejsFuncInvokeContext::NodejsFuncInvokeContext(MonoObject* _this) 24 | { 25 | DBG("NodejsFuncInvokeContext::NodejsFuncInvokeContext"); 26 | 27 | this->_this = mono_gchandle_new(_this, FALSE); // released in Complete 28 | } 29 | 30 | NodejsFuncInvokeContext::~NodejsFuncInvokeContext() 31 | { 32 | mono_gchandle_free(this->_this); 33 | } 34 | 35 | void NodejsFuncInvokeContext::CallFuncOnV8Thread(MonoObject* _this, NodejsFunc* nativeNodejsFunc, MonoObject* payload) 36 | { 37 | DBG("NodejsFuncInvokeContext::CallFuncOnV8Thread"); 38 | 39 | static Nan::Persistent callbackFactory; 40 | static Nan::Persistent callbackFunction; 41 | v8::Isolate *isolate = v8::Isolate::GetCurrent(); 42 | v8::Local context = isolate->GetCurrentContext(); 43 | 44 | Nan::HandleScope scope; 45 | NodejsFuncInvokeContext* ctx = new NodejsFuncInvokeContext(_this); 46 | 47 | MonoException* exc = NULL; 48 | v8::Local jspayload = ClrFunc::MarshalCLRToV8(payload, &exc); 49 | if (exc) 50 | { 51 | ctx->Complete((MonoObject*)exc, NULL); 52 | // ctx deleted in Complete 53 | } 54 | else 55 | { 56 | // See https://github.com/tjanczuk/edge/issues/125 for context 57 | 58 | if (callbackFactory.IsEmpty()) 59 | { 60 | v8::Local v8FuncCallbackFunction = Nan::GetFunction(Nan::New(v8FuncCallback)).ToLocalChecked(); 61 | callbackFunction.Reset(v8FuncCallbackFunction); 62 | v8::Local code = Nan::New( 63 | "(function (cb, ctx) { return function (e, d) { return cb(e, d, ctx); }; })").ToLocalChecked(); 64 | v8::Local callbackFactoryFunction = 65 | v8::Local::Cast( 66 | v8::Script::Compile(context, code, nullptr).ToLocalChecked() 67 | ->Run(context).ToLocalChecked()); 68 | callbackFactory.Reset(callbackFactoryFunction); 69 | } 70 | 71 | v8::Local factoryArgv[] = { Nan::New(callbackFunction), Nan::New((void*)ctx) }; 72 | v8::Local callback = v8::Local::Cast( 73 | Nan::Call(Nan::New(callbackFactory), Nan::GetCurrentContext()->Global(), 2, factoryArgv).ToLocalChecked()); 74 | 75 | v8::Local argv[] = { jspayload, callback }; 76 | Nan::TryCatch tryCatch; 77 | DBG("NodejsFuncInvokeContext::CallFuncOnV8Thread calling JavaScript function"); 78 | Nan::Call(Nan::New(*(nativeNodejsFunc->Func)), Nan::GetCurrentContext()->Global(), 2, argv); 79 | DBG("NodejsFuncInvokeContext::CallFuncOnV8Thread called JavaScript function"); 80 | if (tryCatch.HasCaught()) 81 | { 82 | DBG("NodejsFuncInvokeContext::CallFuncOnV8Thread caught JavaScript exception"); 83 | ctx->Complete((MonoObject*)exceptionV82stringCLR(tryCatch.Exception()), NULL); 84 | // ctx deleted in Complete 85 | } 86 | else 87 | { 88 | // Kick the next tick 89 | CallbackHelper::KickNextTick(); 90 | } 91 | 92 | // In the absence of exception, processing resumes in v8FuncCallback 93 | } 94 | } 95 | 96 | void NodejsFuncInvokeContext::Complete(MonoObject* exception, MonoObject* result) 97 | { 98 | DBG("NodejsFuncInvokeContext::Complete"); 99 | 100 | static MonoMethod* method; 101 | 102 | if (!method) 103 | { 104 | MonoClass* klass = mono_class_from_name(MonoEmbedding::GetImage(), "", "NodejsFuncInvokeContext"); 105 | method = mono_class_get_method_from_name(klass, "Complete", 2); 106 | } 107 | 108 | void* args[] = { exception, result }; 109 | mono_runtime_invoke(method, mono_gchandle_get_target(this->_this), args, NULL); 110 | delete this; 111 | } 112 | 113 | // vim: ts=4 sw=4 et: 114 | -------------------------------------------------------------------------------- /src/mono/nodejsfuncinvokecontext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Runtime.CompilerServices; 4 | 5 | class NodejsFuncInvokeContext { 6 | NodejsFunc functionContext; 7 | object payload; 8 | 9 | public TaskCompletionSource TaskCompletionSource { get; set; } 10 | 11 | public NodejsFuncInvokeContext(NodejsFunc functionContext, object payload) 12 | { 13 | this.functionContext = functionContext; 14 | this.payload = payload; 15 | this.TaskCompletionSource = new TaskCompletionSource(); 16 | } 17 | 18 | public void CallFuncOnV8Thread() 19 | { 20 | // This function must run on V8 thread 21 | CallFuncOnV8ThreadInternal( 22 | this, this.functionContext.NativeNodejsFunc, this.payload); 23 | } 24 | 25 | [MethodImplAttribute(MethodImplOptions.InternalCall)] 26 | static extern void CallFuncOnV8ThreadInternal(NodejsFuncInvokeContext _this, IntPtr nativeNodejsFunc, object payload); 27 | 28 | public void Complete(object exception, object result) 29 | { 30 | Task.Run(() => { 31 | if (exception != null) 32 | { 33 | var e = exception as Exception; 34 | var s = exception as string; 35 | if (e != null) 36 | { 37 | this.TaskCompletionSource.SetException(e); 38 | } 39 | else if (!string.IsNullOrEmpty(s)) 40 | { 41 | this.TaskCompletionSource.SetException(new Exception(s)); 42 | } 43 | else 44 | { 45 | this.TaskCompletionSource.SetException( 46 | new InvalidOperationException("Unrecognized exception received from JavaScript.")); 47 | } 48 | } 49 | else 50 | { 51 | this.TaskCompletionSource.SetResult(result); 52 | } 53 | }); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /src/mono/task.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | TaskStatus SystemThreading::Task::Status(MonoObject* _this) 4 | { 5 | MonoProperty* prop = mono_class_get_property_from_name(mono_object_get_class(_this), "Status"); 6 | MonoObject* statusBoxed = mono_property_get_value(prop, _this, NULL, NULL); 7 | TaskStatus status = *(TaskStatus*)mono_object_unbox(statusBoxed); 8 | return status; 9 | } 10 | 11 | MonoException* SystemThreading::Task::Exception(MonoObject* _this) 12 | { 13 | MonoProperty* prop = mono_class_get_property_from_name(mono_object_get_class(_this), "Exception"); 14 | MonoObject* exception = mono_property_get_value(prop, _this, NULL, NULL); 15 | return (MonoException*)exception; 16 | } 17 | 18 | MonoObject* SystemThreading::Task::Result(MonoObject* _this) 19 | { 20 | MonoProperty* prop = mono_class_get_property_from_name(mono_object_get_class(_this), "Result"); 21 | MonoObject* result = mono_property_get_value(prop, _this, NULL, NULL); 22 | return result; 23 | } 24 | -------------------------------------------------------------------------------- /src/mono/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | v8::Local stringCLR2V8(MonoString* text) 4 | { 5 | Nan::EscapableHandleScope scope; 6 | return scope.Escape(Nan::New( 7 | mono_string_chars(text), 8 | mono_string_length(text)).ToLocalChecked()); 9 | } 10 | 11 | MonoString* stringV82CLR(v8::Local text) 12 | { 13 | Nan::HandleScope scope; 14 | Nan::Utf8String utf8text(text); 15 | return mono_string_new(mono_domain_get(), *utf8text); 16 | } 17 | 18 | MonoString* exceptionV82stringCLR(v8::Local exception) 19 | { 20 | v8::Isolate *isolate = v8::Isolate::GetCurrent(); 21 | v8::Local context = isolate->GetCurrentContext(); 22 | Nan::HandleScope scope; 23 | if (exception->IsObject()) 24 | { 25 | v8::Local stack = exception->ToObject(Nan::GetCurrentContext()).ToLocalChecked()->Get(Nan::GetCurrentContext(), Nan::New("stack").ToLocalChecked()).ToLocalChecked(); 26 | if (stack->IsString()) 27 | { 28 | return stringV82CLR(stack->ToString(context).ToLocalChecked()); 29 | } 30 | } 31 | 32 | return stringV82CLR(v8::Local::Cast(exception)); 33 | } 34 | -------------------------------------------------------------------------------- /test/101_edge_func.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge.js'), assert = require('assert') 2 | , path = require('path'); 3 | 4 | var edgeTestDll = process.env.EDGE_USE_CORECLR ? 'test' : path.join(__dirname, 'Edge.Tests.dll'); 5 | var prefix = process.env.EDGE_USE_CORECLR ? '[CoreCLR]' : process.platform === 'win32' ? '[.NET]' : '[Mono]'; 6 | 7 | describe('edge.func', function () { 8 | 9 | it(prefix + ' exists', function () { 10 | assert.equal(typeof edge.func, 'function'); 11 | }); 12 | 13 | it(prefix + ' fails without parameters', function () { 14 | assert.throws( 15 | edge.func, 16 | /Specify the source code as string or provide an options object/ 17 | ); 18 | }); 19 | 20 | it(prefix + ' fails with a wrong parameter', function () { 21 | assert.throws( 22 | function () { edge.func(12); }, 23 | /Specify the source code as string or provide an options object/ 24 | ); 25 | }); 26 | 27 | it(prefix + ' fails with a wrong language parameter', function () { 28 | assert.throws( 29 | function () { edge.func(12, 'somescript'); }, 30 | /The first argument must be a string identifying the language compiler to use/ 31 | ); 32 | }); 33 | 34 | it(prefix + ' fails with a unsupported language parameter', function () { 35 | assert.throws( 36 | function () { edge.func('idontexist', 'somescript'); }, 37 | /Unsupported language 'idontexist'/ 38 | ); 39 | }); 40 | 41 | it(prefix + ' fails with missing assemblyFile or source', function () { 42 | assert.throws( 43 | function () { edge.func({}); }, 44 | /Provide DLL or source file name or .NET script literal as a string parmeter, or specify an options object/ 45 | ); 46 | }); 47 | 48 | it(prefix + ' fails with both assemblyFile or source', function () { 49 | assert.throws( 50 | function () { edge.func({ assemblyFile: 'foo.dll', source: 'async (input) => { return null; }'}); }, 51 | /Provide either an asseblyFile or source property, but not both/ 52 | ); 53 | }); 54 | 55 | it(prefix + ' fails with nonexisting assemblyFile', function () { 56 | assert.throws( 57 | function () { edge.func('idontexist.dll'); }, 58 | /System.IO.FileNotFoundException/ 59 | ); 60 | }); 61 | 62 | if (!process.env.EDGE_USE_CORECLR) { 63 | it(prefix + ' succeeds with assemblyFile as string', function () { 64 | var func = edge.func(edgeTestDll); 65 | assert.equal(typeof func, 'function'); 66 | }); 67 | 68 | it(prefix + ' succeeds with assemblyFile as options property', function () { 69 | var func = edge.func({ assemblyFile: edgeTestDll }); 70 | assert.equal(typeof func, 'function'); 71 | }); 72 | } 73 | 74 | it(prefix + ' succeeds with assemblyFile and type name', function () { 75 | var func = edge.func({ 76 | assemblyFile: edgeTestDll, 77 | typeName: 'Edge.Tests.Startup' 78 | }); 79 | assert.equal(typeof func, 'function'); 80 | }); 81 | 82 | it(prefix + ' fails with assemblyFile and nonexisting type name', function () { 83 | assert.throws( 84 | function () { 85 | edge.func({ 86 | assemblyFile: edgeTestDll, 87 | typeName: 'Edge.Tests.idontexist' 88 | }); 89 | }, 90 | /Could not load type 'Edge.Tests.idontexist'/ 91 | ); 92 | }); 93 | 94 | it(prefix + ' succeeds with assemblyFile, type name, and method name', function () { 95 | var func = edge.func({ 96 | assemblyFile: edgeTestDll, 97 | typeName: 'Edge.Tests.Startup', 98 | methodName: 'Invoke' 99 | }); 100 | assert.equal(typeof func, 'function'); 101 | }); 102 | 103 | it(prefix + ' fails with assemblyFile, type name and nonexisting method name', function () { 104 | assert.throws( 105 | function () { 106 | edge.func({ 107 | assemblyFile: edgeTestDll, 108 | typeName: 'Edge.Tests.Startup', 109 | methodName: 'idontexist' 110 | }); 111 | }, 112 | /Unable to access the CLR method to wrap through reflection/ 113 | ); 114 | }); 115 | }); -------------------------------------------------------------------------------- /test/105_node2net_sync.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge.js'), assert = require('assert') 2 | , path = require('path'); 3 | 4 | var edgeTestDll = process.env.EDGE_USE_CORECLR ? 'test' : path.join(__dirname, 'Edge.Tests.dll'); 5 | var prefix = process.env.EDGE_USE_CORECLR ? '[CoreCLR]' : process.platform === 'win32' ? '[.NET]' : '[Mono]'; 6 | 7 | describe('sync call from node.js to .net', function () { 8 | 9 | it(prefix + ' succeeds for hello world', function () { 10 | var func = edge.func({ 11 | assemblyFile: edgeTestDll, 12 | typeName: 'Edge.Tests.Startup', 13 | methodName: 'Invoke' 14 | }); 15 | var result = func('Node.js', true); 16 | assert.equal(result, '.NET welcomes Node.js'); 17 | }); 18 | 19 | it(prefix + ' succeeds for hello world when called sync and async', function (done) { 20 | // create the func 21 | var func = edge.func({ 22 | assemblyFile: edgeTestDll, 23 | typeName: 'Edge.Tests.Startup', 24 | methodName: 'Invoke' 25 | }); 26 | 27 | // call the func synchronously 28 | var result = func('Node.js', true); 29 | assert.equal(result, '.NET welcomes Node.js'); 30 | 31 | // call the same func asynchronously 32 | func('Node.js', function (error, result) { 33 | assert.ifError(error); 34 | assert.equal(result, '.NET welcomes Node.js'); 35 | done(); 36 | }); 37 | }); 38 | 39 | it(prefix + ' successfuly marshals data from node.js to .net', function () { 40 | var func = edge.func({ 41 | assemblyFile: edgeTestDll, 42 | typeName: 'Edge.Tests.Startup', 43 | methodName: 'MarshalIn' 44 | }); 45 | var payload = { 46 | a: 1, 47 | b: 3.1415, 48 | c: 'fooåäö', 49 | d: true, 50 | e: false, 51 | f: new Buffer(10), 52 | g: [ 1, 'fooåäö' ], 53 | h: { a: 'fooåäö', b: 12 }, 54 | i: function (payload, callback) { }, 55 | j: new Date(Date.UTC(2013,07,30)) 56 | }; 57 | var result = func(payload, true); 58 | assert.equal(result, 'yes'); 59 | }); 60 | 61 | it(prefix + ' successfuly marshals .net exception thrown on v8 thread from .net to node.js', function () { 62 | var func = edge.func({ 63 | assemblyFile: edgeTestDll, 64 | typeName: 'Edge.Tests.Startup', 65 | methodName: 'NetExceptionTaskStart' 66 | }); 67 | assert.throws( 68 | function() { func(null, true); }, 69 | function (error) { 70 | if ((error instanceof Error) && error.Message.match(/Test .NET exception/)) { 71 | return true; 72 | } 73 | return false; 74 | }, 75 | 'Unexpected result' 76 | ); 77 | }); 78 | 79 | it(prefix + ' fails if C# method does not complete synchronously', function () { 80 | var func = edge.func({ 81 | assemblyFile: edgeTestDll, 82 | typeName: 'Edge.Tests.Startup', 83 | methodName: 'DelayedReturn' 84 | }); 85 | assert.throws( 86 | function() { func(null, true); }, 87 | / The JavaScript function was called synchronously but/ 88 | ); 89 | }); 90 | }); -------------------------------------------------------------------------------- /test/202_serialization.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge.js'), assert = require('assert'), path = require('path'); 2 | 3 | var prefix = process.env.EDGE_USE_CORECLR ? '[CoreCLR]' : process.platform === 'win32' ? '[.NET]' : '[Mono]'; 4 | 5 | describe('serialization', function () { 6 | 7 | if (!process.env.EDGE_USE_CORECLR) { 8 | it(prefix + ' complex exception serialization', function (done) { 9 | var func = edge.func({ 10 | source: function () {/* 11 | #r "System.Data.dll" 12 | 13 | using System.Data; 14 | using System.Data.SqlClient; 15 | 16 | async (input) => 17 | { 18 | 19 | using (SqlConnection connection = new SqlConnection("Data Source=my_localhost;Initial Catalog=catalog;Integrated Security=True;Connection Timeout=1")) 20 | { 21 | connection.Open(); 22 | } 23 | return input.ToString(); 24 | 25 | } 26 | */ 27 | } 28 | }); 29 | func("JavaScript", function (error, result) { 30 | var exception = error.toString(); 31 | var contains = exception.indexOf('A network-related or instance-specific error occurred while establishing a connection to SQL Server') !== -1 32 | || exception.indexOf('Server does not exist or connection refused') !== -1 33 | || exception.indexOf('System.Data.SqlClient.SqlException') !== -1; 34 | assert.ok(contains); 35 | 36 | done(); 37 | }); 38 | }); 39 | } 40 | 41 | }); -------------------------------------------------------------------------------- /test/build.bat: -------------------------------------------------------------------------------- 1 | set SELF=%~dp0 2 | ver > nul 3 | 4 | IF "%EDGE_USE_CORECLR%"=="1" ( 5 | cmd /c "cd ""%SELF%"" && dotnet restore -f ..\tools\build\nuget -f ..\..\edge-cs\src\Edge.js.CSharp\bin\Release && dotnet build" 6 | 7 | IF %ERRORLEVEL% NEQ 0 ( 8 | ECHO Test restore failed 9 | EXIT /b -1 10 | ) 11 | ) ELSE ( 12 | csc /target:library /debug /out:"%SELF%\Edge.Tests.dll" "%SELF%\tests.cs" 13 | 14 | IF %ERRORLEVEL% NEQ 0 ( 15 | ECHO Test build failed 16 | EXIT /b -1 17 | ) 18 | ) -------------------------------------------------------------------------------- /test/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$(which dotnet 2>/dev/null)" ] 4 | then 5 | dotnet restore 6 | dotnet build 7 | cp bin/Debug/net5.0/test.dll Edge.Tests.CoreClr.dll 8 | fi 9 | 10 | if [ -n "$(which mono 2>/dev/null)" ] 11 | then 12 | mcs /target:library /debug /out:Edge.Tests.dll tests.cs 13 | fi 14 | -------------------------------------------------------------------------------- /test/double/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | packages/ 3 | edge/ 4 | TestResults/ -------------------------------------------------------------------------------- /test/double/double_stress/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/double/double_stress/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("double_stress")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("double_stress")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("806b8070-743b-46f3-8178-5c1acd7badaf")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/double/double_stress/double_stress.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {51C38DFE-9FC5-4A14-A046-1F6EA3910904} 8 | Exe 9 | Properties 10 | double_stress 11 | double_stress 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | packages\Edge.js.7.10.1\lib\net40\EdgeJs.dll 37 | True 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | PreserveNewest 55 | 56 | 57 | PreserveNewest 58 | 59 | 60 | 61 | 62 | 63 | PreserveNewest 64 | 65 | 66 | PreserveNewest 67 | 68 | 69 | PreserveNewest 70 | 71 | 72 | PreserveNewest 73 | 74 | 75 | 76 | 83 | -------------------------------------------------------------------------------- /test/double/double_stress/double_stress.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "double_stress", "double_stress.csproj", "{51C38DFE-9FC5-4A14-A046-1F6EA3910904}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {51C38DFE-9FC5-4A14-A046-1F6EA3910904}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {51C38DFE-9FC5-4A14-A046-1F6EA3910904}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {51C38DFE-9FC5-4A14-A046-1F6EA3910904}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {51C38DFE-9FC5-4A14-A046-1F6EA3910904}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /test/double/double_stress/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /test/double/double_test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("double_test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("double_test")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("787ea5a0-e995-417f-92d2-ae117b05ac40")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/double/double_test/double_test.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "double_test", "double_test.csproj", "{721FC9B2-4747-48E7-B57D-1084FCE6D7D3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {721FC9B2-4747-48E7-B57D-1084FCE6D7D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {721FC9B2-4747-48E7-B57D-1084FCE6D7D3}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {721FC9B2-4747-48E7-B57D-1084FCE6D7D3}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {721FC9B2-4747-48E7-B57D-1084FCE6D7D3}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /test/double/double_test/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /test/hello_class.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | public class Startup 5 | { 6 | public async Task Invoke(object input) 7 | { 8 | return "Hello, " + input.ToString(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/hello_class.csx: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | public class Startup 5 | { 6 | public async Task Invoke(object input) 7 | { 8 | return "Hello, " + input.ToString(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/hello_lambda.csx: -------------------------------------------------------------------------------- 1 | async (input) => { return "Hello, " + input.ToString(); } 2 | -------------------------------------------------------------------------------- /test/test.bat: -------------------------------------------------------------------------------- 1 | rem usage: test.bat [ia32|x64 {version}], e.g. test.bat x64 0.10.0 2 | @echo off 3 | set EDGE_APP_ROOT=%~dp0\bin\Debug\net5.0 4 | set NODEEXE=node.exe 5 | set EDGE_USE_CORECLR= 6 | if "%1" neq "" if "%2" neq "" set NODEEXE=%~dp0\..\lib\native\win32\%1\%2\node.exe 7 | echo Using node.js: %NODEEXE% 8 | rmdir /s /q "%~dp0/bin" 9 | rmdir /s /q "%~dp0/obj" 10 | call "%~dp0\build.bat" 11 | if %ERRORLEVEL% NEQ 0 exit /b -1; 12 | pushd "%~dp0\.." 13 | "%NODEEXE%" "%APPDATA%\npm\node_modules\mocha\bin\mocha" -R spec -t 10000 14 | set EDGE_USE_CORECLR=1 15 | REM set EDGE_DEBUG=1 16 | popd 17 | rmdir /s /q "%~dp0/bin" 18 | rmdir /s /q "%~dp0/obj" 19 | call "%~dp0\build.bat" 20 | if %ERRORLEVEL% NEQ 0 exit /b -1; 21 | pushd "%~dp0\.." 22 | "%NODEEXE%" "%APPDATA%\npm\node_modules\mocha\bin\mocha" -R spec -t 10000 23 | set EDGE_USE_CORECLR= 24 | set EDGE_DEBUG= 25 | popd 26 | echo Finished running tests using node.js: %NODEEXE% 27 | -------------------------------------------------------------------------------- /test/test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net5.0 5 | true 6 | true 7 | test 8 | Exe 9 | test 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /test/testall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set SELF=%~dp0 4 | set run32=N 5 | set run64=N 6 | 7 | if "%1"=="" set run32=Y 8 | if "%1"=="ia32" set run32=Y 9 | if "%1"=="" set run64=Y 10 | if "%1"=="x64" set run64=Y 11 | 12 | if "%run32%"=="Y" ( 13 | call "%SELF%\test.bat" ia32 14.3.0 14 | call "%SELF%\test.bat" ia32 13.0.1 15 | call "%SELF%\test.bat" ia32 12.13.0 16 | call "%SELF%\test.bat" ia32 11.3.0 17 | call "%SELF%\test.bat" ia32 10.14.0 18 | call "%SELF%\test.bat" ia32 8.14.0 19 | call "%SELF%\test.bat" ia32 6.15.0 20 | ) 21 | 22 | if "%run64%"=="Y" ( 23 | call "%SELF%\test.bat" x64 14.3.0 24 | call "%SELF%\test.bat" x64 13.0.1 25 | call "%SELF%\test.bat" x64 12.13.0 26 | call "%SELF%\test.bat" x64 11.3.0 27 | call "%SELF%\test.bat" x64 10.14.0 28 | call "%SELF%\test.bat" x64 8.14.0 29 | call "%SELF%\test.bat" x64 6.15.0 30 | ) -------------------------------------------------------------------------------- /tools/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set SELF=%~dp0 3 | if "%1" equ "" ( 4 | echo Usage: build.bat debug^|release "{version} {version}" ... 5 | echo e.g. build.bat release "0.8.22 0.10.0" 6 | exit /b -1 7 | ) 8 | 9 | SET FLAVOR=%1 10 | shift 11 | if "%FLAVOR%" equ "" set FLAVOR=release 12 | for %%i in (node.exe) do set NODEEXE=%%~$PATH:i 13 | if not exist "%NODEEXE%" ( 14 | echo Cannot find node.exe 15 | popd 16 | exit /b -1 17 | ) 18 | for %%i in ("%NODEEXE%") do set NODEDIR=%%~dpi 19 | SET DESTDIRROOT=%SELF%\..\lib\native\win32 20 | set VERSIONS= 21 | :harvestVersions 22 | if "%1" neq "" ( 23 | set VERSIONS=%VERSIONS% %1 24 | shift 25 | goto :harvestVersions 26 | ) 27 | if "%VERSIONS%" equ "" set VERSIONS=0.10.0 28 | pushd %SELF%\.. 29 | for %%V in (%VERSIONS%) do call :build ia32 x86 %%V 30 | for %%V in (%VERSIONS%) do call :build x64 x64 %%V 31 | popd 32 | 33 | exit /b 0 34 | 35 | :build 36 | 37 | set DESTDIR=%DESTDIRROOT%\%1\%3 38 | if exist "%DESTDIR%\node.exe" goto gyp 39 | if not exist "%DESTDIR%\NUL" mkdir "%DESTDIR%" 40 | echo Downloading node.exe %2 %3... 41 | node "%SELF%\download.js" %2 %3 "%DESTDIR%" 42 | if %ERRORLEVEL% neq 0 ( 43 | echo Cannot download node.exe %2 v%3 44 | exit /b -1 45 | ) 46 | 47 | :gyp 48 | 49 | echo Building edge.node %FLAVOR% for node.js %2 v%3 50 | set NODEEXE=%DESTDIR%\node.exe 51 | FOR /F "tokens=* USEBACKQ" %%F IN (`npm config get prefix`) DO (SET NODEBASE=%%F) 52 | set GYP=%NODEBASE%\node_modules\node-gyp\bin\node-gyp.js 53 | if not exist "%GYP%" ( 54 | echo Cannot find node-gyp at %GYP%. Make sure to install with npm install node-gyp -g 55 | exit /b -1 56 | ) 57 | 58 | "%NODEEXE%" "%GYP%" configure build --msvs_version=2017 -%FLAVOR% 59 | if %ERRORLEVEL% neq 0 ( 60 | echo Error building edge.node %FLAVOR% for node.js %2 v%3 61 | exit /b -1 62 | ) 63 | 64 | echo %DESTDIR% 65 | copy /y .\build\%FLAVOR%\edge_*.node "%DESTDIR%" 66 | if %ERRORLEVEL% neq 0 ( 67 | echo Error copying edge.node %FLAVOR% for node.js %2 v%3 68 | exit /b -1 69 | ) 70 | 71 | copy /y "%DESTDIR%\..\*.dll" "%DESTDIR%" 72 | if %ERRORLEVEL% neq 0 ( 73 | echo Error copying VC redist %FLAVOR% to %DESTDIR% 74 | exit /b -1 75 | ) 76 | 77 | echo Success building edge.node %FLAVOR% for node.js %2 v%3 78 | -------------------------------------------------------------------------------- /tools/buildall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | "%~dp0\build.bat" release 6.15.0 7.10.1 8.14.0 9.11.2 10.14.0 11.3.0 12.13.0 13.0.1 14.3.0 3 | -------------------------------------------------------------------------------- /tools/checkplatform.js: -------------------------------------------------------------------------------- 1 | try { 2 | require('../lib/edge.js'); 3 | } 4 | catch (e) { 5 | console.log('***************************************'); 6 | console.log(e); 7 | console.log('***************************************'); 8 | } 9 | 10 | console.log('Success: platform check for edge.js: node.js ' + process.arch + ' v' + process.versions.node); 11 | -------------------------------------------------------------------------------- /tools/coverage.js: -------------------------------------------------------------------------------- 1 | var spawn = require('child_process').spawn; 2 | var path = require('path'); 3 | var testDir = path.resolve(__dirname, '../test'); 4 | var input = path.resolve(testDir, 'tests.cs'); 5 | var output = path.resolve(testDir, 'Edge.Tests.dll'); 6 | var buildParameters = ['-target:library', '/debug', '-out:' + output, input]; 7 | var mocha = path.resolve(__dirname, '../node_modules/mocha/bin/mocha'); 8 | var xunit = path.resolve(__dirname, '../node_modules/xunit-viewer/bin/xunit-viewer'); 9 | var fs = require('fs'); 10 | const merge = require('junit-report-merger'); 11 | 12 | if (!process.env.EDGE_USE_CORECLR) { 13 | run(process.platform === 'win32' ? 'csc' : 'mcs', buildParameters, runOnSuccess, 'net'); 14 | } 15 | 16 | else { 17 | run(process.platform === 'win32' ? 'dotnet.exe' : 'dotnet', ['restore'], function(code, signal) { 18 | if (code === 0) { 19 | run(process.platform === 'win32' ? 'dotnet.exe' : 'dotnet', ['build'], runOnSuccess, 'coreclr'); 20 | } 21 | }); 22 | } 23 | 24 | function run(cmd, args, onClose, signal){ 25 | 26 | var params = process.env.EDGE_USE_CORECLR ? {cwd: testDir} : {}; 27 | var command = spawn(cmd, args, params); 28 | var result = ''; 29 | var error = ''; 30 | command.stdout.on('data', function(data) { 31 | result += data.toString(); 32 | }); 33 | command.stderr.on('data', function(data) { 34 | error += data.toString(); 35 | }); 36 | 37 | command.on('error', function(err) { 38 | console.log(error); 39 | console.log(err); 40 | }); 41 | 42 | command.on('close', function(code){ 43 | //console.log(result); 44 | onClose(code, signal); 45 | }); 46 | } 47 | 48 | function runOnSuccess(code, framework) { 49 | if (code === 0) { 50 | process.env['EDGE_APP_ROOT'] = path.join(testDir, 'bin', 'Debug', 'net5.0'); 51 | 52 | createJunitReports(framework, false); 53 | createJunitReports(framework, true); 54 | } 55 | } 56 | 57 | function createJunitReports(framework, createHtml){ 58 | let suffix = createHtml ? '-xunit-viewer' : ''; 59 | spawn('node', [mocha, testDir, '-R', 'mocha-junit-reporter', '-t', '10000', '-gc', '--reporter-options', `mochaFile=./test-results-${framework}${suffix}.xml,testCaseSwitchClassnameAndName=${createHtml ? 'true' : ''}`], { 60 | stdio: 'inherit' 61 | }).on('close', function(code) { 62 | let source = []; 63 | if(fs.existsSync(`./test-results-coreclr${suffix}.xml`)){ 64 | source.push(`./test-results-coreclr${suffix}.xml`); 65 | } 66 | if(fs.existsSync(`./test-results-net${suffix}.xml`)){ 67 | source.push(`./test-results-net${suffix}.xml`); 68 | } 69 | merge.mergeFiles(`./test-results${suffix}.xml`, source, function(err) { 70 | if(err) 71 | { 72 | console.log(err) 73 | }else{ 74 | if(createHtml){ 75 | spawn('node', [xunit, '--results=test-results-xunit-viewer.xml','--output=test-results-xunit-viewer.html'], { 76 | stdio: 'inherit' 77 | }).on('close', function(code) { 78 | }).on('error', function(err) { 79 | console.log(err); 80 | }); 81 | } 82 | 83 | 84 | } 85 | }) 86 | }).on('error', function(err) { 87 | console.log(err); 88 | }); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /tools/download.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | class Program 5 | { 6 | public static void Main(string[] args) 7 | { 8 | if (args.Length != 2) { 9 | throw new InvalidOperationException("Usage: download.exe "); 10 | } 11 | 12 | Console.WriteLine("Downloading " + args[0] + " to " + args[1] + "..."); 13 | var client = new WebClient(); 14 | client.DownloadFile(args[0], args[1]); 15 | Console.WriteLine("Done."); 16 | } 17 | } -------------------------------------------------------------------------------- /tools/download.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | 3 | var urls; 4 | if (process.argv[2] === 'x86') { 5 | urls = [ 6 | 'http://nodejs.org/dist/v' + process.argv[3] + '/node.exe', 7 | 'http://nodejs.org/dist/v' + process.argv[3] + '/win-x86/node.exe' 8 | ]; 9 | } 10 | else { 11 | urls = [ 12 | 'http://nodejs.org/dist/v' + process.argv[3] + '/x64/node.exe', 13 | 'http://nodejs.org/dist/v' + process.argv[3] + '/win-x64/node.exe' 14 | ]; 15 | } 16 | 17 | try_get(0); 18 | 19 | function try_get(i) { 20 | console.log('Trying download from', urls[i]); 21 | http.get(urls[i], function (res) { 22 | console.log('HTTP', res.statusCode); 23 | if (res.statusCode !== 200) { 24 | if (++i === urls.length) 25 | throw new Error('Unable to download node.exe'); 26 | else 27 | try_get(i); 28 | } 29 | 30 | var stream = require('fs').createWriteStream(process.argv[4] + '/node.exe'); 31 | res.pipe(stream); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /tools/install.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | , path = require('path') 3 | , spawn = require('child_process').spawn 4 | , whereis = require('./whereis'); 5 | 6 | if (process.platform === 'win32') { 7 | var libroot = path.resolve(__dirname, '../lib/native/win32') 8 | , lib32bit = path.resolve(libroot, 'ia32') 9 | , lib64bit = path.resolve(libroot, 'x64'); 10 | 11 | function copyFile(filePath, filename) { 12 | return function(copyToDir) { 13 | //console.log( 'copy '+filename+' from '+filePath+' to '+ copyToDir ); 14 | outFile = path.resolve(copyToDir, filename); 15 | if ( fs.existsSync( outFile ) ) { 16 | // clear readonly: add write permission to ogw (222 octal -> 92 hex -> 146 decimal) 17 | fs.chmodSync( outFile, fs.statSync(outFile).mode | 146 ) 18 | } 19 | fs.writeFileSync(path.resolve(copyToDir, filename), fs.readFileSync(filePath)); 20 | }; 21 | } 22 | 23 | function isDirectory(info) { 24 | return info.isDirectory; 25 | } 26 | 27 | function getInfo(basedir) { 28 | return function(file) { 29 | var filepath = path.resolve(basedir, file); 30 | 31 | return { 32 | path: filepath, 33 | isDirectory: fs.statSync(filepath).isDirectory() 34 | }; 35 | } 36 | } 37 | 38 | function getPath(info) { 39 | return info.path; 40 | } 41 | 42 | var dest32dirs = fs.readdirSync(lib32bit) 43 | .map(getInfo(lib32bit)) 44 | .filter(isDirectory) 45 | .map(getPath); 46 | 47 | var redist = [ 48 | 'concrt140.dll', 49 | 'msvcp140.dll', 50 | 'vccorlib140.dll', 51 | 'vcruntime140.dll', 52 | ]; 53 | 54 | redist.forEach(function (dllname) { 55 | var dll32bit = path.resolve(lib32bit, dllname); 56 | dest32dirs.forEach(copyFile(dll32bit, dllname)); 57 | }); 58 | 59 | var dest64dirs = fs.readdirSync(lib64bit) 60 | .map(getInfo(lib64bit)) 61 | .filter(isDirectory) 62 | .map(getPath); 63 | 64 | redist.forEach(function (dllname) { 65 | var dll64bit = path.resolve(lib64bit, dllname); 66 | dest64dirs.forEach(copyFile(dll64bit, dllname)); 67 | }); 68 | 69 | var dotnetPath = whereis('dotnet', 'dotnet.exe'); 70 | 71 | if (dotnetPath) { 72 | spawn(dotnetPath, ['restore'], { stdio: 'inherit', cwd: path.resolve(__dirname, '..', 'lib', 'bootstrap') }) 73 | .on('close', function() { 74 | spawn(dotnetPath, ['build', '--configuration', 'Release'], { stdio: 'inherit', cwd: path.resolve(__dirname, '..', 'lib', 'bootstrap') }) 75 | .on('close', function() { 76 | require('./checkplatform'); 77 | }); 78 | }); 79 | } 80 | 81 | else { 82 | require('./checkplatform'); 83 | } 84 | } 85 | 86 | else { 87 | spawn('node-gyp', ['configure', 'build'], { stdio: 'inherit' }); 88 | } 89 | -------------------------------------------------------------------------------- /tools/nuget/edge.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | EdgeJs 5 | 11.3.3 6 | agracio 7 | agracio 8 | https://raw.githubusercontent.com/agracio/edge-js/master/LICENSE 9 | https://github.com/agracio/edge-js 10 | false 11 | Run .NET and Node.js code in-process on Windows, macOS, and Linux 12 | Run .NET and Node.js code in-process on Windows, macOS, and Linux 13 | With Edge.js you can script Node.js in a .NET application. Edge.js allows you to run Node.js and .NET code in one process. You can call Node.js functions from .NET and .NET functions from Node.js. Edge.js takes care of marshalling data between CLR and V8. Edge.js also reconciles threading models of single threaded V8 and multi-threaded CLR. Edge.js ensures correct lifetime of objects on V8 and CLR heaps. This Edge.js NuGet package supports scripting Node.js v8.9.3. 14 | Copyright 2017 Tomasz Janczuk 15 | node.js node .net edge edge.js v8 clr coreclr mono interop javascript 16 | 17 | -------------------------------------------------------------------------------- /tools/nuget/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | function MarkDirectoryAsCopyToOutputRecursive($item) 4 | { 5 | $item.ProjectItems | ForEach-Object { MarkFileASCopyToOutputDirectory($_) } 6 | } 7 | 8 | function MarkFileASCopyToOutputDirectory($item) 9 | { 10 | Try 11 | { 12 | Write-Host Try set $item.Name 13 | $item.Properties.Item("CopyToOutputDirectory").Value = 2 14 | } 15 | Catch 16 | { 17 | Write-Host RecurseOn $item.Name 18 | MarkDirectoryAsCopyToOutputRecursive($item) 19 | } 20 | } 21 | 22 | MarkDirectoryAsCopyToOutputRecursive($project.ProjectItems.Item("edge")) 23 | -------------------------------------------------------------------------------- /tools/repl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | class Program 5 | { 6 | public static void Main(string[] args) 7 | { 8 | if (args.Length != 3) { 9 | throw new InvalidOperationException("Usage: repl.exe "); 10 | } 11 | 12 | Console.WriteLine("Replacing " + args[1] + " with " + args[2] + " in " + args[0] + "..."); 13 | var s = File.ReadAllText(args[0]); 14 | File.WriteAllText(args[0], s.Replace(args[1], args[2])); 15 | Console.WriteLine("Done."); 16 | } 17 | } -------------------------------------------------------------------------------- /tools/runJsHint.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var jshint = require('jshint').JSHINT; 3 | 4 | var foldersToLint = [ 5 | './lib', 6 | './test' 7 | ]; 8 | 9 | var utils = { 10 | errors: 0, 11 | 12 | readFile: function (filename) { 13 | return fs.readFileSync(filename, 'utf8'); 14 | }, 15 | 16 | lintFile: function (filename, config) { 17 | var results = jshint(this.readFile(filename), config.options, config.globals); 18 | if (!results) { 19 | this.errors++; 20 | this.renderResults(filename); 21 | } 22 | }, 23 | 24 | resolveFiles: function(folders) { 25 | var files = []; 26 | folders.forEach(function (dir) { 27 | var filesInFolder = fs.readdirSync(dir); 28 | var jsFiles = filesInFolder.filter(function (file) { 29 | return file.indexOf('.js') > 0; 30 | }).map(function (js) { 31 | return dir + '/' + js; 32 | }); 33 | 34 | files = files.concat(jsFiles); 35 | }); 36 | 37 | return files; 38 | }, 39 | 40 | renderResults: function (filename) { 41 | jshint.errors.forEach(function (e) { 42 | if (!e) { 43 | return; 44 | } 45 | console.error(filename + ': ' + e.code + ' ' + e.raw + ' at line: ' + e.line + ' character: ' + e.character); 46 | }); 47 | } 48 | }; 49 | 50 | var config = JSON.parse(utils.readFile('.jshintrc')); 51 | var filesToLint = utils.resolveFiles(foldersToLint); 52 | 53 | filesToLint.forEach(function (filename) { 54 | utils.lintFile(filename, config); 55 | }); 56 | 57 | if (utils.errors > 0) { 58 | return process.exit(1); 59 | } 60 | 61 | console.log('Success: no linting errors.'); -------------------------------------------------------------------------------- /tools/test.js: -------------------------------------------------------------------------------- 1 | var spawn = require('child_process').spawn; 2 | var path = require('path'); 3 | var testDir = path.resolve(__dirname, '../test'); 4 | var input = path.resolve(testDir, 'tests.cs'); 5 | var output = path.resolve(testDir, 'Edge.Tests.dll'); 6 | var buildParameters = ['-target:library', '/debug', '-out:' + output, input]; 7 | var mocha = path.resolve(__dirname, '../node_modules/mocha/bin/mocha'); 8 | var fs = require('fs'); 9 | 10 | if (!process.env.EDGE_USE_CORECLR) { 11 | if (process.platform !== 'win32') { 12 | buildParameters = buildParameters.concat(['-sdk:4.5']); 13 | } 14 | 15 | run(process.platform === 'win32' ? 'csc' : 'mcs', buildParameters, runOnSuccess); 16 | } 17 | 18 | else { 19 | run(process.platform === 'win32' ? 'dotnet.exe' : 'dotnet', ['restore'], function(code, signal) { 20 | if (code === 0) { 21 | run(process.platform === 'win32' ? 'dotnet.exe' : 'dotnet', ['build'], function(code, signal) { 22 | if (code === 0) { 23 | run('cp', ['../test/bin/Debug/net5.0/test.dll', '../test/Edge.Tests.CoreClr.dll'], runOnSuccess); 24 | } 25 | }); 26 | } 27 | }); 28 | } 29 | 30 | function run(cmd, args, onClose){ 31 | 32 | var params = process.env.EDGE_USE_CORECLR ? {cwd: testDir} : {}; 33 | var command = spawn(cmd, args, params); 34 | var result = ''; 35 | var error = ''; 36 | command.stdout.on('data', function(data) { 37 | result += data.toString(); 38 | }); 39 | command.stderr.on('data', function(data) { 40 | error += data.toString(); 41 | }); 42 | 43 | command.on('error', function(err) { 44 | console.log(error); 45 | console.log(err); 46 | }); 47 | 48 | command.on('close', function(code){ 49 | console.log(result); 50 | onClose(code, ''); 51 | }); 52 | } 53 | 54 | function runOnSuccess(code, signal) { 55 | if (code === 0) { 56 | process.env['EDGE_APP_ROOT'] = path.join(testDir, 'bin', 'Debug', 'net5.0'); 57 | spawn('node', [mocha, testDir, '-R', 'spec', '-t', '10000', '-gc'], { 58 | stdio: 'inherit' 59 | }).on('error', function(err) { 60 | console.log(err); 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tools/unzip.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO.Compression; 3 | 4 | class Program 5 | { 6 | public static void Main(string[] args) 7 | { 8 | if (args.Length != 2) { 9 | throw new InvalidOperationException("Usage: unzip.exe "); 10 | } 11 | 12 | Console.WriteLine("Unziping " + args[0] + " to " + args[1] + "..."); 13 | ZipFile.ExtractToDirectory(args[0], args[1]); 14 | Console.WriteLine("Done."); 15 | } 16 | } -------------------------------------------------------------------------------- /tools/unzip.vbs: -------------------------------------------------------------------------------- 1 | ' UnZip a file script 2 | ' 3 | ' By Justin Godden 2010 4 | ' 5 | ' It's a mess, I know!!! 6 | ' 7 | 8 | ' Dim ArgObj, var1, var2 9 | Set ArgObj = WScript.Arguments 10 | 11 | If (Wscript.Arguments.Count > 0) Then 12 | var1 = ArgObj(0) 13 | Else 14 | var1 = "" 15 | End if 16 | 17 | If var1 = "" then 18 | strFileZIP = "example.zip" 19 | Else 20 | strFileZIP = var1 21 | End if 22 | 23 | 'The location of the zip file. 24 | REM Set WshShell = CreateObject("Wscript.Shell") 25 | REM CurDir = WshShell.ExpandEnvironmentStrings("%%cd%%") 26 | Dim sCurPath 27 | sCurPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") 28 | strZipFile = sCurPath & "\" & strFileZIP 29 | 'The folder the contents should be extracted to. 30 | outFolder = sCurPath & "\" 31 | 32 | WScript.Echo ( "Extracting file " & strFileZIP) 33 | 34 | Set objShell = CreateObject( "Shell.Application" ) 35 | Set objSource = objShell.NameSpace(strZipFile).Items() 36 | Set objTarget = objShell.NameSpace(outFolder) 37 | intOptions = 256 38 | objTarget.CopyHere objSource, intOptions 39 | 40 | WScript.Echo ( "Extracted." ) 41 | 42 | ' This bit is for testing purposes 43 | REM Dim MyVar 44 | REM MyVar = MsgBox ( strZipFile, 65, "MsgBox Example" -------------------------------------------------------------------------------- /tools/whereis.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | 4 | module.exports = function() { 5 | var pathSep = process.platform === 'win32' ? ';' : ':'; 6 | 7 | var directories = process.env.PATH.split(pathSep); 8 | 9 | for (var i = 0; i < directories.length; i++) { 10 | for (var j = 0; j < arguments.length; j++) { 11 | var filename = arguments[j]; 12 | var filePath = path.join(directories[i], filename); 13 | 14 | if (fs.existsSync(filePath)) { 15 | return filePath; 16 | } 17 | } 18 | } 19 | 20 | return null; 21 | } --------------------------------------------------------------------------------