unsign in zext to prevent a sign error
This commit is contained in:
Родитель
b6aeefa650
Коммит
94db193155
|
@ -753,6 +753,8 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
|||
});
|
||||
|
||||
function makeSignOp(value, type, op) {
|
||||
if (!value) return value;
|
||||
if (!GUARD_SIGNS) return value;
|
||||
if (type in Runtime.INT_TYPES) {
|
||||
var bits = parseInt(type.substr(1));
|
||||
return op + 'Sign(' + value + ', ' + bits + ')';
|
||||
|
@ -772,16 +774,16 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
|||
for (var i = 1; i <= 4; i++) {
|
||||
if (item['param'+i]) {
|
||||
item['ident'+i] = indexizeFunctions(finalizeLLVMParameter(item['param'+i]));
|
||||
} else {
|
||||
item['ident'+i] = null; // just so it exists for purposes of reading ident2 etc. later on, and no exception is thrown
|
||||
}
|
||||
}
|
||||
if (GUARD_SIGNS) {
|
||||
if (op[0] == 'u' || (variant && variant[0] == 'u')) {
|
||||
ident1 = makeSignOp(ident1, type, 'un');
|
||||
ident2 = makeSignOp(ident2, type, 'un');
|
||||
} else if (op[0] == 's' || (variant && variant[0] == 's')) {
|
||||
ident1 = makeSignOp(ident1, type, 're');
|
||||
ident2 = makeSignOp(ident2, type, 're');
|
||||
}
|
||||
if (op[0] == 'u' || op[0] == 'z' || (variant && variant[0] == 'u')) { // z for zext, see below
|
||||
ident1 = makeSignOp(ident1, type, 'un');
|
||||
ident2 = makeSignOp(ident2, type, 'un');
|
||||
} else if (op[0] == 's' || (variant && variant[0] == 's')) {
|
||||
ident1 = makeSignOp(ident1, type, 're');
|
||||
ident2 = makeSignOp(ident2, type, 're');
|
||||
}
|
||||
var bits = null;
|
||||
if (item.type[0] === 'i') {
|
||||
|
@ -838,13 +840,17 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria
|
|||
default: throw 'Unknown fcmp variant: ' + variant;
|
||||
}
|
||||
}
|
||||
case 'zext': case 'fpext': case 'sext': case 'fptrunc': return ident1;
|
||||
// Note that zext has sign checking, see above. We must guard against -33 in i8 turning into -33 in i32
|
||||
// then unsigning that i32... which would give something huge.
|
||||
case 'zext': case 'fpext': case 'sext': return ident1;
|
||||
case 'fptrunc': return ident1;
|
||||
case 'trunc': {
|
||||
// Unlike extending, which we just 'do' (by doing nothing),
|
||||
// truncating can change the number, e.g. by truncating to an i1
|
||||
// in order to get the first bit
|
||||
assert(ident2[0] == 'i');
|
||||
var bitsLeft = ident2.substr(1);
|
||||
assert(bitsLeft <= 32, 'Cannot truncate to more than 32 bits, since we use a native & op');
|
||||
return '((' + ident1 + ') & ' + (Math.pow(2, bitsLeft)-1) + ')';
|
||||
}
|
||||
case 'select': return ident1 + ' ? ' + ident2 + ' : ' + ident3;
|
||||
|
|
|
@ -168,6 +168,12 @@ var Library = {
|
|||
}
|
||||
}
|
||||
return Pointer_make(ret.concat(0), 0, ALLOC_STACK); // NB: Stored on the stack
|
||||
//var len = ret.length+1;
|
||||
//var ret = Pointer_make(ret.concat(0), 0, ALLOC_STACK); // NB: Stored on the stack
|
||||
//STACKTOP -= len; // XXX horrible hack. we rewind the stack, to 'undo' the alloc we just did.
|
||||
// // the point is that this works if nothing else allocs on the stack before
|
||||
// // the string is read, which should be true - it is very transient, see the *printf* functions below.
|
||||
//return ret;
|
||||
},
|
||||
|
||||
printf__deps: ['_formatString'],
|
||||
|
@ -451,7 +457,7 @@ var Library = {
|
|||
exit: function(status) {
|
||||
__shutdownRuntime__();
|
||||
ABORT = true;
|
||||
throw 'exit(' + status + ') called.';
|
||||
throw 'exit(' + status + ') called, at ' + new Error().stack;
|
||||
},
|
||||
|
||||
atexit: function(func) {
|
||||
|
@ -541,6 +547,7 @@ var Library = {
|
|||
// TODO: optimize for the typed arrays case
|
||||
// || 0, since memcpy sometimes copies uninitialized areas XXX: Investigate why initializing alloc'ed memory does not fix that too
|
||||
{{{ makeCopyValue('dest', 'i', 'src', 'i', 'null', ' || 0') }}};
|
||||
// XXX Try copying the safe-heap type info, instead of using null
|
||||
}
|
||||
},
|
||||
llvm_memcpy_i32: 'memcpy',
|
||||
|
|
|
@ -301,11 +301,19 @@ if 'benchmark' not in sys.argv:
|
|||
}
|
||||
printf("*\\n");
|
||||
printf("*%.1d,%.2d*\\n", 56, 9);
|
||||
|
||||
// zext issue - see mathop in jsifier
|
||||
unsigned char x8 = -10;
|
||||
unsigned long hold = 0;
|
||||
hold += x8;
|
||||
int y32 = hold+50;
|
||||
printf("*%u,%u*\\n", hold, y32);
|
||||
|
||||
printf("*%ld*%p\\n", (long)21, &hash); // The %p should not enter an infinite loop!
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
self.do_test(src, '*5,23,10,19,121,1,37,1,0*\n0:-1,1:134217727,2:4194303,3:131071,4:4095,5:127,6:3,7:0,8:0*\n*56,09*\n*21*')
|
||||
self.do_test(src, '*5,23,10,19,121,1,37,1,0*\n0:-1,1:134217727,2:4194303,3:131071,4:4095,5:127,6:3,7:0,8:0*\n*56,09*\n*246,296*\n*21*')
|
||||
|
||||
def test_unsigned(self):
|
||||
src = '''
|
||||
|
|
Загрузка…
Ссылка в новой задаче