// Copyright 2010 The Emscripten Authors. All rights reserved. // Emscripten is available under two separate licenses, the MIT license and the // University of Illinois/NCSA Open Source License. Both these licenses can be // found in the LICENSE file. //"use strict"; var Compiletime = { isPointerType: isPointerType, isStructType: isStructType, isNumberType: function(type) { return type in Compiletime.INT_TYPES || type in Compiletime.FLOAT_TYPES; }, INT_TYPES: set('i1', 'i8', 'i16', 'i32', 'i64'), FLOAT_TYPES: set('float', 'double'), }; // code used both at compile time and runtime is defined here, then put on // the Runtime object for compile time and support.js for the generated code function getNativeTypeSize(type) { switch (type) { case 'i1': case 'i8': return 1; case 'i16': return 2; case 'i32': return 4; case 'i64': return 8; case 'float': return 4; case 'double': return 8; default: { if (type[type.length-1] === '*') { return 4; // A pointer } else if (type[0] === 'i') { var bits = Number(type.substr(1)); assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); return bits / 8; } else { return 0; } } } } function alignMemory(size, factor) { if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default return Math.ceil(size / factor) * factor; } var Runtime = { getNativeTypeSize: getNativeTypeSize, alignMemory: alignMemory, //! Returns the size of a structure field, as C/C++ would have it (in 32-bit, //! for now). //! @param type The type, by name. getNativeFieldSize: function(type) { return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE); }, STACK_ALIGN: {{{ STACK_ALIGN }}}, POINTER_SIZE: 4, // 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 (!vararg && (type == 'i64' || type == 'double')) return 8; if (!type) return Math.min(size, 8); // align structures internally to 64 bits return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE); } }; // Additional runtime elements, that need preprocessing // Converts a value we have as signed, into an unsigned value. For // example, -1 in int32 would be a very large number as unsigned. function unSign(value, bits, ignore) { if (value >= 0) { return value; } return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts : Math.pow(2, bits) + value; } // Converts a value we have as unsigned, into a signed value. For // example, 200 in a uint8 would be a negative number. function reSign(value, bits, ignore) { if (value <= 0) { return value; } var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 : Math.pow(2, bits-1); if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors // TODO: In i64 mode 1, resign the two parts separately and safely value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts } return value; } // Allocated here in JS, after we have the runtime etc. prepared. // This constant is emitted into the JS or wasm code. var DYNAMICTOP_PTR = makeStaticAlloc(4); // "Process info" for syscalls is static and cannot change, so define it using // some fixed values var PROCINFO = { ppid: 1, pid: 42, sid: 42, pgid: 42 };