├── .gitattributes ├── .github ├── FUNDING.yml ├── actions │ ├── build-electron │ │ └── action.yml │ ├── build │ │ └── action.yml │ ├── create-test-report │ │ └── action.yml │ ├── get-electron-version │ │ └── action.yml │ ├── setup-env │ │ └── action.yml │ └── test-build │ │ └── action.yml └── workflows │ ├── build-all.yml │ ├── build.yml │ ├── ci-old.yml │ └── ci.yml ├── .gitignore ├── .npmignore ├── EdgeJs.sln ├── LICENSE ├── README.md ├── binding.gyp ├── electron-edge-js.d.ts ├── lib ├── bootstrap │ ├── .gitignore │ ├── Dummy.cs │ └── bootstrap.csproj ├── double_edge.js ├── edge.js ├── electronPath.js └── native │ ├── darwin │ ├── arm64 │ │ ├── 31 │ │ │ ├── MonoEmbedding.exe │ │ │ ├── edge_coreclr.node │ │ │ └── edge_nativeclr.node │ │ ├── 32 │ │ │ ├── MonoEmbedding.exe │ │ │ ├── edge_coreclr.node │ │ │ └── edge_nativeclr.node │ │ ├── 33 │ │ │ ├── MonoEmbedding.exe │ │ │ ├── edge_coreclr.node │ │ │ └── edge_nativeclr.node │ │ ├── 34 │ │ │ ├── MonoEmbedding.exe │ │ │ ├── edge_coreclr.node │ │ │ └── edge_nativeclr.node │ │ ├── 35 │ │ │ ├── MonoEmbedding.exe │ │ │ ├── edge_coreclr.node │ │ │ └── edge_nativeclr.node │ │ └── 36 │ │ │ ├── MonoEmbedding.exe │ │ │ ├── edge_coreclr.node │ │ │ └── edge_nativeclr.node │ └── x64 │ │ ├── 31 │ │ ├── MonoEmbedding.exe │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ │ ├── 32 │ │ ├── MonoEmbedding.exe │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ │ ├── 33 │ │ ├── MonoEmbedding.exe │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ │ ├── 34 │ │ ├── MonoEmbedding.exe │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ │ ├── 35 │ │ ├── MonoEmbedding.exe │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ │ └── 36 │ │ ├── MonoEmbedding.exe │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ └── win32 │ ├── arm64 │ ├── 31 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 32 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 33 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 34 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 35 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 36 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll │ ├── ia32 │ ├── 31 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 32 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 33 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 34 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 35 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── 36 │ │ ├── edge_coreclr.node │ │ └── edge_nativeclr.node │ ├── .gitignore │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll │ └── x64 │ ├── 31 │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 32 │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 33 │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 34 │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 35 │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── 36 │ ├── edge_coreclr.node │ └── edge_nativeclr.node │ ├── .gitignore │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll ├── package-lock.json ├── package.json ├── 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 │ │ │ ├── pplx │ │ │ │ ├── pplx.h │ │ │ │ ├── pplxcancellation_token.h │ │ │ │ ├── pplxconv.h │ │ │ │ ├── pplxinterface.h │ │ │ │ ├── pplxlinux.h │ │ │ │ ├── pplxtasks.h │ │ │ │ ├── pplxwin.h │ │ │ │ └── threadpool.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 │ │ ├── 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 ├── test ├── 101_edge_func.js ├── 102_node2net.js ├── 103_net2node.js ├── 104_csx.js ├── 105_node2net_sync.js ├── 106_node2net_symbols.js ├── 201_patterns.js ├── 202_serialization.js ├── app.js ├── hello_class.cs ├── hello_class.csx ├── hello_lambda.csx ├── index.html ├── loading.gif ├── main.js ├── mochawesome-report │ └── assets │ │ ├── MaterialIcons-Regular.woff │ │ ├── MaterialIcons-Regular.woff2 │ │ ├── app.css │ │ ├── app.js │ │ ├── app.js.LICENSE.txt │ │ ├── loading1.gif │ │ ├── roboto-light-webfont.woff │ │ ├── roboto-light-webfont.woff2 │ │ ├── roboto-medium-webfont.woff │ │ ├── roboto-medium-webfont.woff2 │ │ ├── roboto-regular-webfont.woff │ │ └── roboto-regular-webfont.woff2 ├── preload.js ├── renderer.js ├── test.csproj └── tests.cs └── tools ├── build.bat ├── checkMono.js ├── getVersion.js ├── install.js ├── mergeTests.js ├── test.js └── whereis.js /.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 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [agracio] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 15 | -------------------------------------------------------------------------------- /.github/actions/build-electron/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Electron build' 2 | description: 'Electron build' 3 | inputs: 4 | electron: 5 | description: 'Electron version' 6 | required: true 7 | os: 8 | description: 'runs-on' 9 | required: false 10 | default: 'windows-2025' 11 | 12 | runs: 13 | using: "composite" 14 | steps: 15 | 16 | - name: Setup env 17 | uses: ./.github/actions/setup-env 18 | with: 19 | electron: '${{ inputs.electron }}.0.0' 20 | os: ${{ inputs.os }} 21 | 22 | - name: install node-gyp 23 | shell: bash 24 | run: npm i -g node-gyp 25 | 26 | - name: Create release folder 27 | uses: actions/github-script@v7 28 | with: 29 | result-encoding: string 30 | script: | 31 | try { 32 | const fs = require('fs') 33 | if('${{ runner.os }}' == 'Windows'){ 34 | fs.mkdirSync('release/win32/ia32/${{ inputs.electron }}', { recursive: true }); 35 | fs.mkdirSync('release/win32/x64/${{ inputs.electron }}', { recursive: true }); 36 | fs.mkdirSync('release/win32/arm64/${{ inputs.electron }}', { recursive: true }); 37 | } 38 | else if('${{ inputs.os }}' == 'macos-15'){ 39 | fs.mkdirSync(`release/${process.platform}/arm64/${{ inputs.electron }}`, { recursive: true }); 40 | } 41 | else if('${{ inputs.os }}' == 'macos-13'){ 42 | fs.mkdirSync(`release/${process.platform}/x64/${{ inputs.electron }}`, { recursive: true }); 43 | } 44 | } catch(err) { 45 | core.error("Error creating release directory") 46 | core.setFailed(err) 47 | } 48 | 49 | - name: Cache node-gyp 50 | if: runner.os == 'Windows' 51 | uses: actions/cache@v4 52 | env: 53 | cache-name: cache-node-gyp 54 | with: 55 | path: ~\AppData\Local\node-gyp\Cache 56 | key: '${{ runner.os }}-${{ inputs.electron }}' 57 | 58 | - name: Cache node-gyp macOS 59 | if: runner.os == 'macOS' 60 | uses: actions/cache@v4 61 | env: 62 | cache-name: cache-node-gyp 63 | with: 64 | path: ~/Library/Caches/node-gyp 65 | key: '${{ runner.os }}-${{ inputs.electron }}' 66 | 67 | - name: Build ia32 68 | if: runner.os == 'Windows' 69 | uses: ./.github/actions/build 70 | with: 71 | electron: ${{ inputs.electron }} 72 | arch: 'ia32' 73 | 74 | - name: Build x64 75 | if: runner.os == 'Windows' || inputs.os == 'macos-13' 76 | uses: ./.github/actions/build 77 | with: 78 | electron: ${{ inputs.electron }} 79 | arch: 'x64' 80 | 81 | - name: Build arm64 82 | if: runner.os == 'Windows' || inputs.os == 'macos-15' 83 | uses: ./.github/actions/build 84 | with: 85 | electron: ${{ inputs.electron }} 86 | arch: 'arm64' 87 | 88 | - name: Upload artifacts 89 | uses: actions/upload-artifact@v4 90 | if: runner.os == 'Windows' && success() 91 | with: 92 | name: win32-electron-edge-js-${{ inputs.electron }} 93 | path: | 94 | release 95 | 96 | - name: Upload artifacts 97 | uses: actions/upload-artifact@v4 98 | if: inputs.os == 'macos-15' && success() 99 | with: 100 | name: darwin-electron-edge-js-arm64-${{ inputs.electron }} 101 | path: | 102 | release 103 | 104 | - name: Upload artifacts 105 | uses: actions/upload-artifact@v4 106 | if: inputs.os == 'macos-13' && success() 107 | with: 108 | name: darwin-electron-edge-js-x64-${{ inputs.electron }} 109 | path: | 110 | release 111 | -------------------------------------------------------------------------------- /.github/actions/build/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Build Windows binaries' 2 | description: 'Build Windows binaries' 3 | inputs: 4 | electron: 5 | description: 'Electron version' 6 | required: true 7 | arch: 8 | description: 'Target arch' 9 | required: true 10 | 11 | runs: 12 | using: "composite" 13 | steps: 14 | 15 | - name: Build ${{ inputs.arch }} 16 | shell: pwsh 17 | run: | 18 | 19 | node-gyp configure --target=${{ inputs.electron }}.0.0 --disturl=https://electronjs.org/headers --runtime=electron --release --arch=${{ inputs.arch }} 20 | 21 | if ( '${{ inputs.arch }}' -eq 'arm64' -And '${{ runner.os }}' -eq 'Windows'){ 22 | (Get-Content -Raw build/build_managed.vcxproj) -replace 'Strict', '' | Out-File -Encoding Utf8 build/build_managed.vcxproj 23 | (Get-Content -Raw build/edge_coreclr.vcxproj) -replace 'Strict', '' | Out-File -Encoding Utf8 build/edge_coreclr.vcxproj 24 | (Get-Content -Raw build/edge_nativeclr.vcxproj) -replace 'Strict', '' | Out-File -Encoding Utf8 build/edge_nativeclr.vcxproj 25 | } 26 | 27 | if ( '${{ inputs.electron }}' -eq 32 -And '${{ runner.os }}' -eq 'Windows'){ 28 | (Get-Content -Raw build/build_managed.vcxproj) -replace 'std:c\+\+17', 'std:c++20' | Out-File -Encoding Utf8 build/build_managed.vcxproj 29 | (Get-Content -Raw build/edge_coreclr.vcxproj) -replace 'std:c\+\+17', 'std:c++20' | Out-File -Encoding Utf8 build/edge_coreclr.vcxproj 30 | (Get-Content -Raw build/edge_nativeclr.vcxproj) -replace 'std:c\+\+17', 'std:c++20' | Out-File -Encoding Utf8 build/edge_nativeclr.vcxproj 31 | } 32 | 33 | node-gyp build 34 | 35 | if ( '${{ runner.os }}' -eq 'Windows'){ 36 | cmd /c copy /y build\Release\edge_*.node release\win32\${{ inputs.arch }}\${{ inputs.electron }} 37 | cmd /c rmdir /S /Q build 38 | } 39 | 40 | if ( '${{ runner.os }}' -eq 'macOS'){ 41 | Get-ChildItem -Path build/Release 42 | Copy-Item "build/Release/edge_coreclr.node" -Destination "release/darwin/${{ inputs.arch }}/${{ inputs.electron }}" 43 | Copy-Item "build/Release/edge_nativeclr.node" -Destination "release/darwin/${{ inputs.arch }}/${{ inputs.electron }}" 44 | Copy-Item "build/Release/MonoEmbedding.exe" -Destination "release/darwin/${{ inputs.arch }}/${{ inputs.electron }}" 45 | 46 | node-gyp clean 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /.github/actions/create-test-report/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Test report' 2 | description: 'Create test report' 3 | inputs: 4 | name: 5 | description: 'name' 6 | required: false 7 | default: 'test-results' 8 | electron: 9 | description: 'Electron version' 10 | required: true 11 | os: 12 | description: 'runs-on' 13 | required: true 14 | 15 | runs: 16 | using: "composite" 17 | steps: 18 | - name: "Merge test files" 19 | shell: bash 20 | run: node tools/mergeTests.js ${{ inputs.electron }} 21 | 22 | - name: Read mochawesome.json 23 | uses: actions/github-script@v7 24 | with: 25 | result-encoding: string 26 | script: | 27 | try { 28 | const fs = require('fs') 29 | const jsonString = fs.readFileSync('test/mochawesome-report/mochawesome.json') 30 | var report = JSON.parse(jsonString); 31 | let stats = { 32 | Passing: report.stats.passes, 33 | Skipped: report.stats.pending, 34 | Failures: report.stats.failures 35 | }; 36 | core.notice(stats); 37 | } catch(err) { 38 | core.error("Error while reading or parsing test/mochawesome-report/mochawesome.json") 39 | core.setFailed(err) 40 | } 41 | 42 | - name: Upload artifacts 43 | uses: actions/upload-artifact@v4 44 | if: success() 45 | with: 46 | name: ${{ inputs.name }}-${{ inputs.os }}-${{ inputs.electron }} 47 | path: | 48 | test/mochawesome-report/mochawesome.json 49 | test/mochawesome-report/mochawesome.html 50 | test/mochawesome-report/assets/ 51 | 52 | # - name: Create test report 53 | # uses: phoenix-actions/test-reporting@v15 54 | # if: success() 55 | # with: 56 | # name: ${{ inputs.name }}-${{ inputs.os }}-v${{ inputs.electron }} 57 | # fail-on-error: true 58 | # path: test/mochawesome-report/mochawesome.json # Path to test results 59 | # reporter: mochawesome-json 60 | -------------------------------------------------------------------------------- /.github/actions/get-electron-version/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Get Electron version' 2 | description: 'Get Electron version' 3 | inputs: 4 | electron: 5 | description: 'Electron version' 6 | required: true 7 | 8 | runs: 9 | using: "composite" 10 | steps: 11 | 12 | - name: Resolve Electron version from major 13 | shell: bash 14 | run: | 15 | if [[ ${{ inputs.electron }} == '29' ]]; then 16 | echo "test-version=29.4.6" >> $GITHUB_OUTPUT 17 | elif [[ ${{ inputs.electron }} == '30' ]]; then 18 | echo "test-version=30.5.1" >> $GITHUB_OUTPUT 19 | elif [[ ${{ inputs.electron }} == '31' ]]; then 20 | echo "test-version=31.7.2" >> $GITHUB_OUTPUT 21 | elif [[ ${{ inputs.electron }} == '32' ]]; then 22 | echo "test-version=32.2.2" >> $GITHUB_OUTPUT 23 | elif [[ ${{ inputs.electron }} == '33' ]]; then 24 | echo "test-version=33.0.2" >> $GITHUB_OUTPUT 25 | fi -------------------------------------------------------------------------------- /.github/actions/setup-env/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup environment' 2 | description: 'Sets up environment' 3 | inputs: 4 | node: 5 | description: 'Node.js version' 6 | required: false 7 | default: '22' 8 | os: 9 | description: 'runs-on' 10 | required: false 11 | default: 'windows-2025' 12 | electron: 13 | description: 'Electron version' 14 | required: true 15 | replace-version: 16 | description: 'Replace electron version?' 17 | required: false 18 | default: 'false' 19 | arch: 20 | description: 'Architecture' 21 | required: false 22 | default: '' 23 | 24 | runs: 25 | using: "composite" 26 | steps: 27 | 28 | - name: Setup NodeJS 29 | uses: actions/setup-node@v4 30 | with: 31 | node-version: ${{ inputs.node }} 32 | architecture: ${{ inputs.arch }} 33 | cache: 'npm' 34 | cache-dependency-path: package-lock.json 35 | 36 | - name: Read package.json 37 | uses: actions/github-script@v7 38 | with: 39 | result-encoding: string 40 | script: | 41 | try { 42 | const fs = require('fs') 43 | const jsonString = fs.readFileSync('package.json') 44 | var json = JSON.parse(jsonString); 45 | core.exportVariable('json_electron_version', json.devDependencies.electron.toString()) 46 | } catch(err) { 47 | core.error("Error while reading or parsing package.json") 48 | core.setFailed(err) 49 | } 50 | 51 | - name: setup electron version 52 | shell: bash 53 | if: ${{ inputs.replace-version == 'true' }} 54 | run: | 55 | sed -i -e 's/\${{ env.json_electron_version}}/=${{ inputs.electron }}/g' package.json 56 | 57 | - name: Cache node-gyp Linux 58 | if: runner.os == 'Linux' 59 | uses: actions/cache@v4 60 | env: 61 | cache-name: cache-node-gyp 62 | with: 63 | path: ~/.cache/node-gyp 64 | key: '${{ inputs.os }}-${{ inputs.electron}}' 65 | 66 | - name: Cache node-gyp macOS 67 | if: runner.os == 'macOS' 68 | uses: actions/cache@v4 69 | env: 70 | cache-name: cache-node-gyp 71 | with: 72 | path: ~/Library/Caches/node-gyp 73 | key: '${{ inputs.os }}-${{ inputs.electron}}' 74 | 75 | - name: Cache node modules 76 | id: cache-nodemodules 77 | uses: actions/cache@v4 78 | env: 79 | cache-name: cache-node-modules 80 | with: 81 | path: node_modules 82 | key: ${{ inputs.os }}-${{ inputs.electron }}-${{ hashFiles('package.json') }} 83 | 84 | - name: Setup dotnet 85 | uses: actions/setup-dotnet@v4 86 | with: 87 | dotnet-version: '8.0.x' # SDK Version to use; x will use the latest version of the 8.0 channel 88 | 89 | - name: Setup Mono 90 | if: runner.os == 'macOS' 91 | shell: bash 92 | run: | 93 | brew install mono --overwrite 94 | brew reinstall pkg-config 95 | 96 | # - name: Setup Mono 97 | # if: runner.os == 'Linux' 98 | # shell: bash 99 | # run: | 100 | # sudo apt -q install mono-complete pkg-config gdb 101 | 102 | - name: Versions 103 | shell: bash 104 | run: | 105 | node -v && npm -v && dotnet --version && node -p process.platform && node -p process.arch 106 | 107 | - name: npm install 108 | shell: bash 109 | run: npm i 110 | env: 111 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | electron: 7 | description: 'Electron version to build' 8 | required: true 9 | default: '30' 10 | type: choice 11 | options: 12 | - 31 13 | - 32 14 | - 33 15 | - 34 16 | - 35 17 | - 36 18 | 19 | env: 20 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 21 | DOTNET_NOLOGO: 1 22 | 23 | jobs: 24 | build: 25 | runs-on: ${{ matrix.os }} 26 | outputs: 27 | test-version: ${{ steps.electron-test-version.outputs.test-version }} 28 | strategy: 29 | matrix: 30 | # os: [macos-13, macos-15] 31 | os: [windows-2025, macos-13, macos-15] 32 | fail-fast: true 33 | 34 | name: build electron-${{ inputs.electron }} ${{ matrix.os }} 35 | steps: 36 | 37 | - name: Checkout code 38 | uses: actions/checkout@v4 39 | 40 | - name: npm install 41 | shell: bash 42 | run: npm i 43 | 44 | - name: Get latest Electron version for ${{ inputs.electron }} 45 | id: electron-test-version 46 | shell: bash 47 | run: | 48 | node tools/getVersion.js ${{ inputs.electron }} 49 | echo "test-version=$(cat electron.txt)" >> $GITHUB_OUTPUT 50 | 51 | - name: Build Electron ${{ inputs.electron }} 52 | uses: ./.github/actions/build-electron 53 | with: 54 | electron: ${{ inputs.electron }} 55 | os: ${{ matrix.os }} 56 | 57 | 58 | upload-artifacts: 59 | runs-on: ubuntu-latest 60 | needs: test 61 | strategy: 62 | fail-fast: false 63 | 64 | name: upload artifacts electron-${{ inputs.electron }} 65 | steps: 66 | 67 | - name: Download artifacts 68 | uses: actions/download-artifact@v4 69 | if: success() 70 | with: 71 | path: release 72 | pattern: win32-electron-edge-js* 73 | 74 | - name: Download artifacts 75 | uses: actions/download-artifact@v4 76 | if: success() 77 | with: 78 | path: release 79 | pattern: darwin-electron-edge-js* 80 | 81 | - name: Upload artifacts 82 | uses: actions/upload-artifact/merge@v4 83 | if: success() 84 | with: 85 | name: electron-edge-js-${{ inputs.electron }} 86 | 87 | test: 88 | runs-on: ${{ matrix.os }} 89 | needs: build 90 | strategy: 91 | matrix: 92 | # os: [windows-2022] 93 | os: [windows-2025, windows-11-arm, macos-13, macos-15] 94 | fail-fast: false 95 | 96 | name: test electron-${{ needs.build.outputs.test-version }} ${{ matrix.os }} 97 | steps: 98 | 99 | - name: Checkout code 100 | uses: actions/checkout@v4 101 | 102 | - name: Test build 103 | uses: ./.github/actions/test-build 104 | timeout-minutes: 10 105 | with: 106 | electron: ${{ needs.build.outputs.test-version }} 107 | os: ${{ matrix.os }} 108 | 109 | -------------------------------------------------------------------------------- /.github/workflows/ci-old.yml: -------------------------------------------------------------------------------- 1 | name: CI out of support 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | paths-ignore: 7 | - 'samples/*' 8 | - 'stress/*' 9 | - 'performance/*' 10 | - '.github/FUNDING.YML' 11 | - '.github/workflows/ci.yml' 12 | - '.github/workflows/build.yml' 13 | - '.github/workflows/build*.yml' 14 | - '.github/actions/test-build/action.yml' 15 | - '.github/actions/build*/*.*' 16 | - '.github/actions/build/*.*' 17 | - '**/*.md' 18 | - '**/*.d.ts' 19 | - '**/*.bat' 20 | - '.travis.yml' 21 | - 'Dockerfile' 22 | - '.gitconfig' 23 | - '.gitignore' 24 | - 'appveyor*.*' 25 | - 'LICENSE*' 26 | - '.idea/**' 27 | - '.vscode/**' 28 | - '*.bat' 29 | - '*.nuspec' 30 | - 'tools/nuget/*' 31 | - '.npmignore' 32 | - 'test/config.json' 33 | - 'test/double' 34 | - '.circleci' 35 | - '.circleci/*' 36 | - 'README.md' 37 | - '*.sln' 38 | - '*.vcxproj' 39 | push: 40 | branches-ignore: 41 | - 'circleci' 42 | paths-ignore: 43 | - 'samples/*' 44 | - 'stress/*' 45 | - 'performance/*' 46 | - '.github/FUNDING.YML' 47 | - '.github/workflows/ci.yml' 48 | - '.github/workflows/build.yml' 49 | - '.github/workflows/build*.yml' 50 | - '.github/actions/test-build/action.yml' 51 | - '.github/actions/build*/*.*' 52 | - '.github/actions/build/*.*' 53 | - '**/*.md' 54 | - '**/*.d.ts' 55 | - '**/*.bat' 56 | - '.travis.yml' 57 | - 'Dockerfile' 58 | - '.gitconfig' 59 | - '.gitignore' 60 | - 'appveyor*.*' 61 | - 'LICENSE*' 62 | - '.idea/**' 63 | - '.vscode/**' 64 | - '*.bat' 65 | - '*.nuspec' 66 | - 'tools/nuget/*' 67 | - '.npmignore' 68 | - 'test/config.json' 69 | - 'test/double' 70 | - '.circleci' 71 | - '.circleci/*' 72 | - 'README.md' 73 | - '*.sln' 74 | - '*.vcxproj' 75 | 76 | env: 77 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true # required to setup CSC 78 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 79 | DOTNET_NOLOGO: 1 80 | 81 | jobs: 82 | test: 83 | runs-on: ${{ matrix.os }} 84 | strategy: 85 | fail-fast: false 86 | matrix: 87 | os: [macos-13, macos-15, ubuntu-22.04, ubuntu-22.04-arm] 88 | electron: [29.4.6, 30.5.1] 89 | # electron: [29.4.6, 30.5.1, 31.7.7, 32.3.3, 33.4.9, 34.0.1] 90 | 91 | name: test-${{ matrix.os }}-v${{ matrix.electron }} 92 | steps: 93 | - name: Checkout code 94 | uses: actions/checkout@v4 95 | 96 | - name: Setup env 97 | uses: ./.github/actions/setup-env 98 | with: 99 | electron: ${{ matrix.electron }} 100 | os: ${{ matrix.os }} 101 | replace-version: true 102 | 103 | - if: runner.os == 'Linux' || runner.os == 'macOS' 104 | name: Check electron-edge-js build file 105 | id: check_build 106 | uses: andstor/file-existence-action@v3 107 | with: 108 | files: "build/Release/edge_coreclr.node" 109 | fail: true 110 | ignore_case: true 111 | 112 | - if: runner.os == 'macOS' || runner.os == 'Windows' 113 | name: Run .NET 4.5/Mono tests 114 | run: node tools/test.js CI 115 | timeout-minutes: 10 116 | 117 | - if: runner.os == 'macOS' || runner.os == 'Windows' 118 | name: "Run .net core tests" 119 | run: node tools/test.js CI 120 | timeout-minutes: 10 121 | env: 122 | EDGE_USE_CORECLR: 1 123 | 124 | # - if: runner.os == 'Linux' 125 | # name: Run Mono tests 126 | # timeout-minutes: 10 127 | # run: | 128 | # export DISPLAY=:99 129 | # echo "DISPLAY=:99" >> $GITHUB_ENV 130 | # Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & 131 | # sleep 3 132 | # node tools/test.js CI 133 | 134 | - if: runner.os == 'Linux' 135 | name: "Run .net core tests Linux" 136 | timeout-minutes: 10 137 | run: | 138 | export DISPLAY=:99 139 | echo "DISPLAY=:99" >> $GITHUB_ENV 140 | Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & 141 | sleep 3 142 | node tools/test.js CI 143 | env: 144 | EDGE_USE_CORECLR: 1 145 | 146 | - name: Test report 147 | uses: ./.github/actions/create-test-report 148 | with: 149 | electron: ${{ matrix.electron }} 150 | os: ${{ matrix.os }} 151 | 152 | 153 | -------------------------------------------------------------------------------- /.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 | tools/nuget/content 68 | tools/nuget/lib 69 | tools/nuget/*.nupkg 70 | tools/nuget/*.zip 71 | tools/*.nupkg 72 | tools/*.zip 73 | tools/nuget.exe 74 | 75 | *test-results*.* 76 | TemporaryGeneratedFile*.* 77 | /lib/native/win32/ia32/*/concrt140.dll 78 | /lib/native/win32/ia32/*/msvcp140.dll 79 | /lib/native/win32/ia32/*/vccorlib140.dll 80 | /lib/native/win32/ia32/*/vcruntime140.dll 81 | 82 | /lib/native/win32/x64/*/concrt140.dll 83 | /lib/native/win32/x64/*/msvcp140.dll 84 | /lib/native/win32/x64/*/vccorlib140.dll 85 | /lib/native/win32/x64/*/vcruntime140.dll 86 | 87 | /lib/native/win32/arm64/*/concrt140.dll 88 | /lib/native/win32/arm64/*/msvcp140.dll 89 | /lib/native/win32/arm64/*/vccorlib140.dll 90 | /lib/native/win32/arm64/*/vcruntime140.dll 91 | 92 | test/mochawesome-report 93 | mochawesome-report 94 | mochawesome.json 95 | 96 | release 97 | *.zip 98 | electron*.txt 99 | 100 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 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 | tools/nuget/content 68 | tools/nuget/lib 69 | tools/nuget/*.zip 70 | tools/*.zip 71 | tools/nuget.exe 72 | 73 | test-results*.* 74 | /lib/native/win32/ia32/*/concrt140.dll 75 | /lib/native/win32/ia32/*/msvcp140.dll 76 | /lib/native/win32/ia32/*/vccorlib140.dll 77 | /lib/native/win32/ia32/*/vcruntime140.dll 78 | 79 | /lib/native/win32/x64/*/concrt140.dll 80 | /lib/native/win32/x64/*/msvcp140.dll 81 | /lib/native/win32/x64/*/vccorlib140.dll 82 | /lib/native/win32/x64/*/vcruntime140.dll 83 | 84 | /lib/native/win32/arm64/*/concrt140.dll 85 | /lib/native/win32/arm64/*/msvcp140.dll 86 | /lib/native/win32/arm64/*/vccorlib140.dll 87 | /lib/native/win32/arm64/*/vcruntime140.dll 88 | 89 | test 90 | stress 91 | samples 92 | performance 93 | *.bat 94 | tools/*.cs 95 | tools/*.vbs 96 | tools/nuget 97 | *.nupkg 98 | appveyor*.* 99 | .github 100 | tools/coverage.js 101 | tools/test*.js 102 | tools/download*.js 103 | test/mochawesome-report 104 | mochawesome-report 105 | mochawesome.json 106 | *.zip 107 | *.sln 108 | xunit*.* 109 | getVersion*.js 110 | *.vcxproj 111 | getVersion*.js 112 | electron*.txt -------------------------------------------------------------------------------- /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}") = "bootstrap", "lib\bootstrap\bootstrap.csproj", "{9AF3DB99-E51A-463F-896A-A9F6123C6999}" 8 | EndProject 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|Any CPU = Debug|Any CPU 12 | Release|Any CPU = Release|Any CPU 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 16 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Debug|Any CPU.Build.0 = Debug|Any CPU 17 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Release|Any CPU.ActiveCfg = Release|Any CPU 18 | {D232E683-ED16-4B7B-BD76-44A9DE96F79E}.Release|Any CPU.Build.0 = Release|Any CPU 19 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {E94194B3-965D-4CC5-8080-C897A9B607E9}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {9AF3DB99-E51A-463F-896A-A9F6123C6999}.Release|Any CPU.Build.0 = Release|Any CPU 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2024 Tomasz Janczuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /electron-edge-js.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'electron-edge-js' { 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 | } -------------------------------------------------------------------------------- /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 | net6.0 5 | true 6 | bootstrap 7 | bootstrap 8 | default 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /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/electronPath.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const _path = require('path'); 3 | 4 | const normalizeElectronPath = function(s) { 5 | const alp = s.replace(/app\.asar(?!\.unpacked)/g, 'app.asar.unpacked'); 6 | 7 | let inAsarUnpacked = false; 8 | 9 | if (fs.existsSync(alp)) { 10 | inAsarUnpacked = true; 11 | } else { 12 | try { 13 | require.resolve(alp); 14 | inAsarUnpacked = true; 15 | } catch(e) {} 16 | } 17 | 18 | return inAsarUnpacked ? alp : s; 19 | } 20 | 21 | const join = function() { 22 | return normalizeElectronPath(_path.join.apply(this, arguments)); 23 | } 24 | 25 | const resolve = function() { 26 | return normalizeElectronPath(_path.resolve.apply(this, arguments)); 27 | } 28 | 29 | const normalize = function() { 30 | return normalizeElectronPath(_path.normalize.apply(this, arguments)); 31 | } 32 | 33 | module.exports = { 34 | join, 35 | resolve, 36 | normalize, 37 | normalizeElectronPath, 38 | }; 39 | -------------------------------------------------------------------------------- /lib/native/darwin/arm64/31/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/31/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/arm64/31/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/31/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/31/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/31/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/32/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/32/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/arm64/32/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/32/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/32/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/32/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/33/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/33/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/arm64/33/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/33/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/33/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/33/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/34/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/34/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/arm64/34/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/34/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/34/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/34/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/35/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/35/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/arm64/35/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/35/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/35/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/35/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/36/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/36/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/arm64/36/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/36/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/arm64/36/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/arm64/36/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/31/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/31/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/x64/31/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/31/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/31/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/31/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/32/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/32/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/x64/32/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/32/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/32/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/32/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/33/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/33/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/x64/33/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/33/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/33/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/33/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/34/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/34/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/x64/34/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/34/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/34/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/34/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/35/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/35/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/x64/35/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/35/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/35/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/35/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/36/MonoEmbedding.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/36/MonoEmbedding.exe -------------------------------------------------------------------------------- /lib/native/darwin/x64/36/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/36/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/darwin/x64/36/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/darwin/x64/36/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/31/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/31/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/31/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/31/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/32/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/32/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/32/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/32/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/33/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/33/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/33/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/33/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/34/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/34/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/34/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/34/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/35/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/35/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/35/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/35/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/36/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/36/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/36/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/36/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/arm64/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/arm64/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/arm64/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/arm64/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/arm64/vcruntime140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/.gitignore: -------------------------------------------------------------------------------- 1 | [0-9]*/*.dll 2 | -------------------------------------------------------------------------------- /lib/native/win32/ia32/31/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/31/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/31/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/31/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/32/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/32/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/32/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/32/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/33/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/33/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/33/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/33/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/34/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/34/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/34/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/34/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/35/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/35/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/35/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/35/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/36/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/36/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/36/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/36/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/ia32/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/ia32/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/ia32/vcruntime140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/.gitignore: -------------------------------------------------------------------------------- 1 | [0-9]*/*.dll 2 | -------------------------------------------------------------------------------- /lib/native/win32/x64/31/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/31/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/31/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/31/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/32/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/32/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/32/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/32/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/33/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/33/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/33/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/33/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/34/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/34/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/34/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/34/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/35/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/35/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/35/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/35/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/36/edge_coreclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/36/edge_coreclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/36/edge_nativeclr.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/36/edge_nativeclr.node -------------------------------------------------------------------------------- /lib/native/win32/x64/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/concrt140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/msvcp140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/vccorlib140.dll -------------------------------------------------------------------------------- /lib/native/win32/x64/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/lib/native/win32/x64/vcruntime140.dll -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-edge-js", 3 | "author": { 4 | "name": "Tomasz Janczuk ", 5 | "url": "http://tomasz.janczuk.org", 6 | "twitter": "tjanczuk" 7 | }, 8 | "version": "36.0.1", 9 | "description": "Edge.js: run .NET and Node.js in-process on Electron", 10 | "tags": [ 11 | "owin", 12 | "edge", 13 | "net", 14 | "clr", 15 | "coreclr", 16 | "c#", 17 | "mono", 18 | "managed", 19 | ".net", 20 | "edge-js", 21 | "electron" 22 | ], 23 | "keywords": [ 24 | "owin", 25 | "edge", 26 | "net", 27 | "clr", 28 | "coreclr", 29 | "c#", 30 | "mono", 31 | "managed", 32 | ".net", 33 | "edge-js", 34 | "electron" 35 | ], 36 | "main": "./lib/edge.js", 37 | "types": "electron-edge-js.d.ts", 38 | "engines": { 39 | "npm": ">=8.0.0", 40 | "node": ">=16.0.0" 41 | }, 42 | "license": "MIT", 43 | "dependencies": { 44 | "edge-cs": "npm:@agracio/edge-cs@^1.3.7", 45 | "nan": "^2.22.2" 46 | }, 47 | "devDependencies": { 48 | "electron": "^36.2.0", 49 | "follow-redirects": "^1.15.9", 50 | "isomorphic-git": "^1.30.1", 51 | "mocha": "11.2.2", 52 | "mochawesome": "^7.1.3", 53 | "mochawesome-merge": "^5.0.0", 54 | "mochawesome-report-generator": "^6.2.0" 55 | }, 56 | "homepage": "https://github.com/agracio/electron-edge-js", 57 | "repository": { 58 | "type": "git", 59 | "url": "git+ssh://git@github.com/agracio/electron-edge-js.git" 60 | }, 61 | "bugs": { 62 | "url": "http://github.com/agracio/electron-edge-js/issues" 63 | }, 64 | "scripts": { 65 | "install": "node tools/install.js", 66 | "test": "node tools/test.js" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /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/coreclrnodejsfuncinvokecontext.cpp: -------------------------------------------------------------------------------- 1 | #include "edge.h" 2 | 3 | NAN_METHOD(coreClrV8FuncCallback) 4 | { 5 | DBG("coreClrV8FuncCallback"); 6 | 7 | Nan::HandleScope scope; 8 | v8::Local correlator = v8::Local::Cast(info[2]); 9 | CoreClrNodejsFuncInvokeContext* context = (CoreClrNodejsFuncInvokeContext*)(correlator->Value()); 10 | 11 | if (!info[0]->IsUndefined() && !info[0]->IsNull()) 12 | { 13 | void* clrExceptionData; 14 | CoreClrFunc::MarshalV8ExceptionToCLR(info[0], &clrExceptionData); 15 | 16 | context->Complete(TaskStatusFaulted, clrExceptionData, V8TypeException); 17 | } 18 | 19 | else 20 | { 21 | void* marshalData; 22 | int payloadType; 23 | 24 | CoreClrFunc::MarshalV8ToCLR(info[1], &marshalData, &payloadType); 25 | context->Complete(TaskStatusRanToCompletion, marshalData, payloadType); 26 | } 27 | 28 | info.GetReturnValue().SetUndefined(); 29 | } 30 | 31 | CoreClrNodejsFuncInvokeContext::CoreClrNodejsFuncInvokeContext(void* payload, int payloadType, CoreClrNodejsFunc* functionContext, CoreClrGcHandle callbackContext, NodejsFuncCompleteFunction callbackFunction) 32 | { 33 | DBG("CoreClrNodejsFuncInvokeContext::CoreClrNodejsFuncInvokeContext"); 34 | 35 | uv_edge_async = NULL; 36 | Payload = payload; 37 | PayloadType = payloadType; 38 | FunctionContext = functionContext; 39 | CallbackContext = callbackContext; 40 | CallbackFunction = callbackFunction; 41 | } 42 | 43 | CoreClrNodejsFuncInvokeContext::~CoreClrNodejsFuncInvokeContext() 44 | { 45 | if (uv_edge_async) 46 | { 47 | delete uv_edge_async; 48 | } 49 | 50 | if (Payload) 51 | { 52 | CoreClrFunc::FreeMarshalData(Payload, PayloadType); 53 | } 54 | } 55 | 56 | void CoreClrNodejsFuncInvokeContext::Complete(TaskStatus taskStatus, void* result, int resultType) 57 | { 58 | DBG("CoreClrNodejsFuncInvokeContext::Complete"); 59 | CallbackFunction(CallbackContext, taskStatus, result, resultType); 60 | } 61 | 62 | void CoreClrNodejsFuncInvokeContext::Invoke() 63 | { 64 | this->uv_edge_async = V8SynchronizationContext::RegisterAction(CoreClrNodejsFuncInvokeContext::InvokeCallback, this); 65 | V8SynchronizationContext::ExecuteAction(uv_edge_async); 66 | } 67 | 68 | void CoreClrNodejsFuncInvokeContext::InvokeCallback(void* data) 69 | { 70 | DBG("CoreClrNodejsFuncInvokeContext::InvokeCallback"); 71 | 72 | CoreClrNodejsFuncInvokeContext* context = (CoreClrNodejsFuncInvokeContext*) data; 73 | v8::Local v8Payload = CoreClrFunc::MarshalCLRToV8(context->Payload, context->PayloadType); 74 | 75 | static Nan::Persistent callbackFactory; 76 | static Nan::Persistent callbackFunction; 77 | v8::Isolate *isolate = v8::Isolate::GetCurrent(); 78 | v8::Local localContext = isolate->GetCurrentContext(); 79 | 80 | Nan::HandleScope scope; 81 | 82 | // See https://github.com/tjanczuk/edge/issues/125 for context 83 | if (callbackFactory.IsEmpty()) 84 | { 85 | v8::Local v8FuncCallbackFunction = Nan::GetFunction(Nan::New(coreClrV8FuncCallback)).ToLocalChecked(); 86 | callbackFunction.Reset(v8FuncCallbackFunction); 87 | v8::Local code = Nan::New( 88 | "(function (cb, ctx) { return function (e, d) { return cb(e, d, ctx); }; })").ToLocalChecked(); 89 | v8::Local callbackFactoryFunction = 90 | v8::Local::Cast( 91 | v8::Script::Compile(localContext, code, nullptr).ToLocalChecked() 92 | ->Run(localContext).ToLocalChecked()); 93 | callbackFactory.Reset(callbackFactoryFunction); 94 | } 95 | 96 | v8::Local factoryArgv[] = { Nan::New(callbackFunction), Nan::New((void*)context) }; 97 | v8::Local callback = v8::Local::Cast( 98 | Nan::Call(Nan::New(callbackFactory), Nan::GetCurrentContext()->Global(), 2, factoryArgv).ToLocalChecked()); 99 | 100 | v8::Local argv[] = { v8Payload, callback }; 101 | Nan::TryCatch tryCatch; 102 | 103 | DBG("CoreClrNodejsFuncInvokeContext::InvokeCallback - Calling JavaScript function"); 104 | Nan::Call(Nan::New(*(context->FunctionContext->Func)), Nan::GetCurrentContext()->Global(), 2, argv); 105 | // Free allocated memory 106 | CoreClrFunc::FreeMarshalData(context->Payload, context->PayloadType); 107 | DBG("CoreClrNodejsFuncInvokeContext::InvokeCallback - Called JavaScript function"); 108 | 109 | if (tryCatch.HasCaught()) 110 | { 111 | DBG("CoreClrNodejsFuncInvokeContext::InvokeCallback - Caught JavaScript exception"); 112 | 113 | void* exceptionData; 114 | CoreClrFunc::MarshalV8ExceptionToCLR(tryCatch.Exception(), &exceptionData); 115 | 116 | DBG("CoreClrNodejsFuncInvokeContext::InvokeCallback - Exception message is: %s", (char*)exceptionData); 117 | 118 | context->Complete(TaskStatusFaulted, exceptionData, V8TypeException); 119 | } 120 | else 121 | { 122 | // Kick the next tick 123 | CallbackHelper::KickNextTick(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /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 | * Copyright (C) Microsoft. All rights reserved. 3 | * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. 4 | * 5 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 6 | * 7 | * Platform-dependent type definitions 8 | * 9 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 10 | * 11 | * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 12 | ****/ 13 | 14 | #pragma once 15 | 16 | #include "cpprest/details/cpprest_compat.h" 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #ifndef _WIN32 23 | #ifndef __STDC_LIMIT_MACROS 24 | #define __STDC_LIMIT_MACROS 25 | #endif 26 | #include 27 | #else 28 | #include 29 | #endif 30 | 31 | #include "cpprest/details/SafeInt3.hpp" 32 | 33 | namespace utility 34 | { 35 | #ifdef _WIN32 36 | #define _UTF16_STRINGS 37 | #endif 38 | 39 | // We should be using a 64-bit size type for most situations that do 40 | // not involve specifying the size of a memory allocation or buffer. 41 | typedef uint64_t size64_t; 42 | 43 | #ifndef _WIN32 44 | typedef uint32_t HRESULT; // Needed for PPLX 45 | #endif 46 | 47 | #ifdef _UTF16_STRINGS 48 | // 49 | // On Windows, all strings are wide 50 | // 51 | typedef wchar_t char_t; 52 | typedef std::wstring string_t; 53 | #define _XPLATSTR(x) L##x 54 | typedef std::wostringstream ostringstream_t; 55 | typedef std::wofstream ofstream_t; 56 | typedef std::wostream ostream_t; 57 | typedef std::wistream istream_t; 58 | typedef std::wifstream ifstream_t; 59 | typedef std::wistringstream istringstream_t; 60 | typedef std::wstringstream stringstream_t; 61 | #define ucout std::wcout 62 | #define ucin std::wcin 63 | #define ucerr std::wcerr 64 | #else 65 | // 66 | // On POSIX platforms, all strings are narrow 67 | // 68 | typedef char char_t; 69 | typedef std::string string_t; 70 | #define _XPLATSTR(x) x 71 | typedef std::ostringstream ostringstream_t; 72 | typedef std::ofstream ofstream_t; 73 | typedef std::ostream ostream_t; 74 | typedef std::istream istream_t; 75 | typedef std::ifstream ifstream_t; 76 | typedef std::istringstream istringstream_t; 77 | typedef std::stringstream stringstream_t; 78 | #define ucout std::cout 79 | #define ucin std::cin 80 | #define ucerr std::cerr 81 | #endif // endif _UTF16_STRINGS 82 | 83 | #ifndef _TURN_OFF_PLATFORM_STRING 84 | // The 'U' macro can be used to create a string or character literal of the platform type, i.e. utility::char_t. 85 | // If you are using a library causing conflicts with 'U' macro, it can be turned off by defining the macro 86 | // '_TURN_OFF_PLATFORM_STRING' before including the C++ REST SDK header files, and e.g. use '_XPLATSTR' instead. 87 | #define U(x) _XPLATSTR(x) 88 | #endif // !_TURN_OFF_PLATFORM_STRING 89 | 90 | } // namespace utility 91 | 92 | typedef char utf8char; 93 | typedef std::string utf8string; 94 | typedef std::stringstream utf8stringstream; 95 | typedef std::ostringstream utf8ostringstream; 96 | typedef std::ostream utf8ostream; 97 | typedef std::istream utf8istream; 98 | typedef std::istringstream utf8istringstream; 99 | 100 | #ifdef _UTF16_STRINGS 101 | typedef wchar_t utf16char; 102 | typedef std::wstring utf16string; 103 | typedef std::wstringstream utf16stringstream; 104 | typedef std::wostringstream utf16ostringstream; 105 | typedef std::wostream utf16ostream; 106 | typedef std::wistream utf16istream; 107 | typedef std::wistringstream utf16istringstream; 108 | #else 109 | typedef char16_t utf16char; 110 | typedef std::u16string utf16string; 111 | typedef std::basic_stringstream utf16stringstream; 112 | typedef std::basic_ostringstream utf16ostringstream; 113 | typedef std::basic_ostream utf16ostream; 114 | typedef std::basic_istream utf16istream; 115 | typedef std::basic_istringstream utf16istringstream; 116 | #endif 117 | 118 | #if defined(_WIN32) 119 | // Include on everything except Windows Desktop ARM, unless explicitly excluded. 120 | #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) 121 | #if defined(WINAPI_FAMILY) 122 | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_M_ARM) 123 | #define CPPREST_EXCLUDE_WEBSOCKETS 124 | #endif 125 | #else 126 | #if defined(_M_ARM) 127 | #define CPPREST_EXCLUDE_WEBSOCKETS 128 | #endif 129 | #endif 130 | #endif 131 | #endif 132 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/cpprest/details/cpprest_compat.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * Copyright (C) Microsoft. All rights reserved. 3 | * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. 4 | * 5 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 6 | * 7 | * Standard macros and definitions. 8 | * This header has minimal dependency on windows headers and is safe for use in the public API 9 | * 10 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 11 | * 12 | * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 13 | ****/ 14 | 15 | #pragma once 16 | 17 | #if defined(_WIN32) 18 | 19 | #if _MSC_VER >= 1900 20 | #define CPPREST_NOEXCEPT noexcept 21 | #define CPPREST_CONSTEXPR constexpr 22 | #else 23 | #define CPPREST_NOEXCEPT 24 | #define CPPREST_CONSTEXPR const 25 | #endif // _MSC_VER >= 1900 26 | 27 | #include 28 | 29 | #else // ^^^ _WIN32 ^^^ // vvv !_WIN32 vvv 30 | 31 | #define __declspec(x) __attribute__((x)) 32 | #define dllimport 33 | #define novtable /* no novtable equivalent */ 34 | #define __assume(x) \ 35 | do \ 36 | { \ 37 | if (!(x)) __builtin_unreachable(); \ 38 | } while (false) 39 | #define CPPREST_NOEXCEPT noexcept 40 | #define CPPREST_CONSTEXPR constexpr 41 | 42 | #include 43 | #define _ASSERTE(x) assert(x) 44 | 45 | // No SAL on non Windows platforms 46 | #include "cpprest/details/nosal.h" 47 | 48 | #if !defined(__cdecl) 49 | #if defined(cdecl) 50 | #define __cdecl __attribute__((cdecl)) 51 | #else // ^^^ defined cdecl ^^^ // vvv !defined cdecl vvv 52 | #define __cdecl 53 | #endif // defined cdecl 54 | #endif // not defined __cdecl 55 | 56 | #if defined(__ANDROID__) 57 | // This is needed to disable the use of __thread inside the boost library. 58 | // Android does not support thread local storage -- if boost is included 59 | // without this macro defined, it will create references to __tls_get_addr 60 | // which (while able to link) will not be available at runtime and prevent 61 | // the .so from loading. 62 | #if not defined BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION 63 | #define BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION 64 | #endif // not defined BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION 65 | #endif // defined(__ANDROID__) 66 | 67 | #ifdef __clang__ 68 | #include 69 | #endif // __clang__ 70 | #endif // _WIN32 71 | 72 | #ifdef _NO_ASYNCRTIMP 73 | #define _ASYNCRTIMP 74 | #define _ASYNCRTIMP_TYPEINFO 75 | #else // ^^^ _NO_ASYNCRTIMP ^^^ // vvv !_NO_ASYNCRTIMP vvv 76 | #ifdef _ASYNCRT_EXPORT 77 | #define _ASYNCRTIMP __declspec(dllexport) 78 | #else // ^^^ _ASYNCRT_EXPORT ^^^ // vvv !_ASYNCRT_EXPORT vvv 79 | #define _ASYNCRTIMP __declspec(dllimport) 80 | #endif // _ASYNCRT_EXPORT 81 | 82 | #if defined(_WIN32) 83 | #define _ASYNCRTIMP_TYPEINFO 84 | #else // ^^^ _WIN32 ^^^ // vvv !_WIN32 vvv 85 | #define _ASYNCRTIMP_TYPEINFO __attribute__((visibility("default"))) 86 | #endif // _WIN32 87 | 88 | #endif // _NO_ASYNCRTIMP 89 | 90 | #ifdef CASABLANCA_DEPRECATION_NO_WARNINGS 91 | #define CASABLANCA_DEPRECATED(x) 92 | #else 93 | #define CASABLANCA_DEPRECATED(x) __declspec(deprecated(x)) 94 | #endif // CASABLANCA_DEPRECATION_NO_WARNINGS 95 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/cpprest/details/nosal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * Copyright (C) Microsoft. All rights reserved. 3 | * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. 4 | * 5 | * 6 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 7 | * 8 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 9 | ***/ 10 | 11 | #pragma once 12 | // selected MS SAL annotations 13 | 14 | #ifdef _In_ 15 | #undef _In_ 16 | #endif 17 | #define _In_ 18 | 19 | #ifdef _Inout_ 20 | #undef _Inout_ 21 | #endif 22 | #define _Inout_ 23 | 24 | #ifdef _Out_ 25 | #undef _Out_ 26 | #endif 27 | #define _Out_ 28 | 29 | #ifdef _In_z_ 30 | #undef _In_z_ 31 | #endif 32 | #define _In_z_ 33 | 34 | #ifdef _Out_z_ 35 | #undef _Out_z_ 36 | #endif 37 | #define _Out_z_ 38 | 39 | #ifdef _Inout_z_ 40 | #undef _Inout_z_ 41 | #endif 42 | #define _Inout_z_ 43 | 44 | #ifdef _In_opt_ 45 | #undef _In_opt_ 46 | #endif 47 | #define _In_opt_ 48 | 49 | #ifdef _Out_opt_ 50 | #undef _Out_opt_ 51 | #endif 52 | #define _Out_opt_ 53 | 54 | #ifdef _Inout_opt_ 55 | #undef _Inout_opt_ 56 | #endif 57 | #define _Inout_opt_ 58 | 59 | #ifdef _Out_writes_ 60 | #undef _Out_writes_ 61 | #endif 62 | #define _Out_writes_(x) 63 | 64 | #ifdef _Out_writes_opt_ 65 | #undef _Out_writes_opt_ 66 | #endif 67 | #define _Out_writes_opt_(x) 68 | 69 | #ifdef _In_reads_ 70 | #undef _In_reads_ 71 | #endif 72 | #define _In_reads_(x) 73 | 74 | #ifdef _Inout_updates_bytes_ 75 | #undef _Inout_updates_bytes_ 76 | #endif 77 | #define _Inout_updates_bytes_(x) 78 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/pplx/pplxconv.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * Copyright (C) Microsoft. All rights reserved. 3 | * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. 4 | * 5 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 6 | * 7 | * Utilities to convert between PPL tasks and PPLX tasks 8 | * 9 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 10 | * 11 | * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 12 | ****/ 13 | 14 | #pragma once 15 | 16 | #ifndef _PPLXCONV_H 17 | #define _PPLXCONV_H 18 | 19 | #ifndef _WIN32 20 | #error This is only supported on Windows 21 | #endif 22 | 23 | #if defined(_MSC_VER) && (_MSC_VER >= 1700) && (_MSC_VER < 1800) && !CPPREST_FORCE_PPLX 24 | 25 | #include "pplx/pplxtasks.h" 26 | #include 27 | 28 | namespace pplx 29 | { 30 | namespace _Ppl_conv_helpers 31 | { 32 | template 33 | auto _Set_value(_Tc _Tcp, const _F& _Func) -> decltype(_Tcp.set(_Func())) 34 | { 35 | return _Tcp.set(_Func()); 36 | } 37 | 38 | template 39 | auto _Set_value(_Tc _Tcp, const _F& _Func, ...) -> decltype(_Tcp.set()) 40 | { 41 | _Func(); 42 | return _Tcp.set(); 43 | } 44 | 45 | template 46 | _OtherTaskType _Convert_task(_TaskType _Task) 47 | { 48 | _OtherTCEType _Tc; 49 | _Task.then([_Tc](_TaskType _Task2) { 50 | try 51 | { 52 | _Ppl_conv_helpers::_Set_value(_Tc, [=] { return _Task2.get(); }); 53 | } 54 | catch (...) 55 | { 56 | _Tc.set_exception(std::current_exception()); 57 | } 58 | }); 59 | _OtherTaskType _T_other(_Tc); 60 | return _T_other; 61 | } 62 | } // namespace _Ppl_conv_helpers 63 | 64 | template 65 | concurrency::task<_TaskType> pplx_task_to_concurrency_task(pplx::task<_TaskType> _Task) 66 | { 67 | return _Ppl_conv_helpers::_Convert_task, 68 | concurrency::task<_TaskType>, 69 | concurrency::task_completion_event<_TaskType>>(_Task); 70 | } 71 | 72 | template 73 | pplx::task<_TaskType> concurrency_task_to_pplx_task(concurrency::task<_TaskType> _Task) 74 | { 75 | return _Ppl_conv_helpers::_Convert_task, 76 | pplx::task<_TaskType>, 77 | pplx::task_completion_event<_TaskType>>(_Task); 78 | } 79 | } // namespace pplx 80 | 81 | #endif 82 | 83 | #endif // _PPLXCONV_H 84 | -------------------------------------------------------------------------------- /src/CoreCLREmbedding/json/casablanca/include/pplx/threadpool.h: -------------------------------------------------------------------------------- 1 | /*** 2 | * Copyright (C) Microsoft. All rights reserved. 3 | * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. 4 | * 5 | * 6 | * Simple Linux implementation of a static thread pool. 7 | * 8 | * For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk 9 | * 10 | * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 11 | ***/ 12 | #pragma once 13 | 14 | #if defined(__clang__) 15 | #pragma clang diagnostic push 16 | #pragma clang diagnostic ignored "-Wconversion" 17 | #pragma clang diagnostic ignored "-Wunreachable-code" 18 | #pragma clang diagnostic ignored "-Winfinite-recursion" 19 | #endif 20 | #include "boost/asio.hpp" 21 | #if defined(__clang__) 22 | #pragma clang diagnostic pop 23 | #endif 24 | 25 | #if defined(__ANDROID__) 26 | #include "pplx/pplx.h" 27 | #include 28 | #include 29 | #endif 30 | 31 | #include "cpprest/details/cpprest_compat.h" 32 | 33 | namespace crossplat 34 | { 35 | #if defined(__ANDROID__) 36 | // IDEA: Break this section into a separate android/jni header 37 | extern std::atomic JVM; 38 | JNIEnv* get_jvm_env(); 39 | 40 | struct java_local_ref_deleter 41 | { 42 | void operator()(jobject lref) const { crossplat::get_jvm_env()->DeleteLocalRef(lref); } 43 | }; 44 | 45 | template 46 | using java_local_ref = std::unique_ptr::type, java_local_ref_deleter>; 47 | #endif 48 | 49 | class threadpool 50 | { 51 | public: 52 | _ASYNCRTIMP static threadpool& shared_instance(); 53 | _ASYNCRTIMP static std::unique_ptr __cdecl construct(size_t num_threads); 54 | 55 | virtual ~threadpool() = default; 56 | 57 | /// 58 | /// Initializes the cpprestsdk threadpool with a custom number of threads 59 | /// 60 | /// 61 | /// This function allows an application (in their main function) to initialize the cpprestsdk 62 | /// threadpool with a custom threadcount. Libraries should avoid calling this function to avoid 63 | /// a diamond problem with multiple consumers attempting to customize the pool. 64 | /// 65 | /// Thrown if the threadpool has already been initialized 66 | static void initialize_with_threads(size_t num_threads); 67 | 68 | template 69 | CASABLANCA_DEPRECATED("Use `.service().post(task)` directly.") 70 | void schedule(T task) 71 | { 72 | service().post(task); 73 | } 74 | 75 | boost::asio::io_service& service() { return m_service; } 76 | 77 | protected: 78 | threadpool(size_t num_threads) : m_service(static_cast(num_threads)) {} 79 | 80 | boost::asio::io_service m_service; 81 | }; 82 | 83 | } // namespace crossplat 84 | -------------------------------------------------------------------------------- /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 | #endif 53 | 54 | #ifndef NOMINMAX 55 | #define NOMINMAX 56 | #endif 57 | 58 | #include 59 | #include 60 | 61 | // Windows Header Files: 62 | #if !defined(__cplusplus_winrt) 63 | #include 64 | 65 | #endif // #if !defined(__cplusplus_winrt) 66 | #else // LINUX or APPLE 67 | #define __STDC_LIMIT_MACROS 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include "pthread.h" 76 | #include 77 | #include 78 | #include 79 | #include 80 | #endif // _WIN32 81 | 82 | // Macro indicating the C++ Rest SDK product itself is being built. 83 | // This is to help track how many developers are directly building from source themselves. 84 | #define _CASA_BUILD_FROM_SRC 85 | 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | 98 | // json 99 | #include "cpprest/json.h" 100 | 101 | #if defined(max) 102 | #error: max macro defined -- make sure to #define NOMINMAX before including windows.h 103 | #endif 104 | #if defined(min) 105 | #error: min macro defined -- make sure to #define NOMINMAX before including windows.h 106 | #endif 107 | 108 | #if defined(__clang__) 109 | #pragma clang diagnostic pop 110 | #endif 111 | 112 | -------------------------------------------------------------------------------- /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.\r\nType: {typeName}, Method: {methodName}, Assembly: {assembly.GetName().FullName}"); 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 | #if NODE_MAJOR_VERSION >= 10 85 | NAN_MODULE_WORKER_ENABLED(edge_coreclr, init) 86 | #else 87 | NODE_MODULE(edge_coreclr, init) 88 | #endif 89 | #else 90 | #if NODE_MAJOR_VERSION >= 10 91 | NAN_MODULE_WORKER_ENABLED(edge_nativeclr, init) 92 | #else 93 | NODE_MODULE(edge_nativeclr, init) 94 | #endif 95 | #endif 96 | // vim: ts=4 sw=4 et: 97 | -------------------------------------------------------------------------------- /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/edge.h: -------------------------------------------------------------------------------- 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 | #ifndef __EDGE_H 18 | #define __EDGE_H 19 | 20 | #include "../common/edge_common.h" 21 | 22 | #include 23 | 24 | #using 25 | #using 26 | 27 | using namespace System::Collections::Generic; 28 | using namespace System::Reflection; 29 | using namespace System::Threading::Tasks; 30 | using namespace System::Threading; 31 | using namespace System::Web::Script::Serialization; 32 | 33 | v8::Local stringCLR2V8(System::String^ text); 34 | System::String^ stringV82CLR(v8::Local text); 35 | System::String^ stringV82CLR(Nan::Utf8String& utf8text); 36 | System::String^ exceptionV82stringCLR(v8::Local exception); 37 | 38 | typedef struct clrActionContext { 39 | gcroot action; 40 | static void ActionCallback(void* data); 41 | } ClrActionContext; 42 | 43 | ref class ClrFuncInvokeContext { 44 | private: 45 | Nan::Callback* callback; 46 | uv_edge_async_t* uv_edge_async; 47 | 48 | void DisposeCallback(); 49 | 50 | public: 51 | 52 | property System::Object^ Payload; 53 | property System::Threading::Tasks::Task^ Task; 54 | property bool Sync; 55 | 56 | ClrFuncInvokeContext(v8::Local callbackOrSync); 57 | 58 | void CompleteOnCLRThread(System::Threading::Tasks::Task^ task); 59 | void CompleteOnV8ThreadAsynchronous(); 60 | v8::Local CompleteOnV8Thread(); 61 | void InitializeAsyncOperation(); 62 | }; 63 | 64 | ref class NodejsFunc { 65 | public: 66 | 67 | property Nan::Persistent* Func; 68 | 69 | NodejsFunc(v8::Local function); 70 | ~NodejsFunc(); 71 | !NodejsFunc(); 72 | 73 | System::Threading::Tasks::Task^ FunctionWrapper(System::Object^ payload); 74 | }; 75 | 76 | ref class PersistentDisposeContext { 77 | private: 78 | System::IntPtr ptr; 79 | public: 80 | PersistentDisposeContext(Nan::Persistent* handle); 81 | void CallDisposeOnV8Thread(); 82 | }; 83 | 84 | ref class NodejsFuncInvokeContext; 85 | 86 | typedef struct nodejsFuncInvokeContextWrap { 87 | gcroot context; 88 | } NodejsFuncInvokeContextWrap; 89 | 90 | ref class NodejsFuncInvokeContext { 91 | private: 92 | NodejsFunc^ functionContext; 93 | System::Object^ payload; 94 | System::Exception^ exception; 95 | System::Object^ result; 96 | NodejsFuncInvokeContextWrap* wrap; 97 | 98 | void Complete(); 99 | 100 | public: 101 | 102 | property System::Threading::Tasks::TaskCompletionSource^ TaskCompletionSource; 103 | 104 | NodejsFuncInvokeContext( 105 | NodejsFunc^ functionContext, System::Object^ payload); 106 | ~NodejsFuncInvokeContext(); 107 | !NodejsFuncInvokeContext(); 108 | 109 | void CompleteWithError(System::Exception^ exception); 110 | void CompleteWithResult(v8::Local result); 111 | void CallFuncOnV8Thread(); 112 | }; 113 | 114 | ref class ClrFuncReflectionWrap { 115 | private: 116 | System::Object^ instance; 117 | MethodInfo^ invokeMethod; 118 | 119 | ClrFuncReflectionWrap(); 120 | 121 | public: 122 | 123 | static ClrFuncReflectionWrap^ Create(Assembly^ assembly, System::String^ typeName, System::String^ methodName); 124 | System::Threading::Tasks::Task^ Call(System::Object^ payload); 125 | }; 126 | 127 | ref class ClrFunc { 128 | private: 129 | System::Func^>^ func; 130 | 131 | ClrFunc(); 132 | 133 | static v8::Local MarshalCLRObjectToV8(System::Object^ netdata); 134 | 135 | public: 136 | static NAN_METHOD(Initialize); 137 | static v8::Local Initialize(System::Func^>^ func); 138 | v8::Local Call(v8::Local payload, v8::Local callback); 139 | static v8::Local MarshalCLRToV8(System::Object^ netdata); 140 | static v8::Local MarshalCLRExceptionToV8(System::Exception^ exception); 141 | static System::Object^ MarshalV8ToCLR(v8::Local jsdata); 142 | }; 143 | 144 | typedef struct clrFuncWrap { 145 | gcroot clrFunc; 146 | } ClrFuncWrap; 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /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/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 | net462;net6.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/agracio/electron-edge-js/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 | 69 | -------------------------------------------------------------------------------- /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/edge.h: -------------------------------------------------------------------------------- 1 | #ifndef __MONO_EDGE_H 2 | #define __MONO_EDGE_H 3 | 4 | #include "../common/edge_common.h" 5 | 6 | #include 7 | #include "mono/metadata/class.h" 8 | #include "mono/metadata/object.h" 9 | #include "mono/metadata/appdomain.h" 10 | 11 | typedef int GCHandle; 12 | 13 | v8::Local stringCLR2V8(MonoString* text); 14 | MonoString* stringV82CLR(v8::Local text); 15 | MonoString* exceptionV82stringCLR(v8::Local exception); 16 | 17 | class MonoEmbedding 18 | { 19 | static MonoAssembly* assembly; 20 | public: 21 | static void Initialize(); 22 | static void NormalizeException(MonoException** e); 23 | static MonoAssembly* GetAssembly(); 24 | static MonoImage* GetImage(); 25 | static MonoClass* GetClass(); 26 | static MonoObject* GetClrFuncReflectionWrapFunc(const char* assembly, const char* typeName, const char* methodName, MonoException ** exc); 27 | static MonoObject* CreateDateTime(double ticks); 28 | static MonoClass* GetIDictionaryStringObjectClass(MonoException** exc); 29 | static MonoClass* GetUriClass(MonoException** exc); 30 | static MonoObject* CreateExpandoObject(); 31 | static MonoClass* GetFuncClass(); 32 | static MonoArray* IEnumerableToArray(MonoObject* ienumerable, MonoException** exc); 33 | static MonoArray* IDictionaryToFlatArray(MonoObject* dictionary, MonoException** exc); 34 | static void ContinueTask(MonoObject* task, MonoObject* state, MonoException** exc); 35 | static double GetDateValue(MonoObject* dt, MonoException** exc); 36 | static MonoString* ToString(MonoObject* o, MonoException** exc); 37 | static double Int64ToDouble(MonoObject* i64, MonoException** exc); 38 | static MonoString* TryConvertPrimitiveOrDecimal(MonoObject* obj, MonoException** exc); 39 | }; 40 | 41 | typedef struct clrActionContext { 42 | GCHandle action; 43 | static void ActionCallback(void* data); 44 | } ClrActionContext; 45 | 46 | // wrapper for System.Threading.Task 47 | 48 | namespace SystemThreading{ 49 | class Task 50 | { 51 | public: 52 | static TaskStatus Status(MonoObject* _this); 53 | static MonoException* Exception(MonoObject* _this); 54 | static MonoObject* Result(MonoObject* _this); 55 | }; 56 | } 57 | 58 | 59 | // wrapper for System.Collections.Generic.Dictionary 60 | 61 | class Dictionary 62 | { 63 | public: 64 | static void Add(MonoObject* _this, const char* name, MonoObject* value); 65 | }; 66 | 67 | class ClrFuncInvokeContext { 68 | private: 69 | GCHandle _this; 70 | Nan::Callback* callback; 71 | uv_edge_async_t* uv_edge_async; 72 | 73 | public: 74 | MonoObject* Payload(); 75 | void Payload(MonoObject* value); 76 | MonoObject* Task(); 77 | void Task(MonoObject* value); 78 | bool Sync(); 79 | void Sync(bool value); 80 | 81 | MonoObject* GetMonoObject(); 82 | 83 | ClrFuncInvokeContext(v8::Local callbackOrSync); 84 | ~ClrFuncInvokeContext(); 85 | 86 | void InitializeAsyncOperation(); 87 | 88 | static void __cdecl CompleteOnCLRThread(ClrFuncInvokeContext *_this, MonoObject* task); 89 | static void __cdecl CompleteOnV8ThreadAsynchronous(ClrFuncInvokeContext *_this); 90 | v8::Local CompleteOnV8Thread(bool completedSynchronously); 91 | }; 92 | 93 | class NodejsFunc { 94 | GCHandle _this; 95 | public: 96 | Nan::Persistent* Func; 97 | 98 | NodejsFunc(v8::Local function); 99 | ~NodejsFunc(); 100 | 101 | MonoObject* GetFunc(); // returns Func> 102 | 103 | static void __cdecl ExecuteActionOnV8Thread(MonoObject* action); 104 | static void __cdecl Release(NodejsFunc* _this); 105 | }; 106 | 107 | class NodejsFuncInvokeContext { 108 | GCHandle _this; 109 | public: 110 | NodejsFuncInvokeContext(MonoObject* _this); 111 | ~NodejsFuncInvokeContext(); 112 | 113 | static void __cdecl CallFuncOnV8Thread(MonoObject* _this, NodejsFunc* nativeNodejsFunc, MonoObject* payload); 114 | void Complete(MonoObject* exception, MonoObject* result); 115 | }; 116 | 117 | class ClrFunc { 118 | private: 119 | //System::Func^>^ func; 120 | GCHandle func; 121 | 122 | ClrFunc(); 123 | 124 | static v8::Local MarshalCLRObjectToV8(MonoObject* netdata, MonoException** exc); 125 | 126 | public: 127 | ~ClrFunc(); 128 | static NAN_METHOD(Initialize); 129 | static v8::Local Initialize(MonoObject* func); 130 | v8::Local Call(v8::Local payload, v8::Local callback); 131 | static v8::Local MarshalCLRToV8(MonoObject* netdata, MonoException** exc); 132 | static v8::Local MarshalCLRExceptionToV8(MonoException* exception); 133 | static MonoObject* MarshalV8ToCLR(v8::Local jsdata); 134 | }; 135 | 136 | typedef struct clrFuncWrap { 137 | ClrFunc* clrFunc; 138 | } ClrFuncWrap; 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /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 parameter, 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 | it(prefix + ' succeeds with assemblyFile as string', function () { 63 | if (process.env.EDGE_USE_CORECLR) { 64 | this.skip(); 65 | } 66 | var func = edge.func(edgeTestDll); 67 | assert.equal(typeof func, 'function'); 68 | }); 69 | 70 | it(prefix + ' succeeds with assemblyFile as options property', function () { 71 | if (process.env.EDGE_USE_CORECLR) { 72 | this.skip(); 73 | } 74 | var func = edge.func({ assemblyFile: edgeTestDll }); 75 | assert.equal(typeof func, 'function'); 76 | }); 77 | 78 | it(prefix + ' succeeds with assemblyFile and type name', function () { 79 | var func = edge.func({ 80 | assemblyFile: edgeTestDll, 81 | typeName: 'Edge.Tests.Startup' 82 | }); 83 | assert.equal(typeof func, 'function'); 84 | }); 85 | 86 | it(prefix + ' fails with assemblyFile and nonexisting type name', function () { 87 | assert.throws( 88 | function () { 89 | edge.func({ 90 | assemblyFile: edgeTestDll, 91 | typeName: 'Edge.Tests.idontexist' 92 | }); 93 | }, 94 | /Could not load type 'Edge.Tests.idontexist'/ 95 | ); 96 | }); 97 | 98 | it(prefix + ' succeeds with assemblyFile, type name, and method name', function () { 99 | var func = edge.func({ 100 | assemblyFile: edgeTestDll, 101 | typeName: 'Edge.Tests.Startup', 102 | methodName: 'Invoke' 103 | }); 104 | assert.equal(typeof func, 'function'); 105 | }); 106 | 107 | it(prefix + ' fails with assemblyFile, type name and nonexisting method name', function () { 108 | assert.throws( 109 | function () { 110 | edge.func({ 111 | assemblyFile: edgeTestDll, 112 | typeName: 'Edge.Tests.Startup', 113 | methodName: 'idontexist' 114 | }); 115 | }, 116 | /Unable to access the CLR method to wrap through reflection/ 117 | ); 118 | }); 119 | }); -------------------------------------------------------------------------------- /test/105_node2net_sync.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge.js'), assert = require('assert') 2 | , path = require('path'); 3 | 4 | const crypto = require('crypto'); 5 | 6 | var edgeTestDll = process.env.EDGE_USE_CORECLR ? 'test' : path.join(__dirname, 'Edge.Tests.dll'); 7 | var prefix = process.env.EDGE_USE_CORECLR ? '[CoreCLR]' : process.platform === 'win32' ? '[.NET]' : '[Mono]'; 8 | 9 | function generateUuidBySeed() { 10 | 11 | const hash = crypto.createHash('sha256').update('seed').digest('hex'); 12 | 13 | // UUID version 4 consists of 32 hexadecimal digits in the form: 14 | // 8-4-4-4-12 (total 36 characters including hyphens) 15 | const uuid = [ 16 | hash.substring(0, 8), 17 | hash.substring(8, 12), 18 | '4' + hash.substring(12, 15), // Set the version to 4 19 | '8' + hash.substring(15, 18), // Set the variant to 8 (RFC 4122) 20 | hash.substring(18, 30), 21 | ].join('-'); 22 | 23 | return uuid; 24 | } 25 | describe('sync call from node.js to .net', function () { 26 | 27 | it(prefix + ' succeeds for hello world', function () { 28 | var func = edge.func({ 29 | assemblyFile: edgeTestDll, 30 | typeName: 'Edge.Tests.Startup', 31 | methodName: 'Invoke' 32 | }); 33 | var result = func('Node.js', true); 34 | assert.equal(result, '.NET welcomes Node.js'); 35 | }); 36 | 37 | it(prefix + ' succeeds for hello world when called sync and async', function (done) { 38 | // create the func 39 | var func = edge.func({ 40 | assemblyFile: edgeTestDll, 41 | typeName: 'Edge.Tests.Startup', 42 | methodName: 'Invoke' 43 | }); 44 | 45 | // call the func synchronously 46 | var result = func('Node.js', true); 47 | assert.equal(result, '.NET welcomes Node.js'); 48 | 49 | // call the same func asynchronously 50 | func('Node.js', function (error, result) { 51 | assert.ifError(error); 52 | assert.equal(result, '.NET welcomes Node.js'); 53 | done(); 54 | }); 55 | }); 56 | 57 | it(prefix + ' successfuly marshals data from node.js to .net', function () { 58 | var func = edge.func({ 59 | assemblyFile: edgeTestDll, 60 | typeName: 'Edge.Tests.Startup', 61 | methodName: 'MarshalIn' 62 | }); 63 | var payload = { 64 | a: 1, 65 | b: 3.1415, 66 | c: 'fooåäö', 67 | d: true, 68 | e: false, 69 | f: Buffer.alloc(10), 70 | g: [ 1, 'fooåäö' ], 71 | h: { a: 'fooåäö', b: 12 }, 72 | i: function (payload, callback) { }, 73 | j: new Date(Date.UTC(2013,07,30)), 74 | k: 65535, 75 | l: 4294967295, 76 | m: 18446744073709551615, 77 | n: 'c', 78 | o: generateUuidBySeed(), 79 | }; 80 | var result = func(payload, true); 81 | assert.equal(result, 'yes'); 82 | }); 83 | 84 | it(prefix + ' successfuly marshals .net exception thrown on v8 thread from .net to node.js', function () { 85 | var func = edge.func({ 86 | assemblyFile: edgeTestDll, 87 | typeName: 'Edge.Tests.Startup', 88 | methodName: 'NetExceptionTaskStart' 89 | }); 90 | assert.throws( 91 | function() { func(null, true); }, 92 | function (error) { 93 | if ((error instanceof Error) && error.Message.match(/Test .NET exception/)) { 94 | return true; 95 | } 96 | return false; 97 | }, 98 | 'Unexpected result' 99 | ); 100 | }); 101 | 102 | it(prefix + ' fails if C# method does not complete synchronously', function () { 103 | var func = edge.func({ 104 | assemblyFile: edgeTestDll, 105 | typeName: 'Edge.Tests.Startup', 106 | methodName: 'DelayedReturn' 107 | }); 108 | assert.throws( 109 | function() { func(null, true); }, 110 | / The JavaScript function was called synchronously but/ 111 | ); 112 | }); 113 | }); -------------------------------------------------------------------------------- /test/106_node2net_symbols.js: -------------------------------------------------------------------------------- 1 | var edge = require('../lib/edge.js'), assert = require('assert') 2 | , path = require('path'); 3 | 4 | const crypto = require('crypto'); 5 | 6 | var edgeTestDll = path.join(__dirname, '测试', 'Edge.Tests.CoreClr.dll'); 7 | var prefix = process.env.EDGE_USE_CORECLR ? '[CoreCLR]' : process.platform === 'win32' ? '[.NET]' : '[Mono]'; 8 | 9 | function generateUuidBySeed() { 10 | 11 | const hash = crypto.createHash('sha256').update('seed').digest('hex'); 12 | 13 | // UUID version 4 consists of 32 hexadecimal digits in the form: 14 | // 8-4-4-4-12 (total 36 characters including hyphens) 15 | const uuid = [ 16 | hash.substring(0, 8), 17 | hash.substring(8, 12), 18 | '4' + hash.substring(12, 15), // Set the version to 4 19 | '8' + hash.substring(15, 18), // Set the variant to 8 (RFC 4122) 20 | hash.substring(18, 30), 21 | ].join('-'); 22 | 23 | return uuid; 24 | } 25 | 26 | describe('node.js to .net dll from path with asian chracters', function () { 27 | 28 | it(prefix + ' succeeds for hello world', function (done) { 29 | if (!process.env.EDGE_USE_CORECLR) { 30 | this.skip(); 31 | } 32 | var func = edge.func({ 33 | assemblyFile: edgeTestDll, 34 | typeName: 'Edge.Tests.Startup', 35 | methodName: 'Invoke' 36 | }); 37 | func('Node.js', function (error, result) { 38 | assert.ifError(error); 39 | assert.equal(result, '.NET welcomes Node.js'); 40 | done(); 41 | }); 42 | }); 43 | 44 | it(prefix + ' successfuly marshals data from node.js to .net', function (done) { 45 | if (!process.env.EDGE_USE_CORECLR) { 46 | this.skip(); 47 | } 48 | var func = edge.func({ 49 | assemblyFile: edgeTestDll, 50 | typeName: 'Edge.Tests.Startup', 51 | methodName: 'MarshalIn' 52 | }); 53 | var payload = { 54 | a: 1, 55 | b: 3.1415, 56 | c: 'fooåäö', 57 | d: true, 58 | e: false, 59 | f: Buffer.alloc(10), 60 | g: [ 1, 'fooåäö' ], 61 | h: { a: 'fooåäö', b: 12 }, 62 | i: function (payload, callback) { }, 63 | j: new Date(Date.UTC(2013, 07, 30)), 64 | k: 65535, 65 | l: 4294967295, 66 | m: 18446744073709551615, 67 | n: 'c', 68 | o: generateUuidBySeed(), 69 | }; 70 | func(payload, function (error, result) { 71 | assert.ifError(error); 72 | assert.equal(result, 'yes'); 73 | done(); 74 | }); 75 | }); 76 | 77 | it(prefix + ' successfuly marshals data from .net to node.js', function (done) { 78 | if (!process.env.EDGE_USE_CORECLR) { 79 | this.skip(); 80 | } 81 | var func = edge.func({ 82 | assemblyFile: edgeTestDll, 83 | typeName: 'Edge.Tests.Startup', 84 | methodName: 'MarshalBack' 85 | }); 86 | func(null, function (error, result) { 87 | assert.ifError(error); 88 | assert.equal(typeof result, 'object'); 89 | assert.ok(result.a === 1); 90 | assert.ok(result.b === 3.1415); 91 | assert.ok(result.c === 'fooåäö'); 92 | assert.ok(result.d === true); 93 | assert.ok(result.e === false); 94 | assert.equal(typeof result.f, 'object'); 95 | assert.ok(Buffer.isBuffer(result.f)); 96 | assert.equal(result.f.length, 10); 97 | assert.ok(Array.isArray(result.g)); 98 | assert.equal(result.g.length, 2); 99 | assert.ok(result.g[0] === 1); 100 | assert.ok(result.g[1] === 'fooåäö'); 101 | assert.equal(typeof result.h, 'object'); 102 | assert.ok(result.h.a === 'fooåäö'); 103 | assert.ok(result.h.b === 12); 104 | assert.equal(typeof result.i, 'function'); 105 | assert.equal(typeof result.j, 'object'); 106 | assert.ok(result.j.valueOf() === Date.UTC(2013, 07, 30)); 107 | assert.equal(result.k, 65535); 108 | assert.equal(result.l, 4294967295); 109 | assert.equal(result.m, 18446744073709551615); 110 | assert.equal(result.n, 'c'); 111 | assert.equal(result.o, generateUuidBySeed()); 112 | done(); 113 | }); 114 | }); 115 | }); -------------------------------------------------------------------------------- /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 | it(prefix + ' complex exception serialization', function (done) { 8 | if (process.env.EDGE_USE_CORECLR || process.platform !== 'win32') { 9 | this.skip(); 10 | } 11 | var func = edge.func({ 12 | source: function () {/* 13 | #r "System.Data.dll" 14 | 15 | using System.Data; 16 | using System.Data.SqlClient; 17 | 18 | async (input) => 19 | { 20 | 21 | using (SqlConnection connection = new SqlConnection("Data Source=my_localhost;Initial Catalog=catalog;Integrated Security=True;Connection Timeout=1")) 22 | { 23 | connection.Open(); 24 | } 25 | return input.ToString(); 26 | 27 | } 28 | */ 29 | } 30 | }); 31 | func("JavaScript", function (error, result) { 32 | var exception = error.toString(); 33 | var contains = exception.indexOf('A network-related or instance-specific error occurred while establishing a connection to SQL Server') !== -1 34 | || exception.indexOf('Server does not exist or connection refused') !== -1 35 | || exception.indexOf('System.Data.SqlClient.SqlException') !== -1; 36 | assert.ok(contains); 37 | 38 | done(); 39 | }); 40 | 41 | 42 | }); 43 | 44 | 45 | }); -------------------------------------------------------------------------------- /test/app.js: -------------------------------------------------------------------------------- 1 | /*jshint esversion: 6 */ 2 | const { ipcMain, ipcRenderer} = require("electron"); 3 | const path = require('path'); 4 | const Mocha = require('mocha'); 5 | //const merge = require('mochawesome-merge'); 6 | 7 | const baseNetAppPath = path.join(__dirname, '/bin/Debug/'); 8 | 9 | process.env.EDGE_APP_ROOT = baseNetAppPath; 10 | var runner = process.argv[2].replace('--', ''); 11 | 12 | function createMocha (reportFilename, version) { 13 | return new Mocha({ 14 | reporter: 'mochawesome', 15 | reporterOptions: { 16 | reportFilename: reportFilename, 17 | reportDir: path.join(__dirname, 'mochawesome-report'), 18 | quiet: false, 19 | consoleReporter: 'none', 20 | showSkipped: true, 21 | json: true, 22 | reportTitle: `electron-edge-js ${version} Electron ${process.versions.electron}` 23 | }, 24 | timeout:10000, 25 | }); 26 | } 27 | 28 | function addFiles(mocha){ 29 | mocha.addFile(path.join(__dirname, '101_edge_func.js')); 30 | mocha.addFile(path.join(__dirname, '102_node2net.js')); 31 | mocha.addFile(path.join(__dirname, '103_net2node.js')); 32 | mocha.addFile(path.join(__dirname, '104_csx.js')); 33 | mocha.addFile(path.join(__dirname, '105_node2net_sync.js')); 34 | mocha.addFile(path.join(__dirname, '106_node2net_symbols.js')); 35 | mocha.addFile(path.join(__dirname, '201_patterns.js')); 36 | mocha.addFile(path.join(__dirname, '202_serialization.js')); 37 | } 38 | 39 | exports.runTests = function (framework, window){ 40 | 41 | var version = process.env.EDGE_USE_CORECLR ? 'CoreCLR' : process.platform === 'win32' ? '.NET Framework 4.5' : 'Mono Framework'; 42 | //process.platform === 'win32' && !process.env.EDGE_USE_CORECLR ? delete process.env.EDGE_USE_CORECLR : process.env.EDGE_USE_CORECLR = 1 43 | //var prefix = process.env.EDGE_USE_CORECLR ? 'CoreCLR' : 'NET'; 44 | var prefix = ''; 45 | var suffix = process.env.EDGE_USE_CORECLR ? 'coreclr' :'net'; 46 | 47 | //ipcRenderer.send("testResult", 'title', `Running ${version} tests on Electron ${process.versions.electron}`); 48 | window.webContents.send("testResult", 'title', `Running ${version} tests on Electron ${process.versions.electron}`); 49 | 50 | var reportFilename = `test-results-${suffix}.html`; 51 | var mocha = createMocha(reportFilename, version); 52 | addFiles(mocha); 53 | 54 | var run = mocha.run(); 55 | window.webContents.send("testResult", 'testsNumber', run.total); 56 | 57 | var margin = 0; 58 | run.on('suite', function(suite){ 59 | if(suite.file){ 60 | window.webContents.send("testResult", 'suites', '', suite.title, suite.file.replace(/^.*[\\/]/, ''), suite.tests.length, margin, prefix); 61 | margin = 10; 62 | } 63 | }); 64 | 65 | run.on('end', function(){ 66 | setTimeout(function(){ 67 | mocha.dispose(); 68 | window.webContents.send("runComplete", reportFilename); 69 | if(runner === 'CI'){ 70 | window.close(); 71 | } 72 | }, 1000); 73 | }); 74 | 75 | }; 76 | 77 | // ipcMain.on("runTests", (event, args) => { 78 | // console.log(ipcRenderer); 79 | // runTests(process.env.EDGE_USE_CORECLR, args); 80 | // }); 81 | 82 | // exports.run = function (window) { 83 | // ipcMain.handle("run", (event, args) =>{ 84 | // runTests(process.env.EDGE_USE_CORECLR, window); 85 | // }); 86 | // }; 87 | -------------------------------------------------------------------------------- /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/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | electron-edge-js tests 7 | 8 | 9 | 10 | 11 | 12 | 26 |
27 |
    28 | 29 |
30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /test/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/loading.gif -------------------------------------------------------------------------------- /test/main.js: -------------------------------------------------------------------------------- 1 | process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = true; 2 | // if(process.platform === 'linux' && !process.env.EDGE_USE_CORECLR){ 3 | // Object.assign(process.env, { 4 | // // Work around Mono problem: undefined symbol: mono_add_internal_call_with_flags 5 | // LD_PRELOAD: 'libmono-2.0.so libmonosgen-2.0.so libstdc++.so.6', 6 | // }); 7 | // } 8 | const {app, BrowserWindow, ipcMain, ipcRenderer} = require("electron"); 9 | const testRunner = require('./app.js'); 10 | 11 | // Keep a global reference of the window object, if you don't, the window will 12 | // be closed automatically when the JavaScript object is garbage collected. 13 | let mainWindow; 14 | 15 | function createWindow () { 16 | // Create the browser window. 17 | mainWindow = new BrowserWindow({ 18 | width: 1280, 19 | height: 900, 20 | webPreferences:{ 21 | nodeIntegration: false, 22 | nodeIntegrationInWorker: false, 23 | contextIsolation: true, 24 | preload: `${__dirname}/preload.js`, 25 | } 26 | }); 27 | 28 | // and load the index.html of the app. 29 | mainWindow.loadURL(`file://${__dirname}/index.html?platform=${process.platform}&useClr=${process.env.EDGE_USE_CORECLR}`); 30 | 31 | // Open the DevTools. 32 | //mainWindow.webContents.openDevTools() 33 | 34 | // Emitted when the window is closed. 35 | mainWindow.on('closed', function () { 36 | // Dereference the window object, usually you would store windows 37 | // in an array if your app supports multi windows, this is the time 38 | // when you should delete the corresponding element. 39 | mainWindow = null; 40 | }); 41 | } 42 | 43 | // This method will be called when Electron has finished 44 | // initialization and is ready to create browser windows. 45 | // Some APIs can only be used after this event occurs. 46 | app.on('ready', createWindow); 47 | 48 | // Quit when all windows are closed. 49 | app.on('window-all-closed', function () { 50 | // On OS X it is common for applications and their menu bar 51 | // to stay active until the user quits explicitly with Cmd + Q 52 | //if (process.platform !== 'darwin') { 53 | app.quit(); 54 | //} 55 | }); 56 | 57 | app.on('activate', function () { 58 | // On OS X it's common to re-create a window in the app when the 59 | // dock icon is clicked and there are no other windows open. 60 | if (mainWindow === null) { 61 | createWindow(); 62 | } 63 | }); 64 | 65 | ipcMain.on("runTests", (event, args) => { 66 | // if (typeof args !== "undefined"){ 67 | // process.env.EDGE_USE_CORECLR = args; 68 | // } 69 | testRunner.runTests(args, mainWindow); 70 | }); 71 | 72 | // In this file you can include the rest of your app's specific main process 73 | // code. You can also put them in separate files and require them here. 74 | -------------------------------------------------------------------------------- /test/mochawesome-report/assets/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /test/mochawesome-report/assets/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /test/mochawesome-report/assets/app.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | Copyright (c) 2017 Jed Watson. 9 | Licensed under the MIT License (MIT), see 10 | http://jedwatson.github.io/classnames 11 | */ 12 | 13 | /*! ***************************************************************************** 14 | Copyright (c) Microsoft Corporation. All rights reserved. 15 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 16 | this file except in compliance with the License. You may obtain a copy of the 17 | License at http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 | KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 21 | WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 22 | MERCHANTABLITY OR NON-INFRINGEMENT. 23 | 24 | See the Apache Version 2.0 License for specific language governing permissions 25 | and limitations under the License. 26 | ***************************************************************************** */ 27 | 28 | /*! mochawesome-report-generator 6.2.0 | https://github.com/adamgruber/mochawesome-report-generator */ 29 | 30 | /** @license React v0.19.1 31 | * scheduler.production.min.js 32 | * 33 | * Copyright (c) Facebook, Inc. and its affiliates. 34 | * 35 | * This source code is licensed under the MIT license found in the 36 | * LICENSE file in the root directory of this source tree. 37 | */ 38 | 39 | /** @license React v16.13.1 40 | * react-dom.production.min.js 41 | * 42 | * Copyright (c) Facebook, Inc. and its affiliates. 43 | * 44 | * This source code is licensed under the MIT license found in the 45 | * LICENSE file in the root directory of this source tree. 46 | */ 47 | 48 | /** @license React v16.13.1 49 | * react.production.min.js 50 | * 51 | * Copyright (c) Facebook, Inc. and its affiliates. 52 | * 53 | * This source code is licensed under the MIT license found in the 54 | * LICENSE file in the root directory of this source tree. 55 | */ 56 | -------------------------------------------------------------------------------- /test/mochawesome-report/assets/loading1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/loading1.gif -------------------------------------------------------------------------------- /test/mochawesome-report/assets/roboto-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/roboto-light-webfont.woff -------------------------------------------------------------------------------- /test/mochawesome-report/assets/roboto-light-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/roboto-light-webfont.woff2 -------------------------------------------------------------------------------- /test/mochawesome-report/assets/roboto-medium-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/roboto-medium-webfont.woff -------------------------------------------------------------------------------- /test/mochawesome-report/assets/roboto-medium-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/roboto-medium-webfont.woff2 -------------------------------------------------------------------------------- /test/mochawesome-report/assets/roboto-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/roboto-regular-webfont.woff -------------------------------------------------------------------------------- /test/mochawesome-report/assets/roboto-regular-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agracio/electron-edge-js/612bc2081206854324b954259582f0dab6e537a8/test/mochawesome-report/assets/roboto-regular-webfont.woff2 -------------------------------------------------------------------------------- /test/preload.js: -------------------------------------------------------------------------------- 1 | /*jshint esversion: 6 */ 2 | const { 3 | contextBridge, 4 | ipcRenderer 5 | } = require("electron"); 6 | 7 | 8 | contextBridge.exposeInMainWorld( 9 | "api", { 10 | send: (channel, data) => { 11 | ipcRenderer.send(channel, data); 12 | }, 13 | receive: (channel, func) => { 14 | ipcRenderer.on(channel, (event, ...args) => func(...args)); 15 | }, 16 | run: (framework) => ipcRenderer.invoke("run", framework) 17 | } 18 | ); -------------------------------------------------------------------------------- /test/renderer.js: -------------------------------------------------------------------------------- 1 | /*jshint esversion: 6 */ 2 | const params = new URLSearchParams(document.location.search); 3 | 4 | var suitesDoc = document.getElementById("suites"); 5 | 6 | window.api.send("runTests"); 7 | 8 | window.api.receive("testResult", (documentId, data, suiteName, suiteFile, testNumber, margin, prefix) => { 9 | if(suiteName){ 10 | document.getElementById(documentId).innerHTML += addTestSuite(suiteName, suiteFile, testNumber, margin, prefix); 11 | }else{ 12 | document.getElementById(documentId).innerHTML = data; 13 | } 14 | }); 15 | 16 | window.api.receive("runComplete", (reportFilename) => { 17 | window.location.href = `mochawesome-report/${reportFilename}` 18 | // framework = frameworks.shift(); 19 | // if (typeof framework !== "undefined"){ 20 | // window.api.send("runTests", framework); 21 | // } 22 | console.log(reportFilename); 23 | }); 24 | 25 | function addTestSuite(suiteName, suiteFile, testNumber, margin, prefix){ 26 | return ` 27 |
28 |

29 | 30 | ${suiteName} 31 |
  • ${testNumber}
  • 32 |

    33 |
    ${suiteFile}
    34 |
    35 | `; 36 | } -------------------------------------------------------------------------------- /test/test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | true 6 | true 7 | test 8 | Exe 9 | test 10 | default 11 | disable 12 | false 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 | -------------------------------------------------------------------------------- /tools/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set SELF=%~dp0 3 | if "%1" equ "" ( 4 | echo Usage: build.bat debug^|release "{version}" 5 | echo e.g. build.bat release "30.0.0" 6 | exit /b -1 7 | ) 8 | rmdir /S /Q ..\build\ 9 | FOR /F "tokens=* USEBACKQ" %%F IN (`node -p process.arch`) DO (SET ARCH=%%F) 10 | 11 | SET FLAVOR=%1 12 | shift 13 | if "%FLAVOR%" equ "" set FLAVOR=release 14 | SET DESTDIRROOT=%SELF%\..\lib\native\win32 15 | 16 | set VERSION=%1 17 | 18 | set ELECTRONV=%1 19 | echo %ELECTRONV% 20 | set "ELECTRONV=%ELECTRONV:~,2%" 21 | 22 | if %ELECTRONV% equ %VERSION% ( 23 | SET VERSION=%ELECTRONV%.0.0 24 | ) 25 | pushd %SELF%\.. 26 | 27 | call :build ia32 ia32 %VERSION% 28 | call :build x64 x64 %VERSION% 29 | call :build arm64 arm64 %VERSION% 30 | 31 | popd 32 | 33 | exit /b 0 34 | 35 | :build 36 | 37 | set DESTDIR=%DESTDIRROOT%\%1\%ELECTRONV% 38 | echo %DESTDIR% 39 | if not exist "%DESTDIR%\NUL" mkdir "%DESTDIR%" 40 | 41 | :gyp 42 | 43 | echo Building edge.node %FLAVOR% for Electron %2 v%3 44 | 45 | FOR /F "tokens=* USEBACKQ" %%F IN (`npm config get prefix`) DO (SET NODEBASE=%%F) 46 | set GYP=%NODEBASE%\node_modules\node-gyp\bin\node-gyp.js 47 | if not exist "%GYP%" ( 48 | echo Cannot find node-gyp at %GYP%. Make sure to install with npm install node-gyp -g 49 | exit /b -1 50 | ) 51 | 52 | node "%GYP%" configure --msvs_version=2022 --target=%3 --arch=%2 --runtime=electron --disturl=https://electronjs.org/headers --%FLAVOR% 53 | if %ERRORLEVEL% neq 0 ( 54 | echo Error building edge.node %FLAVOR% for Electron %2 v%3 55 | exit /b -1 56 | ) 57 | 58 | @REM Conflict when building arm64 binaries 59 | if "%2" == "arm64" ( 60 | FOR %%F IN (build\*.vcxproj) DO ( 61 | echo Patch /fp:strict in %%F 62 | powershell -Command "(Get-Content -Raw %%F) -replace 'Strict', '' | Out-File -Encoding Utf8 %%F" 63 | ) 64 | ) 65 | 66 | @REM Conflict when building Electron v32 67 | if %ELECTRONV% EQU 32 ( 68 | FOR %%F IN (build\*.vcxproj) DO ( 69 | echo Replace std:c++17 with std:c++20 in %%F 70 | powershell -Command "(Get-Content -Raw %%F) -replace 'std:c\+\+17', 'std:c++20' | Out-File -Encoding Utf8 %%F" 71 | ) 72 | ) 73 | 74 | node "%GYP%" build 75 | if %ERRORLEVEL% neq 0 ( 76 | echo Error building edge.node %FLAVOR% for Electron %2 v%3 77 | exit /b -1 78 | ) 79 | 80 | echo %DESTDIR% 81 | copy /y .\build\%FLAVOR%\edge_*.node "%DESTDIR%" 82 | if %ERRORLEVEL% neq 0 ( 83 | echo Error copying edge.node %FLAVOR% for Electron %2 v%3 84 | exit /b -1 85 | ) 86 | rmdir /S /Q .\build\ 87 | copy /y "%DESTDIR%\..\*.dll" "%DESTDIR%" 88 | if %ERRORLEVEL% neq 0 ( 89 | echo Error copying VC redist %FLAVOR% to %DESTDIR% 90 | exit /b -1 91 | ) 92 | 93 | echo Success building edge.node %FLAVOR% for Electron %2 v%3 94 | -------------------------------------------------------------------------------- /tools/checkMono.js: -------------------------------------------------------------------------------- 1 | const { execSync } = require('child_process'); 2 | 3 | function exists(cmd){ 4 | try{ 5 | let result = execSync(cmd).toString(); 6 | return result.toLowerCase().includes('not found') || result.length === 0 ? false : true; 7 | } 8 | catch{ 9 | return false; 10 | } 11 | } 12 | 13 | module.exports = function() { 14 | let mono = exists('which mono'); 15 | let pkgconfig = exists('which pkg-config'); 16 | return mono && pkgconfig 17 | } -------------------------------------------------------------------------------- /tools/getVersion.js: -------------------------------------------------------------------------------- 1 | var {http} = require('follow-redirects'); 2 | const fs = require("fs"); 3 | 4 | const majors = [31, 32, 33, 34, 35, 36]; 5 | // const majors = [30]; 6 | const oses = ['macos-13', 'macos-15', 'ubuntu-22.04', 'ubuntu-22.04-arm', 'windows-2025', 'windows-11-arm']; 7 | // const oses = ['ubuntu-22.04', 'ubuntu-22.04-arm']; 8 | getVersion(); 9 | 10 | function getVersion() { 11 | let url = 'http://releases.electronjs.org/releases.json'; 12 | 13 | function getVersionFromMajor(json, major){ 14 | json = json.filter(function (str) { return str.startsWith(`${major}.`); }); 15 | if(json.length !== 0){ 16 | return json[0]; 17 | } 18 | else{ 19 | console.warn(`Unable to resolve latest version for Electron ${major}`); 20 | return null; 21 | } 22 | } 23 | 24 | http.get(url,(res) => { 25 | let body = ""; 26 | 27 | if (res.statusCode !== 200) { 28 | throw new Error(`Unable to get Electron versions from ${url}`); 29 | } 30 | 31 | res.on("data", (chunk) => { 32 | body += chunk; 33 | }); 34 | 35 | res.on("end", () => { 36 | try { 37 | 38 | let json = JSON.parse(body) 39 | .sort() 40 | .map(({ version }) => version) 41 | .filter(function (str) { return !str.includes('^'); }) 42 | .filter(function (str) { return !str.includes('-'); }); 43 | 44 | let major = process.argv[2]; 45 | if(major){ 46 | version = getVersionFromMajor(json, major); 47 | fs.writeFileSync('electron.txt', version); 48 | console.log(version); 49 | } 50 | else{ 51 | let versions = []; 52 | let results = []; 53 | 54 | majors.forEach((major) => { 55 | let version = getVersionFromMajor(json, major); 56 | if(version){ 57 | versions.push(version); 58 | } 59 | }); 60 | 61 | oses.forEach((os) => { 62 | versions.forEach((version) => { 63 | results.push({'electron': `${version}`, 'os': `${os}`}); 64 | }); 65 | }); 66 | 67 | let res = `{'include':${JSON.stringify(results)}}` 68 | fs.writeFileSync('electron-versions.txt', res); 69 | console.log(versions); 70 | } 71 | } catch (error) { 72 | throw error; 73 | }; 74 | }); 75 | 76 | }).on("error", (error) => { 77 | throw new Error(error); 78 | }); 79 | } 80 | -------------------------------------------------------------------------------- /tools/mergeTests.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const merge = require('mochawesome-merge'); 4 | const marge = require('mochawesome-report-generator') 5 | 6 | const options = { 7 | files: [ 8 | './test/mochawesome-report/*.json', 9 | ], 10 | } 11 | 12 | const margeOptions = { 13 | reportFilename: 'mochawesome.html', 14 | reportDir: './test/mochawesome-report', 15 | overwrite: true, 16 | reportTitle: `electron-edge-js Electron ${process.argv[2]}` 17 | } 18 | 19 | merge.merge(options).then(report => { 20 | var file = './test/mochawesome-report/mochawesome.json'; 21 | fs.writeFileSync(file, JSON.stringify(report, null, 2)) 22 | console.log(`Mochawesome json created: ${file}`); 23 | marge.create(report, margeOptions).then(() => 24 | { 25 | console.log(`Mochawesome report created: ${margeOptions.reportDir}/${margeOptions.reportFilename}`) 26 | } 27 | ); 28 | }) 29 | -------------------------------------------------------------------------------- /tools/test.js: -------------------------------------------------------------------------------- 1 | var spawn = require('child_process').spawn; 2 | var path = require('path'); 3 | var fs = require('fs'); 4 | var testDir = path.resolve(__dirname, '../test'); 5 | var input = path.resolve(testDir, 'tests.cs'); 6 | var output = path.resolve(testDir, 'Edge.Tests.dll'); 7 | var buildParameters = ['-target:library', '/debug', '-out:' + output, input]; 8 | 9 | var electron = require('electron') 10 | const checkMono = require('./checkMono'); 11 | var runner = process.argv[2]; 12 | 13 | if(process.platform === 'linux' && !process.env.EDGE_USE_CORECLR){ 14 | Object.assign(process.env, { 15 | // Work around Mono problem: undefined symbol: mono_add_internal_call_with_flags 16 | LD_PRELOAD: 'libmono-2.0.so libmonosgen-2.0.so libstdc++.so.6', 17 | }); 18 | } 19 | 20 | function build(){ 21 | if (!process.env.EDGE_USE_CORECLR) { 22 | if (process.platform !== 'win32') { 23 | buildParameters = buildParameters.concat(['-sdk:4.5']); 24 | } 25 | 26 | let compiler; 27 | 28 | if(process.platform === 'win32'){ 29 | compiler = 'C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe' 30 | } 31 | else if(checkMono()){ 32 | compiler = 'mcs' 33 | } 34 | 35 | if(compiler){ 36 | dotnet(compiler, buildParameters); 37 | } 38 | else{ 39 | coreclr(); 40 | } 41 | } 42 | 43 | else { 44 | coreclr(); 45 | } 46 | } 47 | 48 | function dotnet(compiler, buildParameters){ 49 | run(compiler, buildParameters, runOnSuccess); 50 | } 51 | 52 | function coreclr(){ 53 | run(process.platform === 'win32' ? 'dotnet.exe' : 'dotnet', ['restore'], function(code, signal) { 54 | if (code === 0) { 55 | run(process.platform === 'win32' ? 'dotnet.exe' : 'dotnet', ['build'], function(code, signal) { 56 | if (code === 0) { 57 | try{ 58 | fs.mkdirSync('test/测试', { recursive: true }) 59 | } 60 | catch (e){ 61 | console.error(e); 62 | throw e; 63 | } 64 | fs.copyFile('test/bin/Debug/test.dll', 'test/测试/Edge.Tests.CoreClr.dll', (e) => { 65 | if (e) { 66 | console.error(e); 67 | throw e; 68 | } 69 | runOnSuccess(0); 70 | }); 71 | } 72 | }); 73 | } 74 | }); 75 | } 76 | 77 | build(); 78 | 79 | function run(cmd, args, onClose){ 80 | 81 | var params = process.env.EDGE_USE_CORECLR ? {cwd: testDir} : {}; 82 | var command = spawn(cmd, args, params); 83 | var result = ''; 84 | var error = ''; 85 | command.stdout.on('data', function(data) { 86 | result += data.toString(); 87 | }); 88 | command.stderr.on('data', function(data) { 89 | error += data.toString(); 90 | }); 91 | 92 | command.on('error', function(err) { 93 | console.log(error); 94 | console.log(err); 95 | }); 96 | 97 | command.on('close', function(code){ 98 | console.log(result); 99 | onClose(code, ''); 100 | }); 101 | } 102 | 103 | function runOnSuccess(code, signal) { 104 | if (code === 0) { 105 | process.env['EDGE_APP_ROOT'] = path.join(testDir, 'bin', 'Debug'); 106 | var electronPath = path.resolve(__dirname, '../test/main.js') 107 | spawn(electron, [electronPath, runner], { 108 | stdio: 'inherit' 109 | }).on('error', function(err) { 110 | console.log(err); 111 | }); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /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) && fs.lstatSync(filePath).isFile()) { 15 | return filePath; 16 | } 17 | } 18 | } 19 | 20 | return null; 21 | } --------------------------------------------------------------------------------