Esempio n. 1
0
extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs) {
    i64 orig_rhs = rhs;
    i64 rtn = 1, curpow = lhs;

    if (rhs < 0)
        return boxFloat(pow_float_float(lhs, rhs));

    if (rhs == 0) {
        if (lhs < 0)
            return boxInt(-1);
        return boxInt(1);
    }

    assert(rhs > 0);
    while (rhs) {
        if (rhs & 1) {
            // TODO: could potentially avoid restarting the entire computation on overflow?
            if (__builtin_smull_overflow(rtn, curpow, &rtn))
                return longPow(boxLong(lhs), boxLong(orig_rhs));
        }
        if (__builtin_smull_overflow(curpow, curpow, &curpow))
            return longPow(boxLong(lhs), boxLong(orig_rhs));

        rhs >>= 1;
    }
    return boxInt(rtn);
}
Esempio n. 2
0
OBJ
readNumber(OBJ inStream, char firstChar, int isNegative){
	//printf(YEL "\nreadNumber>" RESET);

	/*
 	* TO-DO refactor!	
 	*/	
	jscheme_int64 *iVal = NULL;
	char ch;
	OBJ retVal;

	// substract the ASCII value of '0' from char to get the actual value between 0 and 9.
	jscheme_int64 start = (jscheme_int64) firstChar - '0';
	if(isNegative) start *= -1;

	iVal = &start;
	while( isDigit( ch = nextChar(inStream) )){
		//iVal = iVal * 10 + ( (int)ch - '0');

		jscheme_int64 ch_val = (jscheme_int64) ch - '0';
		
		if(isNegative){
			int mul = __builtin_smull_overflow(*iVal, 10, iVal);
			int sub = __builtin_ssubl_overflow(*iVal, ch_val, iVal);
			if( mul || sub ){
				if(thisIsTheEnd(inStream)){
					prompt_on();
				}
				js_error("readNumber: integer underflow", newInteger(*iVal));
			}
		}else{
			int mul = __builtin_smull_overflow(*iVal, 10, iVal);
			int add = __builtin_saddl_overflow(*iVal, ch_val, iVal);
			if( mul || add ){
				if(thisIsTheEnd(inStream)){
					prompt_on();
				}
				js_error("readNumber: integer overflow", newInteger(*iVal));
			}
		
		}
	}
	unreadChar(inStream, ch);
	retVal = newInteger( *iVal );
	return retVal;
}
Esempio n. 3
0
OBJ
builtin_times(int numArgs){
	jscheme_int64 *product= NULL;
	jscheme_int64 start = 1;
	product = &start;

	for(int i = 0; i < numArgs; i++){
		OBJ theArg = POP();
		
		if( !ISINTEGER(theArg)){
			POPN((numArgs - 1) - i);
			js_error("(*): non-integer argument", theArg);
		}
		if(__builtin_smull_overflow(*product,INTVAL(theArg),product)){
			// clean stack
			POPN((numArgs - 1) - i);
			js_error("(*): integer overflow", newInteger(*product));
		}
	}
	return newInteger(*product);
}
Esempio n. 4
0
extern "C" Box* mul_i64_i64(i64 lhs, i64 rhs) {
    i64 result;
    if (!__builtin_smull_overflow(lhs, rhs, &result))
        return boxInt(result);
    return longMul(boxLong(lhs), boxLong(rhs));
}