Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental WebAssembly Port Using emscripten #1966

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ ipch/
*.*codeanalysis*
read.lock
fileList.bin

*.js
*.wasm
40 changes: 39 additions & 1 deletion ACE/ACE-INSTALL.html
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ <h1><a name="aceinstall">Building and Installing ACE</a></h1>
<li><a href="#win32">Windows (including MinGW and Cygwin)</a></li>
<li><a href="#vxworks">VxWorks</a></li>
<li><a href="#android">Android</a></li>
<li><a href="#emscripten">Emscripten WebAssembly</a></li>
</ul>

<h2>General Rules</h2>
Expand Down Expand Up @@ -1823,7 +1824,7 @@ <h3><a name="android-openssl">OpenSSL</a></h3>
OpenSSL. On Android, OpenSSL isn't part of the NDK Library and Android
preloads the system SSL library (either OpenSSL or BoringSSL) for the Java
Android API. This means OpenSSL <b>MUST</b> be statically linked to avoid
conflicts with the almost certianly incompatible system SSL library.
conflicts with the almost certainly incompatible system SSL library.

To build OpenSSL for Android, please read <code>NOTES.ANDROID</code> that comes
with OpenSSL's source code. The static libraries will used if the shared
Expand All @@ -1833,6 +1834,43 @@ <h3><a name="android-openssl">OpenSSL</a></h3>
building OpenSSL.
</p>

<hr align="left" width="50%">

<h2><a name="emscripten">Building ACE for Emscripten WebAssembly</a></h2>

<p><b>NOTE: This has only been tested on Linux with NodeJS 16.18.</b></p>

<a href="https://emscripten.org/">Emscripten</a>
is a LLVM toolchain that allows compiling C++ to
<a href="https://en.wikipedia.org/wiki/WebAssembly">WebAssembly</a>
that can be ran on a web browser or <a href="https://nodejs.org">NodeJS</a>.

<h3>Building</h3>

<ol>
<li>Download and setup <a href="https://emscripten.org/docs/getting_started/downloads.html">emscripten</a>.</li>
<li>Run <code>source emsdk_env.sh</code> in <code>emsdk</code>.</li>
<li>Make sure MPC is available and <code>MPC_ROOT</code> is set.</li>
<li>Configure ACE:
<ol>
<li><code>$ACE_ROOT/bin/MakeProjectCreator/config/default.features</code>
should contain <code>no_cxx11=0</code></li>
<li><code>$ACE_ROOT/include/makeinclude/platform_macros.GNU</code> should contain
<code>include $(ACE_ROOT)/include/makeinclude/platform_emscripten.GNU</code></li>
<li><code>$ACE_ROOT/ace/config.h</code> should contain
<code>#include "config-emscripten.h"</code></li>
<li><code>cd $ACE_ROOT/ace &amp;&amp; mwc.pl -type gnuace .</code></li>
</ol>
</li>
<li>Build ACE: <code>cd $ACE_ROOT/ace &amp;&amp; make -j4</code></li>
</ol>

<h3>Running Tests</h3>

<pre class="indent">
DOC_TEST_1=NODEJS NODEJS_OS=local ./run_test.pl -Config STATIC -Config NODEJS
</pre>

<hr>
<h1><a name="svcsinstall">Building and Installing ACE Network Services</a></h1>

Expand Down
2 changes: 2 additions & 0 deletions ACE/ace/Notification_Queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "ace/Intrusive_List.h"
#include "ace/Intrusive_List_Node.h"
#include "ace/Unbounded_Queue.h"
#include "ace/Synch_Traits.h"
#include "ace/Thread_Mutex.h"

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

Expand Down
3 changes: 3 additions & 0 deletions ACE/ace/Timer_Queue_T.inl
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// -*- C++ -*-

#include "ace/Guard_T.h"

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

template <class TYPE, class FUNCTOR> ACE_INLINE FUNCTOR &
Expand Down
54 changes: 54 additions & 0 deletions ACE/ace/config-emscripten.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef ACE_CONFIG_EMSCRIPTEN_H
#define ACE_CONFIG_EMSCRIPTEN_H

#define ACE_EMSCRIPTEN

#define ACE_HAS_CPP11

// Threading
#define ACE_MT_SAFE 1
#define ACE_HAS_THREADS 1
#define ACE_HAS_PTHREADS
#define ACE_HAS_PTHREADS_UNIX98_EXT
#define ACE_HAS_THREAD_SPECIFIC_STORAGE

// Basic Types
#define ACE_HAS_SSIZE_T
#define ACE_HAS_WCHAR

// Time
#define ACE_HAS_POSIX_TIME
#define ACE_LACKS_TIMESPEC_T
#define ACE_HAS_NONCONST_SELECT_TIMEVAL
#define ACE_HAS_VOIDPTR_GETTIMEOFDAY

// Everything else
#define ACE_HAS_UCONTEXT_T
#define ACE_HAS_MSG
#define ACE_HAS_CPU_SET_T
#define ACE_LACKS_ISCTYPE
#define ACE_HAS_STRBUF_T
#define ACE_HAS_SOCKLEN_T
#define ACE_LACKS_AUTO_PTR
#define ACE_HAS_SIGINFO_T
#define ACE_LACKS_SIGINFO_H
#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES
#define ACE_HAS_3_PARAM_WCSTOK
#define ACE_LACKS_ITOW
#define ACE_LACKS_WCSICMP
#define ACE_LACKS_WCSNICMP
#define ACE_HAS_DIRENT
#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG

// These exist, but don't seem to work correctly
#define ACE_LACKS_PWD_FUNCTIONS

#include "config-posix.h"
#include "config-g++-common.h"

// Not supported: https://github.com/emscripten-core/emscripten/issues/18050
#ifdef ACE_HAS_AIO_CALLS
# undef ACE_HAS_AIO_CALLS
#endif

#endif
3 changes: 2 additions & 1 deletion ACE/ace/os_include/sys/os_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ typedef double ACE_timer_t;

#if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG == 8
typedef off_t ACE_LOFF_T;
#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__APPLE__)
#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__APPLE__) || \
defined (ACE_EMSCRIPTEN)
typedef off_t ACE_LOFF_T;
#elif defined (__QNX__)
typedef off64_t ACE_LOFF_T;
Expand Down
21 changes: 21 additions & 0 deletions ACE/bin/PerlACE/ProcessNodeJS.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package PerlACE::ProcessNodeJS;

use strict;

use PerlACE::Process;
our @ISA = qw(PerlACE::Process);

sub new {
my $class = shift();
my $name = shift();
my $args = shift();
my $node_args = shift() // '';

my $self = $class->SUPER::new("$name.js", $node_args);
bless($self, $class);
$self->IgnoreExeSubDir(1);
$self->{VALGRIND_CMD} = "node $node_args";
return $self;
}

1;
5 changes: 5 additions & 0 deletions ACE/bin/PerlACE/Run_Test.pm
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ if ($PerlACE::Android_Test) {
require PerlACE::ProcessAndroid;
}

$PerlACE::NodeJS_Test = $config->check_config("NODEJS");
if ($PerlACE::NodeJS_Test) {
require PerlACE::ProcessNodeJS;
}

# Figure out the svc.conf extension
$svcconf_ext = $ENV{'ACE_RUNTEST_SVCCONF_EXT'};
if (!defined $svcconf_ext) {
Expand Down
28 changes: 18 additions & 10 deletions ACE/bin/PerlACE/TestTarget.pm
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ sub new
{
my $proto = shift;
my $class = ref ($proto) || $proto;
my $self = {};

my $config_name = shift;

my $self = {config_name => $config_name};

bless ($self, $class);
$self->GetConfigSettings($config_name);

Expand Down Expand Up @@ -505,7 +506,7 @@ sub DeleteFile ($)
print STDERR "Deleting remote $file from path $newfile using $cmd\n";
}
if (system ($cmd) != 0) {
print STDERR "ERROR executing [".$cmd."]\n";
print STDERR "ERROR executing [".$cmd."]\n";
}
} else {
unlink ($newfile);
Expand All @@ -523,9 +524,9 @@ sub GetFile ($)
$remote_file = $self->LocalFile($local_file);
}
if (defined $self->{GET_CMD}) {
if (system ($self->{GET_CMD}.' '.$remote_file.' '.$local_file) != 0) {
print STDERR "ERROR executing [".$self->{GET_CMD}." $remote_file $local_file]\n";
}
if (system ($self->{GET_CMD}.' '.$remote_file.' '.$local_file) != 0) {
print STDERR "ERROR executing [".$self->{GET_CMD}." $remote_file $local_file]\n";
}
}
elsif (($remote_file ne $local_file) &&
(File::Spec->rel2abs($remote_file) ne File::Spec->rel2abs($local_file))) {
Expand All @@ -541,9 +542,9 @@ sub PutFile ($)
my $src = shift;
my $dest = $self->LocalFile ($src);
if (defined $self->{PUT_CMD}) {
if (system ($self->{PUT_CMD}.' '.$src.' '.$dest) != 0) {
print STDERR "ERROR executing [".$self->{PUT_CMD}." $src $dest]\n";
}
if (system ($self->{PUT_CMD}.' '.$src.' '.$dest) != 0) {
print STDERR "ERROR executing [".$self->{PUT_CMD}." $src $dest]\n";
}
}
elsif (($src ne $dest) &&
(File::Spec->rel2abs($src) ne File::Spec->rel2abs($dest))) {
Expand Down Expand Up @@ -594,7 +595,14 @@ sub WaitForFileTimed ($)
sub CreateProcess ($)
{
my $self = shift;
my $process = new PerlACE::Process (@_);

my $process;
if ($self->{config_name} eq 'NODEJS') {
$process = new PerlACE::ProcessNodeJS(@_);
} else {
$process = new PerlACE::Process (@_);
}

$process->Target($self);
return $process;
}
Expand Down
8 changes: 5 additions & 3 deletions ACE/include/makeinclude/platform_clang_common.GNU
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ ifneq ($(CROSS_COMPILE),)
CXX = ${CROSS_COMPILE}clang++${CROSS_COMPILE_SUFFIX}
AR = ${CROSS_COMPILE}ar${CROSS_COMPILE_SUFFIX}
endif
# Cross-linker requires this for linked in shared libs that depend
# themselves on other shared libs (not directly linked in)
LDFLAGS += -Wl,-rpath-link,$(ACE_ROOT)/lib
ifneq ($(static_libs_only), 1)
# Cross-linker requires this for linked in shared libs that depend
# themselves on other shared libs (not directly linked in)
LDFLAGS += -Wl,-rpath-link,$(ACE_ROOT)/lib
endif
ifneq (,$(HOST_ROOT))
TAO_IDLFLAGS += -g $(HOST_ROOT)/bin/ace_gperf
TAO_IDL = $(HOST_ROOT)/bin/tao_idl
Expand Down
31 changes: 31 additions & 0 deletions ACE/include/makeinclude/platform_emscripten.GNU
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ACE_PLATFORM_CONFIG ?= config-emscripten.h
EXEEXT = .js

debug ?= 1
optimize ?= 0
threads ?= 1
inline ?= 1
static_libs_only = 1

CROSS_COMPILE := THIS_VALUE_SHOULD_NOT_BE_USED
override_cross_compile = 1
CC = emcc
CXX = em++
AR = emar
LD = emcc

ifeq ($(threads),1)
FLAGS_C_CC += -pthread
LDFLAGS += -pthread
LIBS += -lrt
endif

ifeq ($(debug),1)
LDFLAGS += -sASSERTIONS=2
endif

# TODO: Require choosing Filesystem model:
# https://emscripten.org/docs/api_reference/Filesystem-API.html
LDFLAGS += -sNODERAWFS=1

include $(ACE_ROOT)/include/makeinclude/platform_clang_common.GNU
2 changes: 1 addition & 1 deletion ACE/tests/OS_Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ ace_ctype_test ()
++retval;
}

return 0;
return retval;
}

int
Expand Down