Skip to content

Commit 6353d59

Browse files
author
Erik McClure
committed
inNative v0.1.2 bugfixes
* Fixed certain C export name handling that could cause a crash * Added a regression test for the name handling bug. * Optimization is now on by default to avoid confusion (#18) * Fixed nonstandard use of `static const int`
1 parent 4c242eb commit 6353d59

File tree

9 files changed

+109
-14
lines changed

9 files changed

+109
-14
lines changed

include/innative/innative.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ limitations under the License.
1919

2020
#define INNATIVE_VERSION_MAJOR 0
2121
#define INNATIVE_VERSION_MINOR 1
22-
#define INNATIVE_VERSION_REVISION 1
22+
#define INNATIVE_VERSION_REVISION 2
2323
#define INNATIVE_VERSION(v, m, r, b) (((v|0ULL)<<48) | ((m|0ULL)<<32) | ((r|0ULL)<<16) | (b|0ULL))
2424

2525
// CPU Architecture (possible pre-defined macros found on http://predef.sourceforge.net/prearch.html)

include/innative/path.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ namespace innative {
1515
{
1616
public:
1717
#ifdef IN_PLATFORM_WIN32
18-
static const char SEPERATOR = '\\';
19-
static const char OTHER = '/';
18+
enum : char { SEPERATOR = '\\' };
19+
enum : char { OTHER = '/' };
2020
#elif defined(IN_PLATFORM_POSIX)
21-
static const char SEPERATOR = '/';
22-
static const char OTHER = '\\';
21+
enum : char { SEPERATOR = '/' };
22+
enum : char { OTHER = '\\' };
2323
#else
2424
#error "unknown platform"
2525
#endif
@@ -118,7 +118,9 @@ namespace innative {
118118
protected:
119119
inline void _canonize()
120120
{
121-
std::replace(_path.begin(), _path.end(), OTHER, SEPERATOR);
121+
char other = OTHER; // std::replace takes the address of it's operators, which breaks on any constant that doesn't necessarily exist.
122+
char seperator = SEPERATOR;
123+
std::replace(_path.begin(), _path.end(), other, seperator);
122124
}
123125

124126
std::string _path;

innative-cmd/main.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ int main(int argc, char* argv[])
137137
std::vector<std::pair<const char*, int>> embeddings;
138138
std::vector<const char*> whitelist;
139139
unsigned int flags = ENV_ENABLE_WAT; // Always enable WAT
140-
unsigned int optimize = 0;
140+
unsigned int optimize = ENV_OPTIMIZE_O3; // Default to O3
141141
innative::Path out;
142142
std::vector<const char*> wast; // WAST files will be executed in the order they are specified, after all other modules are injected into the environment
143143
const char* libpath = nullptr;
@@ -192,6 +192,8 @@ int main(int argc, char* argv[])
192192
std::cout << "Unknown flag: " << argv[i] << std::endl;
193193
err = ERR_UNKNOWN_FLAG;
194194
}
195+
else if(flag->second == ENV_OPTIMIZE_O0 || (flag->second & ENV_OPTIMIZE_OMASK))
196+
optimize = (optimize & ~ENV_OPTIMIZE_OMASK) | flag->second;
195197
else
196198
optimize |= flag->second;
197199
}
@@ -454,6 +456,8 @@ int main(int argc, char* argv[])
454456
printerr(env->log, "Error loading modules", err);
455457
dump_validation_errors(env);
456458
}
459+
460+
(*exports.DestroyEnvironment)(env);
457461
return err;
458462
}
459463

@@ -464,6 +468,7 @@ int main(int argc, char* argv[])
464468
if((*exports.AddEmbedding)(env, embeddings[i].second, embeddings[i].first, 0) == ERR_FATAL_FILE_ERROR)
465469
{
466470
fprintf(env->log, "Error loading file: %s\n", embeddings[i].first);
471+
(*exports.DestroyEnvironment)(env);
467472
return ERR_FATAL_FILE_ERROR;
468473
}
469474

@@ -478,6 +483,8 @@ int main(int argc, char* argv[])
478483
printerr(env->log, "Error loading environment", err);
479484
dump_validation_errors(env);
480485
}
486+
487+
(*exports.DestroyEnvironment)(env);
481488
return err;
482489
}
483490

@@ -500,7 +507,7 @@ int main(int argc, char* argv[])
500507
innative_serialize_module(env, i, target.c_str());
501508
}
502509
}
503-
510+
504511
// Check if this is a .wast file, which must be handled differently because it's an entire environment
505512
if(wast.size() > 0)
506513
{
@@ -518,6 +525,7 @@ int main(int argc, char* argv[])
518525
dump_validation_errors(env);
519526
}
520527

528+
(*exports.DestroyEnvironment)(env);
521529
return err;
522530
}
523531

innative-env/internal.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,9 @@ IN_COMPILER_DLLEXPORT extern void _innative_internal_env_memdump(const unsigned
226226
}
227227
_innative_internal_write_out("\n", 1);
228228
}
229+
230+
// This function exists only to test the _WASM_ C export code path
231+
IN_COMPILER_DLLEXPORT extern void _innative_internal_WASM_print(int32_t a)
232+
{
233+
_innative_internal_env_print(a);
234+
}

innative-test/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
9393

9494
if(stages & TEST_INTERNAL)
9595
{
96-
TestHarness harness(stderr);
96+
TestHarness harness(exports, !argc ? 0 : argv[0], log, stderr, temppath.c_str());
9797
harness.Run(stdout);
9898
}
9999

innative-test/test.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
#include <stdio.h>
1010
#include <vector>
1111
#include <string.h>
12+
#include "innative/path.h"
13+
#include "innative/export.h"
1214

1315
class TestHarness
1416
{
1517
public:
16-
TestHarness(FILE* out);
18+
TestHarness(const IRExports& exports, const char* arg0, int loglevel, FILE* out, const char* folder);
19+
~TestHarness();
1720
size_t Run(FILE* out);
1821
void test_allocator();
1922
void test_environment();
@@ -24,6 +27,7 @@ class TestHarness
2427
void test_util();
2528
void test_parallel_parsing();
2629
void test_malloc();
30+
int CompileWASM(const char* file);
2731

2832
inline std::pair<uint32_t, uint32_t> Results() { auto r = _testdata; _testdata = { 0,0 }; return r; }
2933

@@ -46,6 +50,11 @@ class TestHarness
4650

4751
std::pair<uint32_t, uint32_t> _testdata;
4852
FILE* _target;
53+
const IRExports& _exports;
54+
const char* _arg0;
55+
int _loglevel;
56+
std::vector<std::string> _garbage;
57+
innative::Path _folder;
4958
};
5059

5160
#define TEST(x) DoTest(x, ""#x, __FILE__, __LINE__)

innative-test/test_harness.cpp

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
// For conditions of distribution and use, see copyright notice in innative.h
33

44
#include "test.h"
5+
#include <stdio.h>
56

6-
TestHarness::TestHarness(FILE* out) : _target(out), _testdata(0, 0) {}
7-
7+
TestHarness::TestHarness(const IRExports& exports, const char* arg0, int loglevel, FILE* out, const char* folder) : _exports(exports), _arg0(arg0), _loglevel(loglevel), _target(out), _folder(folder), _testdata(0, 0){}
8+
TestHarness::~TestHarness()
9+
{
10+
// Clean up all the files we just produced
11+
for(auto f : _garbage)
12+
std::remove(f.c_str());
13+
}
814
size_t TestHarness::Run(FILE* out)
915
{
1016
std::pair<const char*, void(TestHarness::*)()> tests[] = {
@@ -37,9 +43,56 @@ size_t TestHarness::Run(FILE* out)
3743
fprintf(out, "%-*s %-*s %-*s\n", COLUMNS[0], tests[i].first, COLUMNS[1], buf, COLUMNS[2], (results.first == results.second) ? "PASS" : "FAIL");
3844
}
3945

46+
{
47+
TEST(CompileWASM("../scripts/test-h.wat") == ERR_SUCCESS);
48+
49+
char buf[COLUMNS[1] + 1] = { 0 };
50+
auto results = Results();
51+
snprintf(buf, COLUMNS[1] + 1, "%u/%u", results.first, results.second);
52+
fprintf(out, "%-*s %-*s %-*s\n", COLUMNS[0], "aux tests", COLUMNS[1], buf, COLUMNS[2], (results.first == results.second) ? "PASS" : "FAIL");
53+
}
54+
4055
// Test compiling EXE
4156
// Test compiling DLL with entry point that gets called in the init function
4257

4358
fprintf(out, "\n");
4459
return failures;
45-
}
60+
}
61+
62+
int TestHarness::CompileWASM(const char* file)
63+
{
64+
Environment* env = (*_exports.CreateEnvironment)(1, 0, 0);
65+
env->flags = ENV_ENABLE_WAT | ENV_LIBRARY;
66+
env->optimize = ENV_OPTIMIZE_O3;
67+
env->features = ENV_FEATURE_ALL;
68+
env->log = stdout;
69+
env->loglevel = _loglevel;
70+
71+
int err = (*_exports.AddEmbedding)(env, 0, (void*)INNATIVE_DEFAULT_ENVIRONMENT, 0);
72+
if(err < 0)
73+
return err;
74+
75+
(*_exports.AddModule)(env, file, 0, file, &err);
76+
if(err < 0)
77+
return err;
78+
79+
(*_exports.FinalizeEnvironment)(env);
80+
std::string base = (_folder + innative::Path(file).File().RemoveExtension()).Get();
81+
std::string out = base + IN_LIBRARY_EXTENSION;
82+
83+
err = (*_exports.Compile)(env, out.c_str());
84+
if(err < 0)
85+
return err;
86+
87+
_garbage.push_back(out);
88+
#ifdef IN_PLATFORM_WIN32
89+
_garbage.push_back(base + ".lib");
90+
#endif
91+
(*_exports.DestroyEnvironment)(env);
92+
void* m = (*_exports.LoadAssembly)(out.c_str());
93+
if(!m)
94+
return ERR_FATAL_INVALID_MODULE;
95+
(*_exports.FreeAssembly)(m);
96+
97+
return ERR_SUCCESS;
98+
}

innative/compile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1950,7 +1950,7 @@ IN_ERROR CompileModule(const Environment* env, code::Context& context)
19501950
//if(context.dbuilder)
19511951
// FunctionDebugInfo(context.functions.back().imported, context, false, context.m.importsection.imports[i].func_desc.debug.line);
19521952

1953-
auto name = (context.m.importsection.imports[i].func_desc.debug.name.get()) ?
1953+
auto name = !(context.m.importsection.imports[i].func_desc.debug.name.get()) ?
19541954
"|" + context.functions.back().imported->getName() + "#internal" :
19551955
context.m.importsection.imports[i].func_desc.debug.name.str() + ("#" + std::to_string(i));
19561956

scripts/test-h.wat

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
(module
2+
(type (;0;) (func (param i32)))
3+
(type (;1;) (func))
4+
(import "_innative_internal" "print" (func (;0;) (type 0)))
5+
(func (;1;) (type 1)
6+
(local i32 i32 i32)
7+
i32.const 10
8+
local.set 0
9+
i32.const 104
10+
local.set 1
11+
i32.const 39
12+
local.set 2
13+
local.get 1
14+
call 0
15+
local.get 0
16+
call 0)
17+
(export "h" (func 1)))

0 commit comments

Comments
 (0)