modules/emscripten/src/runtime.js in webruby-0.2.2 vs modules/emscripten/src/runtime.js in webruby-0.2.4

- old
+ new

@@ -80,12 +80,12 @@ // Given two 32-bit unsigned parts of an emulated 64-bit number, combine them into a JS number (double). // Rounding is inevitable if the number is large. This is a particular problem for small negative numbers // (-1 will be rounded!), so handle negatives separately and carefully makeBigInt: function(low, high, unsigned) { - var unsignedRet = '(' + asmCoercion(makeSignOp(low, 'i32', 'un', 1, 1), 'float') + '+(' + asmCoercion(makeSignOp(high, 'i32', 'un', 1, 1), 'float') + '*' + asmEnsureFloat(4294967296, 'float') + '))'; - var signedRet = '(' + asmCoercion(makeSignOp(low, 'i32', 'un', 1, 1), 'float') + '+(' + asmCoercion(makeSignOp(high, 'i32', 're', 1, 1), 'float') + '*' + asmEnsureFloat(4294967296, 'float') + '))'; + var unsignedRet = '(' + asmCoercion(makeSignOp(low, 'i32', 'un', 1, 1), 'double') + '+(' + asmCoercion(makeSignOp(high, 'i32', 'un', 1, 1), 'double') + '*' + asmEnsureFloat(4294967296, 'double') + '))'; + var signedRet = '(' + asmCoercion(makeSignOp(low, 'i32', 'un', 1, 1), 'double') + '+(' + asmCoercion(makeSignOp(high, 'i32', 're', 1, 1), 'double') + '*' + asmEnsureFloat(4294967296, 'double') + '))'; if (typeof unsigned === 'string') return '(' + unsigned + ' ? ' + unsignedRet + ' : ' + signedRet + ')'; return unsigned ? unsignedRet : signedRet; } }; @@ -143,11 +143,11 @@ //! Returns the size of a type, as C/C++ would have it (in 32-bit), in bytes. //! @param type The type, by name. getNativeTypeSize: function(type) { #if QUANTUM_SIZE == 1 - return 1; + return 1; #else switch (type) { case 'i1': case 'i8': return 1; case 'i16': return 2; case 'i32': return 4; @@ -159,10 +159,12 @@ return Runtime.QUANTUM_SIZE; // A pointer } else if (type[0] === 'i') { var bits = parseInt(type.substr(1)); assert(bits % 8 === 0); return bits/8; + } else { + return 0; } } } #endif }, @@ -181,12 +183,15 @@ STACK_ALIGN: {{{ STACK_ALIGN }}}, // type can be a native type or a struct (or null, for structs we only look at size here) getAlignSize: function(type, size, vararg) { // we align i64s and doubles on 64-bit boundaries, unlike x86 +#if TARGET_LE32 == 1 + if (vararg) return 8; +#endif #if TARGET_LE32 - if (type == 'i64' || type == 'double' || vararg) return 8; + if (!vararg && (type == 'i64' || type == 'double')) return 8; if (!type) return Math.min(size, 8); // align structures internally to 64 bits #endif return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE); }, @@ -222,13 +227,20 @@ } } else if (field[0] == 'b') { // bN, large number field, like a [N x i8] size = field.substr(1)|0; alignSize = 1; - } else { - assert(field[0] === '<', field); // assumed to be a vector type, if none of the above + } else if (field[0] === '<') { + // vector type size = alignSize = Types.types[field].flatSize; // fully aligned + } else if (field[0] === 'i') { + // illegal integer field, that could not be legalized because it is an internal structure field + // it is ok to have such fields, if we just use them as markers of field size and nothing more complex + size = alignSize = parseInt(field.substr(1))/8; + assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field); + } else { + assert(false, 'invalid type for calculateStructAlignment'); } if (type.packed) alignSize = 1; type.alignSize = Math.max(type.alignSize, alignSize); var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory type.flatSize = curr + size; @@ -370,10 +382,22 @@ var table = FUNCTION_TABLE; table[index] = null; #endif }, + getAsmConst: function(code, numArgs) { + // code is a constant string on the heap, so we can cache these + if (!Runtime.asmConstCache) Runtime.asmConstCache = {}; + var func = Runtime.asmConstCache[code]; + if (func) return func; + var args = []; + for (var i = 0; i < numArgs; i++) { + args.push(String.fromCharCode(36) + i); // $0, $1 etc + } + return Runtime.asmConstCache[code] = eval('(function(' + args.join(',') + '){ ' + Pointer_stringify(code) + ' })'); // new Function does not allow upvars in node + }, + warnOnce: function(text) { if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {}; if (!Runtime.warnOnce.shown[text]) { Runtime.warnOnce.shown[text] = 1; Module.printErr(text); @@ -383,11 +407,11 @@ funcWrappers: {}, getFuncWrapper: function(func, sig) { assert(sig); if (!Runtime.funcWrappers[func]) { - Runtime.funcWrappers[func] = function() { + Runtime.funcWrappers[func] = function dynCall_wrapper() { return Runtime.dynCall(sig, func, arguments); }; } return Runtime.funcWrappers[func]; }, @@ -441,10 +465,10 @@ (codePoint - 0x10000) % 0x400 + 0xDC00); } buffer.length = 0; return ret; } - this.processJSString = function(string) { + this.processJSString = function processJSString(string) { string = unescape(encodeURIComponent(string)); var ret = []; for (var i = 0; i < string.length; i++) { ret.push(string.charCodeAt(i)); }