From 4c242eb92ca2fcde5ce9a8c721df00f4fb4d1e19 Mon Sep 17 00:00:00 2001 From: Erik McClure Date: Sat, 8 Jun 2019 02:23:23 -0700 Subject: [PATCH] Fix memory, update tests. fix constant parsing --- include/innative/innative.h | 2 +- innative-env/internal.c | 2 ++ innative-runtime-setup/Product.wxs | 2 +- innative-sdk-setup/Product.wxs | 2 +- innative/lexer.cpp | 27 +++++++++++++++++++-------- innative/parse.cpp | 2 +- innative/tools.cpp | 6 +++--- innative/wat.cpp | 2 +- innative/wat.h | 18 ++++++++++++++---- spec | 2 +- 10 files changed, 44 insertions(+), 21 deletions(-) diff --git a/include/innative/innative.h b/include/innative/innative.h index 2105b03..356ed5c 100644 --- a/include/innative/innative.h +++ b/include/innative/innative.h @@ -19,7 +19,7 @@ limitations under the License. #define INNATIVE_VERSION_MAJOR 0 #define INNATIVE_VERSION_MINOR 1 -#define INNATIVE_VERSION_REVISION 0 +#define INNATIVE_VERSION_REVISION 1 #define INNATIVE_VERSION(v, m, r, b) (((v|0ULL)<<48) | ((m|0ULL)<<32) | ((r|0ULL)<<16) | (b|0ULL)) // CPU Architecture (possible pre-defined macros found on http://predef.sourceforge.net/prearch.html) diff --git a/innative-env/internal.c b/innative-env/internal.c index de6454a..c5fc10c 100644 --- a/innative-env/internal.c +++ b/innative-env/internal.c @@ -69,6 +69,8 @@ IN_COMPILER_DLLEXPORT extern IN_COMPILER_NAKED void* _innative_syscall(size_t sy #else "movcc pc, lr\n\t" #endif + ); +} #else #error unsupported architecture! #endif diff --git a/innative-runtime-setup/Product.wxs b/innative-runtime-setup/Product.wxs index 9420af7..ffec40b 100644 --- a/innative-runtime-setup/Product.wxs +++ b/innative-runtime-setup/Product.wxs @@ -10,7 +10,7 @@ - + - + assign(begin + 3 + i, s - begin - 3 - i); + while(s < end && (*s == '_' || isxdigit(*s))) + { + if(target && *s != '_') + target->append(1, *s); + ++s; + } + return s; } @@ -155,12 +160,12 @@ namespace innative { if(strncasecmp(p, "inf", 3) != 0) return ERR_WAT_OUT_OF_RANGE; } - if(std::is_same::value && fabs(out) <= 1.1754942e-38f) // glibc incorrectly considers subnormal numbers as underflow and sets ERANGE in this case - errno = 0; - if(std::is_same::value && fabs(out) <= 2.2250738585072012e-308) - errno = 0; } #endif + if(std::is_same::value && fabs(out) <= 1.1754942e-38f) // WebAssembly never considers an underflow to be a range error, it rounds to zero + errno = 0; + if(std::is_same::value && fabs(out) <= 2.2250738585072012e-308) + errno = 0; if(errno == ERANGE) return ERR_WAT_OUT_OF_RANGE; // assert(!(errno != 0 || (end - numbuf.c_str()) != length)); @@ -174,7 +179,10 @@ namespace innative { numbuf.assign("400000"); // Hex for the first bit in the mantissa if(CheckTokenNAN(token.pos, token.pos + token.len, &numbuf)) { - union { uint32_t i; float f; } u = { 0x7F800000U | strtoul(numbuf.c_str(), &last, 16) }; + auto mantissa = strtoul(numbuf.c_str(), &last, 16); + if(mantissa < 0x1 || mantissa > 0x7fffff) + return ERR_WAT_OUT_OF_RANGE; + union { uint32_t i; float f; } u = { 0x7F800000U | mantissa }; if(token.pos[0] == '-') u.i |= 0x80000000U; @@ -197,7 +205,10 @@ namespace innative { numbuf.assign("8000000000000"); // Hex for the first bit in the mantissa if(CheckTokenNAN(token.pos, token.pos + token.len, &numbuf)) { - union { uint64_t i; double f; } u = { 0x7FF0000000000000ULL | strtoull(numbuf.c_str(), &last, 16) }; + auto mantissa = strtoull(numbuf.c_str(), &last, 16); + if(mantissa < 0x1 || mantissa > 0xfffffffffffff) + return ERR_WAT_OUT_OF_RANGE; + union { uint64_t i; double f; } u = { 0x7FF0000000000000ULL | mantissa }; if(token.pos[0] == '-') u.i |= 0x8000000000000000ULL; diff --git a/innative/parse.cpp b/innative/parse.cpp index 6eaf219..8dec506 100644 --- a/innative/parse.cpp +++ b/innative/parse.cpp @@ -311,7 +311,7 @@ IN_ERROR innative::ParseInstruction(Stream& s, Instruction& ins, const Environme ins.immediates[0]._varuint32 = s.ReadVarUInt32(err); if(err >= 0) - ins.immediates[1]._varuptr = s.ReadVarUInt64(err); + ins.immediates[1]._varuptr = s.ReadVarUInt32(err); // Currently 32-bit because all memories are 32-bit break; case OP_unreachable: diff --git a/innative/tools.cpp b/innative/tools.cpp index c5954e1..47c2db7 100644 --- a/innative/tools.cpp +++ b/innative/tools.cpp @@ -40,7 +40,10 @@ Environment* innative::CreateEnvironment(unsigned int modules, unsigned int maxt env->loglevel = LOG_WARNING; env->libpath = utility::AllocString(*env, GetProgramPath(arg0).BaseDir().Get()); if(!env->libpath) // Out of memory + { + free(env); return nullptr; + } env->objpath = 0; env->system = ""; @@ -65,12 +68,9 @@ void innative::DestroyEnvironment(Environment* env) return; ClearEnvironmentCache(env, 0); - for(varuint32 i = 0; i < env->n_modules; ++i) { kh_destroy_exports(env->modules[i].exports); - if(env->modules[i].importsection.imports) - free(env->modules[i].importsection.imports); assert(!env->modules[i].cache); } diff --git a/innative/wat.cpp b/innative/wat.cpp index 42287d9..4745d72 100644 --- a/innative/wat.cpp +++ b/innative/wat.cpp @@ -293,7 +293,7 @@ int WatParser::AppendImport(Module& m, const Import& i, varuint32* index) return ERR_WAT_INVALID_IMPORT_ORDER; // If we're trying to insert an import after declaring a table/func/global/memory, fail. *index = 0; - if(!(m.importsection.imports = trealloc(m.importsection.imports, ++m.importsection.n_import))) + if(ReallocArray(env, m.importsection.imports, m.importsection.n_import) != ERR_SUCCESS) return ERR_FATAL_OUT_OF_MEMORY; // Find the correct index to insert into diff --git a/innative/wat.h b/innative/wat.h index 7f240e4..274b56e 100644 --- a/innative/wat.h +++ b/innative/wat.h @@ -52,16 +52,16 @@ namespace innative { int ParseElemData(Queue& tokens, varuint32& index, Instruction& op, wat::kh_indexname_t* hash); int ParseElem(TableInit& e, Queue& tokens); int ParseData(Queue& tokens); + int AppendImport(Module& m, const Import& i, varuint32* index); + int InlineImportExport(const Environment& env, Module& m, Queue& tokens, varuint32* index, varuint7 kind, Import** out); static int ParseBlockType(Queue& tokens, varsint7& out); static int ParseModule(Environment& env, Module& m, Queue& tokens, utility::StringRef name, WatToken& internalname); static int ParseName(const Environment& env, ByteArray& name, const WatToken& t); - static int AppendImport(Module& m, const Import& i, varuint32* index); static int AddWatValType(const Environment& env, WatTokenID id, varsint7*& a, varuint32& n); static int WatString(const Environment& env, ByteArray& str, utility::StringRef t); static void WriteUTF32(uint32_t ch, ByteArray& str, varuint32& index); static varsint7 WatValType(WatTokenID id); - static int InlineImportExport(const Environment& env, Module& m, Queue& tokens, varuint32* index, varuint7 kind, Import** out); static int ParseLocalAppend(const Environment& env, FunctionBody& body, Queue& tokens); static int AddName(wat::kh_indexname_t* h, WatToken t, varuint32 index); @@ -78,7 +78,7 @@ namespace innative { } template - inline static int AppendArray(const Environment& env, T item, T*& a, varuint32& n) + inline static int ReallocArray(const Environment& env, T*& a, varuint32& n) { // We only allocate power of two chunks from our greedy allocator varuint32 i = utility::NextPow2(n++); @@ -87,9 +87,19 @@ namespace innative { T* old = a; if(!(a = utility::tmalloc(env, n * 2))) return ERR_FATAL_OUT_OF_MEMORY; - utility::tmemcpy(a, n * 2, old, n - 1); // Don't free old because it was from a greedy allocator. + if(old != nullptr) + utility::tmemcpy(a, n * 2, old, n - 1); // Don't free old because it was from a greedy allocator. } + return ERR_SUCCESS; + } + + template + inline static int AppendArray(const Environment& env, T item, T*& a, varuint32& n) + { + int err; + if((err = ReallocArray(env, a, n)) != ERR_SUCCESS) + return err; a[n - 1] = item; return ERR_SUCCESS; } diff --git a/spec b/spec index e6dff60..305821c 160000 --- a/spec +++ b/spec @@ -1 +1 @@ -Subproject commit e6dff60130cf8f6e8a228835a6062299418e1f43 +Subproject commit 305821c02ef7790dbbc3ecde1da233b1307b0fe3