Skip to content

Commit 41f04d6

Browse files
author
Erik McClure
committed
RC1 commit
1 parent aedaca7 commit 41f04d6

22 files changed

Lines changed: 278 additions & 68 deletions

include/innative/export.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ typedef struct IN__EXPORTS
104104
/// \param name A name to use for the module. If the module data does not contain a name, this will be used.
105105
/// \param err A pointer to an integer that receives an error code should the function fail. Not valid until
106106
/// FinalizeEnvironment() is called.
107-
void (*AddModule)(Environment* env, const void* data, uint64_t size, const char* name, int* err);
107+
void (*AddModule)(Environment* env, const void* data, size_t size, const char* name, int* err);
108108

109109
/// Adds a prebuilt module object to the environment. This happens synchronously, regardless of multithreading flags.
110110
/// \param env The environment to modify.
@@ -128,7 +128,7 @@ typedef struct IN__EXPORTS
128128
/// \param size The length of the memory that the
129129
/// data pointer points to. If size is 0, the data pointer is actually a null terminated UTF8 encoded file path.
130130
/// \param name_override Resolves all functions in this embedded library as raw C functions with the given module name.
131-
enum IN_ERROR (*AddEmbedding)(Environment* env, int tag, const void* data, uint64_t size, const char* name_override);
131+
enum IN_ERROR (*AddEmbedding)(Environment* env, int tag, const void* data, size_t size, const char* name_override);
132132

133133
/// Tells the linker to export the given symbol from the resulting binary.
134134
/// \param env The environment to modify.
@@ -204,6 +204,15 @@ typedef struct IN__EXPORTS
204204
/// \param global_index The index of the linear memory to retrieve.
205205
INGlobal* (*LoadMemoryIndex)(void* assembly, uint32_t module_index, uint32_t memory_index);
206206

207+
/// Searches for an exported function with the given name in a table and replaces the function pointer with another.
208+
/// \param assembly A pointer to a WebAssembly binary loaded by LoadAssembly.
209+
/// \param module_index The index of the module the table is exported from.
210+
/// \param table_index The index of the table to search through.
211+
/// \param function Name of the exported function to search the table for.
212+
/// \param replace function pointer to another function that should replace the function's table entry
213+
int (*ReplaceTableFuncPtr)(void* assembly, uint32_t module_index, uint32_t table_index, const char* function,
214+
IN_Entrypoint replace);
215+
207216
/// Clears the environment's cached compilation of a given module, or clears the entire cache if the module is a null
208217
/// pointer.
209218
/// \param env The environment to clear.

include/innative/innative.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,26 @@ limitations under the License.
8686
#define IN_CPU_POWERPC
8787
#define IN_32BIT
8888
#endif
89+
#elif defined(__wasm64) || defined(__wasm64__)
90+
#define IN_CPU_WASM64
91+
#define IN_CPU_WASM
92+
#define IN_64BIT
93+
#elif defined(__wasm32) || defined(__wasm32__) || defined(__wasm) || defined(__wasm__)
94+
#define IN_CPU_WASM32
95+
#define IN_CPU_WASM
96+
#define IN_32BIT
8997
#else
9098
#define IN_CPU_UNKNOWN // Unknown CPU architecture (should force architecture independent C implementations)
9199
#endif
92100

93101
// Compiler detection and macro generation
94102
#if defined(__clang__) // Clang (must be before GCC, because clang also pretends it's GCC)
95103
#define IN_COMPILER_CLANG
96-
#define IN_COMPILER_DLLEXPORT __attribute__((dllexport))
104+
#ifdef IN_CPU_WASM
105+
#define IN_COMPILER_DLLEXPORT __attribute__((visibility("default")))
106+
#else
107+
#define IN_COMPILER_DLLEXPORT __attribute__((dllexport))
108+
#endif
97109
#define IN_COMPILER_DLLIMPORT __attribute__((dllimport))
98110
#define IN_COMPILER_FASTCALL __attribute__((fastcall))
99111
#define IN_COMPILER_NAKED __attribute__((naked))
@@ -157,11 +169,17 @@ limitations under the License.
157169

158170
#if !(defined(IN_PLATFORM_WIN32) || defined(IN_PLATFORM_POSIX) || defined(IN_PLATFORM_WIN32_CE) || \
159171
defined(IN_PLATFORM_APPLE))
160-
#error "Unknown Platform"
172+
#ifdef IN_CPU_WASM // On webassembly we assume the WASI platform
173+
#define IN_PLATFORM_WASI
174+
#else
175+
#error "Unknown Platform"
176+
#endif
161177
#endif
162178

163179
// Endianness detection
164-
#if defined(IN_PLATFORM_WIN32) || defined(IN_PLATFORM_WIN32_CE) || defined(IN_CPU_x86_64) || defined(IN_CPU_x86) || \
180+
#ifdef IN_CPU_WASM
181+
#define IN_ENDIAN_LITTLE
182+
#elif defined(IN_PLATFORM_WIN32) || defined(IN_PLATFORM_WIN32_CE) || defined(IN_CPU_x86_64) || defined(IN_CPU_x86) || \
165183
defined(IN_CPU_IA_64) // Windows, x86, x86_64 and itanium all only run in little-endian (except on HP-UX but we don't
166184
// support that)
167185
#define IN_ENDIAN_LITTLE

innative-cmd/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ int main(int argc, char* argv[])
510510
env->log = stdout;
511511
return env;
512512
};
513-
exports.AddModule = [](Environment* env, const void* data, uint64_t size, const char* name, int* err) {
513+
exports.AddModule = [](Environment* env, const void* data, size_t size, const char* name, int* err) {
514514
if(!size)
515515
{
516516
long sz = 0;
@@ -534,7 +534,7 @@ int main(int argc, char* argv[])
534534
}
535535
return ERR_SUCCESS;
536536
};
537-
exports.AddEmbedding = [](Environment* env, int tag, const void* data, uint64_t size,
537+
exports.AddEmbedding = [](Environment* env, int tag, const void* data, size_t size,
538538
const char* name_override) -> IN_ERROR {
539539
char buf[20];
540540
_itoa_s(tag, buf, 10);

innative-test/benchmark.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void Benchmarks::Run(FILE* out)
2222
fprintf(out, "%-*s %-*s %-*s %-*s %-*s %-*s\n", COLUMNS[0], "---------", COLUMNS[1], "-----", COLUMNS[2], "-----",
2323
COLUMNS[3], "------", COLUMNS[4], "-------", COLUMNS[5], "------");
2424

25-
DoBenchmark<int, int>(out, "../scripts/benchmark_debug.wasm", "debug", COLUMNS, &Benchmarks::debug, 20);
25+
//DoBenchmark<int, int>(out, "../scripts/benchmark_debug.wasm", "debug", COLUMNS, &Benchmarks::debug, 20);
2626
DoBenchmark<int, int>(out, "../scripts/benchmark_n-body.wasm", "nbody", COLUMNS, &Benchmarks::nbody, 11);
2727
DoBenchmark<int64_t, int64_t>(out, "../scripts/benchmark_fib.wasm", "fib", COLUMNS, &Benchmarks::fib, 37);
2828
DoBenchmark<int, int>(out, "../scripts/benchmark_fannkuch-redux.wasm", "fannkuch_redux", COLUMNS,

innative-test/benchmark_debug.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ struct Complex
99

1010
Complex() : a(0), b(1.0) {}
1111
explicit Complex(int i) : a(i), b(1.0) {}
12-
// virtual ~Complex() {}
13-
// virtual float get() { return a + b; }
14-
// virtual float get2() { return c->b + b; }
1512
};
1613

1714
/*struct Foo : virtual Complex
@@ -30,10 +27,14 @@ struct FooBar : Foo, Bar
3027
{
3128
FooBar(int i) { a = i; }
3229
virtual ~FooBar() {}
33-
float get3() { return get2(); }
3430
virtual float get() { return Foo::get(); }
3531
};*/
3632

33+
struct FooBar : Complex
34+
{
35+
long long d;
36+
};
37+
3738
extern "C" int converti(Complex* p) { return (int)p; }
3839
extern "C" float convertf(int p) { return (float)p; }
3940
extern "C" int addi(int a, int b) { return a + b; }
@@ -42,10 +43,14 @@ extern "C" int addi(int a, int b) { return a + b; }
4243
#include "benchmark.h"
4344
#include <stdint.h>
4445

46+
float (*testfn)(int) = nullptr;
47+
4548
int Benchmarks::debug(int n)
4649
#else
4750
#include <stdint.h>
4851

52+
__attribute__((visibility("default"))) float (*testfn)(int) = nullptr;
53+
4954
extern "C" void* malloc(uintptr_t n);
5055
extern "C" __attribute__((visibility("default"))) int debug(int n)
5156
#endif
@@ -55,7 +60,14 @@ extern "C" __attribute__((visibility("default"))) int debug(int n)
5560
f[1].a = n * n;
5661
f[2].a = n * n * n;
5762

58-
f[0].b = convertf(converti(&f[1]));
63+
testfn = &convertf;
64+
f[0].b = (*testfn)(converti(&f[1]));
65+
66+
auto& f1 = f[1].a;
67+
f1 = n * n + 1;
68+
69+
FooBar* foobar = (FooBar*)malloc(sizeof(FooBar));
70+
f[0].c = foobar;
5971

6072
f[0].c = &f[1];
6173
f[1].c = &f[2];

innative-test/funcreplace.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
__attribute__((visibility("default"))) int replace_me(int a, int b) { return a; }
2+
3+
int (*testfn)(int, int) = &replace_me;
4+
5+
__attribute__((visibility("default"))) extern int test(int i, int j)
6+
{
7+
return (*testfn)(i, j);
8+
}

innative-test/innative-test.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@
344344
<ClCompile Include="test_embedding.cpp" />
345345
<ClCompile Include="test_environment.cpp" />
346346
<ClCompile Include="test_errors.cpp" />
347+
<ClCompile Include="test_funcreplace.cpp" />
347348
<ClCompile Include="test_harness.cpp" />
348349
<ClCompile Include="test_malloc.cpp" />
349350
<ClCompile Include="test_manual.cpp" />

innative-test/innative-test.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
<ClCompile Include="benchmark_debug.cpp">
8585
<Filter>Source Files</Filter>
8686
</ClCompile>
87+
<ClCompile Include="test_funcreplace.cpp">
88+
<Filter>Source Files</Filter>
89+
</ClCompile>
8790
</ItemGroup>
8891
<ItemGroup>
8992
<ClInclude Include="benchmark.h">

innative-test/test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class TestHarness
3232
void test_malloc();
3333
void test_embedding();
3434
void test_errors();
35+
void test_funcreplace();
3536
int CompileWASM(const path& file);
3637

3738
inline std::pair<uint32_t, uint32_t> Results()

innative-test/test_funcreplace.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c)2019 Black Sphere Studios
2+
// For conditions of distribution and use, see copyright notice in innative.h
3+
4+
#include "test.h"
5+
#include "../innative/util.h"
6+
#include <signal.h>
7+
#include <setjmp.h>
8+
9+
using namespace innative;
10+
11+
int replacement(int a, int b) { return a + b; }
12+
13+
void TestHarness::test_funcreplace()
14+
{
15+
constexpr int i = 4;
16+
constexpr int j = 2;
17+
path dll_path = _folder / "funcreplace" IN_LIBRARY_EXTENSION;
18+
constexpr const char wasm_path[] = "../scripts/funcreplace.wasm";
19+
20+
Environment* env = (*_exports.CreateEnvironment)(1, 0, 0);
21+
env->flags |= ENV_LIBRARY | ENV_ENABLE_WAT;
22+
env->system = "env";
23+
#ifdef IN_DEBUG
24+
env->optimize = ENV_OPTIMIZE_O0;
25+
env->flags |= ENV_DEBUG;
26+
#endif
27+
28+
int err = (*_exports.AddEmbedding)(env, 0, (void*)INNATIVE_DEFAULT_ENVIRONMENT, 0, 0);
29+
TEST(!err);
30+
31+
(*_exports.AddModule)(env, wasm_path, 0, "funcreplace", &err);
32+
TEST(!err);
33+
err = (*_exports.FinalizeEnvironment)(env);
34+
TEST(!err);
35+
36+
err = (*_exports.Compile)(env, dll_path.u8string().c_str());
37+
TEST(!err);
38+
39+
(*_exports.DestroyEnvironment)(env);
40+
41+
void* assembly = (*_exports.LoadAssembly)(dll_path.u8string().c_str());
42+
if(assembly)
43+
{
44+
int (*test)(int, int) = (int (*)(int, int))(*_exports.LoadFunction)(assembly, "funcreplace", "test");
45+
TEST(test != nullptr);
46+
47+
(*_exports.ReplaceTableFuncPtr)(assembly, 0, 0, "replace_me", (IN_Entrypoint)&replacement);
48+
49+
if(test)
50+
TEST((*test)(i, j) == 6);
51+
52+
(*_exports.FreeAssembly)(assembly);
53+
}
54+
55+
remove(dll_path);
56+
}

0 commit comments

Comments
 (0)