diff --git a/.github/workflows/build_release.yml b/.github/workflows/build_release.yml
new file mode 100644
index 0000000..d57e889
--- /dev/null
+++ b/.github/workflows/build_release.yml
@@ -0,0 +1,138 @@
+name: Build Release
+
+on:
+ push:
+ branches:
+ - "main"
+
+env:
+ BUILD_TYPE: Release
+
+
+jobs:
+ create_release:
+ name: "Create Release"
+ runs-on: "ubuntu-latest"
+ outputs:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+
+ steps:
+ - name: Create release
+ id: create_release
+ uses: "marvinpinto/action-automatic-releases@latest"
+ with:
+ repo_token: "${{ secrets.GITHUB_TOKEN }}"
+ automatic_release_tag: "latest"
+ prerelease: true
+ title: "Development Build"
+
+ build_emscripten:
+ name: Build for Emscripten
+ needs: create_release
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Remove unused software to free up space
+ run: |
+ # These are quick to delete and large enough to make a difference
+ rm -rf /usr/share/swift/ # 1.3 GB in 80 subdirs
+ rm -rf /usr/local/lib/android/sdk/build-tools/ # 2.1 GB in 450 subdirs
+ rm -rf /usr/share/dotnet/shared/ # 5.3 GB in 350 subdirs
+ rm -rf /usr/local/lib/android/sdk/ndk/ # 7.6 GB in 1500 subdirs
+
+ - uses: actions/checkout@v2
+
+ - name: Update Submodule
+ run: git submodule update --init --recursive
+
+ - name: Build
+ run: bash ${{github.workspace}}/scripts/build_emscripten.sh
+
+ - name: Upload Release Assets
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ needs.create_release.outputs.upload_url }}
+ asset_name: soljson.js
+ asset_path: ${{github.workspace}}/upload/soljson.js
+ asset_content_type: application/octet-stream
+
+ build_linux:
+ name: Build for Linux
+ needs: create_release
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Update Submodule
+ run: git submodule update --init --recursive
+
+ - name: Install Dependencies
+ run: bash ${{github.workspace}}/scripts/install_deps.sh
+
+ - name: Build
+ run: bash ${{github.workspace}}/build.sh
+
+ - name: Compress Artifact
+ run: |
+ cd ${{github.workspace}}/build/solppc
+ tar -cvzf solppc_linux.tar.gz ./solppc
+
+ - name: Upload Release Assets
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ needs.create_release.outputs.upload_url }}
+ asset_name: solppc_linux.tar.gz
+ asset_path: ${{github.workspace}}/build/solppc/solppc_linux.tar.gz
+ asset_content_type: application/octet-stream
+
+ build-macos:
+ name: Build for MacOS
+ needs: create_release
+ runs-on: macos-11
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Update Submodule
+ run: git submodule update --init --recursive
+
+ - name: Install Dependencies
+ run: |
+ bash ${{github.workspace}}/scripts/osx_install_dependencies.sh
+
+ - name: Build
+ run: |
+ mkdir -p build/
+ echo -n > prerelease.txt
+ cd build/
+ cmake .. -DSOLC_LINK_STATIC=1 -DCMAKE_BUILD_TYPE=Release
+ make -j3
+
+ - name: Compress Artifact
+ run: |
+ cd ${{github.workspace}}/build/solppc
+ tar -cvzf solppc_darwin.tar.gz ./solppc
+
+ - name: Upload Release Assets
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ needs.create_release.outputs.upload_url }}
+ asset_name: solppc_darwin.tar.gz
+ asset_path: ${{github.workspace}}/build/solppc/solppc_darwin.tar.gz
+ asset_content_type: application/octet-stream
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index 0ae8334..0a9bb46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,8 @@ docs/utils/*.pyc
deps/install
deps/cache
cmake-build-*/
+upload/
+soljson.js
# vim stuff
[._]*.sw[a-p]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4afa022..8da44a9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,5 +66,12 @@ add_subdirectory(libyul)
add_subdirectory(libevmasm)
add_subdirectory(libsmtutil)
add_subdirectory(libsolidity)
-add_subdirectory(solppc)
-add_subdirectory(test)
+add_subdirectory(libsolc)
+
+if (NOT EMSCRIPTEN)
+ add_subdirectory(solppc)
+endif()
+
+if (TESTS AND NOT EMSCRIPTEN)
+ add_subdirectory(test)
+endif()
diff --git a/libsolc/CMakeLists.txt b/libsolc/CMakeLists.txt
new file mode 100644
index 0000000..f387122
--- /dev/null
+++ b/libsolc/CMakeLists.txt
@@ -0,0 +1,14 @@
+include_directories(AFTER ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/solidity)
+
+if (EMSCRIPTEN)
+ # Specify which functions to export in soljson.js.
+ # Note that additional Emscripten-generated methods needed by solc-js are
+ # defined to be exported in cmake/EthCompilerSettings.cmake.
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXPORTED_FUNCTIONS='[\"_solidity_license\",\"_solidity_version\",\"_solidity_compile\",\"_solidity_alloc\",\"_solidity_free\",\"_solidity_reset\"]'")
+ add_executable(soljson libsolc.cpp libsolc.h)
+ target_link_libraries(soljson PRIVATE solidity)
+else()
+ add_library(libsolc libsolc.cpp libsolc.h)
+ set_target_properties(libsolc PROPERTIES OUTPUT_NAME solc)
+ target_link_libraries(libsolc PRIVATE solidity)
+endif()
diff --git a/libsolc/libsolc.cpp b/libsolc/libsolc.cpp
new file mode 100644
index 0000000..f87f075
--- /dev/null
+++ b/libsolc/libsolc.cpp
@@ -0,0 +1,162 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+/**
+ * @author Christian
+ * @date 2014
+ * Public compiler API.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "license.h"
+
+using namespace std;
+using namespace solidity;
+using namespace solidity::util;
+
+using solidity::frontend::ReadCallback;
+using solidity::frontend::StandardCompiler;
+
+namespace
+{
+
+// The strings in this list must not be resized after they have been added here (via solidity_alloc()), because
+// this may potentially change the pointer that was passed to the caller from solidity_alloc().
+static list solidityAllocations;
+
+/// Find the equivalent to @p _data in the list of allocations of solidity_alloc(),
+/// removes it from the list and returns its value.
+///
+/// If any invalid argument is being passed, it is considered a programming error
+/// on the caller-side and hence, will call abort() then.
+string takeOverAllocation(char const* _data)
+{
+ for (auto iter = begin(solidityAllocations); iter != end(solidityAllocations); ++iter)
+ if (iter->data() == _data)
+ {
+ string chunk = move(*iter);
+ solidityAllocations.erase(iter);
+ return chunk;
+ }
+
+ abort();
+}
+
+/// Resizes a std::string to the proper length based on the occurrence of a zero terminator.
+void truncateCString(string& _data)
+{
+ size_t pos = _data.find('\0');
+ if (pos != string::npos)
+ _data.resize(pos);
+}
+
+ReadCallback::Callback wrapReadCallback(CStyleReadFileCallback _readCallback, void* _readContext)
+{
+ ReadCallback::Callback readCallback;
+ if (_readCallback)
+ {
+ readCallback = [=](string const& _kind, string const& _data)
+ {
+ char* contents_c = nullptr;
+ char* error_c = nullptr;
+ _readCallback(_readContext, _kind.data(), _data.data(), &contents_c, &error_c);
+ ReadCallback::Result result;
+ result.success = true;
+ if (!contents_c && !error_c)
+ {
+ result.success = false;
+ result.responseOrErrorMessage = "Callback not supported.";
+ }
+ if (contents_c)
+ {
+ result.success = true;
+ result.responseOrErrorMessage = takeOverAllocation(contents_c);
+ }
+ if (error_c)
+ {
+ result.success = false;
+ result.responseOrErrorMessage = takeOverAllocation(error_c);
+ }
+ truncateCString(result.responseOrErrorMessage);
+ return result;
+ };
+ }
+ return readCallback;
+}
+
+string compile(string _input, CStyleReadFileCallback _readCallback, void* _readContext)
+{
+ StandardCompiler compiler(wrapReadCallback(_readCallback, _readContext));
+ return compiler.compile(move(_input));
+}
+
+}
+
+extern "C"
+{
+extern char const* solidity_license() noexcept
+{
+ static string fullLicenseText = otherLicenses + licenseText;
+ return fullLicenseText.c_str();
+}
+
+extern char const* solidity_version() noexcept
+{
+ return frontend::VersionString.c_str();
+}
+
+extern char* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback, void* _readContext) noexcept
+{
+ return solidityAllocations.emplace_back(compile(_input, _readCallback, _readContext)).data();
+}
+
+extern char* solidity_alloc(size_t _size) noexcept
+{
+ try
+ {
+ return solidityAllocations.emplace_back(_size, '\0').data();
+ }
+ catch (...)
+ {
+ // most likely a std::bad_alloc(), if at all.
+ return nullptr;
+ }
+}
+
+extern void solidity_free(char* _data) noexcept
+{
+ takeOverAllocation(_data);
+}
+
+extern void solidity_reset() noexcept
+{
+ // This is called right before each compilation, but not at the end, so additional memory
+ // can be freed here.
+ yul::YulStringRepository::reset();
+ solidityAllocations.clear();
+}
+}
diff --git a/libsolc/libsolc.h b/libsolc/libsolc.h
new file mode 100644
index 0000000..c5b3b3d
--- /dev/null
+++ b/libsolc/libsolc.h
@@ -0,0 +1,101 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+/**
+ * @author Christian
+ * @date 2014
+ * Public compiler API.
+ */
+
+#pragma once
+
+#include
+#include
+
+#ifdef __cplusplus
+#define SOLC_NOEXCEPT noexcept
+#else
+#define SOLC_NOEXCEPT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Callback used to retrieve additional source files or data.
+///
+/// @param _context The readContext passed to solidity_compile. Can be NULL.
+/// @param _kind The kind of callback (a string).
+/// @param _data The data for the callback (a string).
+/// @param o_contents A pointer to the contents of the file, if found. Allocated via solidity_alloc().
+/// @param o_error A pointer to an error message, if there is one.
+///
+/// The file (as well as error) contents that is to be allocated by the callback
+/// implementor must use the solidity_alloc() API to allocate its underlying
+/// storage. Ownership is then transferred to the compiler which will take care
+/// of the deallocation.
+///
+/// If the callback is not supported, *o_contents and *o_error must be set to NULL.
+typedef void (*CStyleReadFileCallback)(void* _context, char const* _kind, char const* _data, char** o_contents, char** o_error);
+
+/// Returns the complete license document.
+///
+/// The pointer returned must NOT be freed by the caller.
+char const* solidity_license() SOLC_NOEXCEPT;
+
+/// Returns the compiler version.
+///
+/// The pointer returned must NOT be freed by the caller.
+char const* solidity_version() SOLC_NOEXCEPT;
+
+/// Allocates a chunk of memory of @p _size bytes.
+///
+/// Use this function inside callbacks to allocate data that is to be passed to
+/// the compiler. You may use solidity_free() or solidity_reset() to free this
+/// memory again but it is not required as the compiler takes ownership for any
+/// data passed to it via callbacks.
+///
+/// This function will return NULL if the requested memory region could not be allocated.
+char* solidity_alloc(size_t _size) SOLC_NOEXCEPT;
+
+/// Explicitly frees the memory (@p _data) that was being allocated with solidity_alloc()
+/// or returned by a call to solidity_compile().
+///
+/// Important, this call will abort() in case of any invalid argument being passed to this call.
+void solidity_free(char* _data) SOLC_NOEXCEPT;
+
+/// Takes a "Standard Input JSON" and an optional callback (can be set to null). Returns
+/// a "Standard Output JSON". Both are to be UTF-8 encoded.
+///
+/// @param _input The input JSON to process.
+/// @param _readCallback The optional callback pointer. Can be NULL, but if not NULL,
+/// it can be called by the compiler to request additional input.
+/// Please see the documentation of the type for details.
+/// @param _readContext An optional context pointer passed to _readCallback. Can be NULL.
+///
+/// @returns A pointer to the result. The pointer returned must be freed by the caller using solidity_free() or solidity_reset().
+char* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback, void* _readContext) SOLC_NOEXCEPT;
+
+/// Frees up any allocated memory.
+///
+/// NOTE: the pointer returned by solidity_compile as well as any other pointer retrieved via solidity_alloc()
+/// is invalid after calling this!
+void solidity_reset() SOLC_NOEXCEPT;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp
index 8a5d246..c65513c 100644
--- a/libsolidity/codegen/YulUtilFunctions.cpp
+++ b/libsolidity/codegen/YulUtilFunctions.cpp
@@ -4146,7 +4146,7 @@ string YulUtilFunctions::panicFunction(util::PanicCode _code)
)")
("functionName", functionName)
("selector", util::selectorFromSignature("Panic(uint256)").str())
- ("code", toCompactHexWithPrefix(_code))
+ ("code", toCompactHexWithPrefix(static_cast(_code)))
.render();
});
}
diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh
new file mode 100755
index 0000000..406ac60
--- /dev/null
+++ b/scripts/build_emscripten.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+#------------------------------------------------------------------------------
+# Bash script for building Solidity for emscripten.
+#
+# The documentation for solidity is hosted at:
+#
+# https://docs.soliditylang.org
+#
+# ------------------------------------------------------------------------------
+# This file is part of solidity.
+#
+# solidity is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# solidity is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with solidity. If not, see
+#
+# (c) 2016 solidity contributors.
+#------------------------------------------------------------------------------
+
+set -e
+
+if test -z "$1"; then
+ BUILD_DIR="emscripten_build"
+else
+ BUILD_DIR="$1"
+fi
+
+# solbuildpackpusher/solidity-buildpack-deps:emscripten-4
+docker run -v $(pwd):/root/project -w /root/project \
+ solbuildpackpusher/solidity-buildpack-deps@sha256:434719d8104cab47712dd1f56f255994d04eb65b802c0d382790071c1a0c074b \
+ ./scripts/ci/build_emscripten.sh $BUILD_DIR
diff --git a/scripts/ci/build_emscripten.sh b/scripts/ci/build_emscripten.sh
new file mode 100755
index 0000000..36133fe
--- /dev/null
+++ b/scripts/ci/build_emscripten.sh
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+
+#------------------------------------------------------------------------------
+# This script builds the solidity binary using Emscripten.
+# Emscripten is a way to compile C/C++ to JavaScript.
+#
+# http://kripken.github.io/emscripten-site/
+#
+# First run install_dep.sh OUTSIDE of docker and then
+# run this script inside a docker image trzeci/emscripten
+#
+# The documentation for solidity is hosted at:
+#
+# https://docs.soliditylang.org
+#
+# ------------------------------------------------------------------------------
+# This file is part of solidity.
+#
+# solidity is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# solidity is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with solidity. If not, see
+#
+# (c) 2016 solidity contributors.
+#------------------------------------------------------------------------------
+
+set -ev
+
+if test -z "$1"; then
+ BUILD_DIR="emscripten_build"
+else
+ BUILD_DIR="$1"
+fi
+
+WORKSPACE=/root/project
+
+cd $WORKSPACE
+
+# shellcheck disable=SC2166
+if [[ "$CIRCLE_BRANCH" = release || -n "$CIRCLE_TAG" || -n "$FORCE_RELEASE" || "$(git tag --points-at HEAD 2>/dev/null)" == v* ]]
+then
+ echo -n >prerelease.txt
+else
+ # Use last commit date rather than build date to avoid ending up with builds for
+ # different platforms having different version strings (and therefore producing different bytecode)
+ # if the CI is triggered just before midnight.
+ TZ=UTC git show --quiet --date="format-local:%Y.%-m.%-d" --format="ci.%cd" >prerelease.txt
+fi
+if [ -n "$CIRCLE_SHA1" ]
+then
+ echo -n "$CIRCLE_SHA1" >commit_hash.txt
+fi
+
+mkdir -p $BUILD_DIR
+cd $BUILD_DIR
+emcmake cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBoost_USE_STATIC_LIBS=1 \
+ -DBoost_USE_STATIC_RUNTIME=1 \
+ -DTESTS=0 \
+ ..
+make -j3 solidity_BuildInfo.h soljson
+
+cd ..
+mkdir -p upload
+cp $BUILD_DIR/libsolc/soljson.js upload/
+cp $BUILD_DIR/libsolc/soljson.js ./
+
+OUTPUT_SIZE=`ls -la soljson.js`
+
+echo "Emscripten output size: $OUTPUT_SIZE"