More optimizations. Also removed makeCheckParameterizedArgumentType: it's expensive. Rewrote baselib.checkNaturalInRange out explicitly for better performance.
This commit is contained in:
parent
06bc6ad34e
commit
def882c23d
|
@ -81,10 +81,11 @@
|
||||||
(format "RT.checkedNumEqualsSlowPath(M, [~a])" (string-join operands ","))])]
|
(format "RT.checkedNumEqualsSlowPath(M, [~a])" (string-join operands ","))])]
|
||||||
|
|
||||||
[(>)
|
[(>)
|
||||||
(format "RT.checkedGreaterThan(M, ~a)"
|
(cond
|
||||||
(string-join operands ","))
|
[(< (length operands) MAX-JAVASCRIPT-ARGS-AT-ONCE)
|
||||||
;; (assemble-boolean-chain "plt.baselib.numbers.greaterThan" checked-operands)
|
(format "RT.checkedGreaterThan(M, ~a)" (string-join operands ","))]
|
||||||
]
|
[else
|
||||||
|
(format "RT.checkedGreaterThanSlowPath(M, [~a])" (string-join operands ","))])]
|
||||||
|
|
||||||
[(>=)
|
[(>=)
|
||||||
(assemble-boolean-chain "plt.baselib.numbers.greaterThanOrEqual" checked-operands)]
|
(assemble-boolean-chain "plt.baselib.numbers.greaterThanOrEqual" checked-operands)]
|
||||||
|
|
|
@ -51,27 +51,6 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeCheckParameterizedArgumentType = function (parameterizedPredicate,
|
|
||||||
parameterizedPredicateName) {
|
|
||||||
return function (MACHINE, callerName, position) {
|
|
||||||
var args = [], i;
|
|
||||||
for (i = 3; i < arguments.length; i++) {
|
|
||||||
args.push(arguments[i]);
|
|
||||||
}
|
|
||||||
return testArgument(
|
|
||||||
MACHINE,
|
|
||||||
function () { return parameterizedPredicateName.apply(null, args); },
|
|
||||||
function (x) {
|
|
||||||
return parameterizedPredicate.apply(null, [x].concat(args));
|
|
||||||
},
|
|
||||||
MACHINE.e[MACHINE.e.length - 1 - position],
|
|
||||||
position,
|
|
||||||
callerName);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var makeCheckListofArgumentType = function (predicate, predicateName) {
|
var makeCheckListofArgumentType = function (predicate, predicateName) {
|
||||||
|
@ -172,15 +151,36 @@
|
||||||
baselib.bytes.isBytes,
|
baselib.bytes.isBytes,
|
||||||
'bytes');
|
'bytes');
|
||||||
|
|
||||||
var checkNaturalInRange = makeCheckParameterizedArgumentType(
|
var checkNaturalInRange = function(M, callerName, index, a, b) {
|
||||||
function (x, a, b) {
|
var expectedTypeName;
|
||||||
if (! baselib.numbers.isNatural(x)) { return false; }
|
var x = M.e[M.e.length - 1 - index];
|
||||||
return (baselib.numbers.lessThanOrEqual(a, x) &&
|
// fast path: if a, b, and x are numbers
|
||||||
baselib.numbers.lessThan(x, b));
|
if (typeof(x) === 'number' && typeof(a) === 'number' && typeof(b) === 'number') {
|
||||||
},
|
if (a <= x && x < b) {
|
||||||
function (a, b) {
|
return x;
|
||||||
return baselib.format.format('natural between ~a and ~a', [a, b]);
|
}
|
||||||
});
|
else {
|
||||||
|
expectedTypeName = baselib.format.format('natural between ~a and ~a', [a, b]);
|
||||||
|
return baselib.exceptions.raiseArgumentTypeError(m,
|
||||||
|
callerName,
|
||||||
|
expectedTypeName,
|
||||||
|
index,
|
||||||
|
x);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (baselib.numbers.lessThanOrEqual(a, x) && baselib.numbers.lessThan(x, b)) {
|
||||||
|
return x;
|
||||||
|
} else {
|
||||||
|
expectedTypeName = baselib.format.format('natural between ~a and ~a', [a, b]);
|
||||||
|
return baselib.exceptions.raiseArgumentTypeError(m,
|
||||||
|
callerName,
|
||||||
|
expectedTypeName,
|
||||||
|
index,
|
||||||
|
x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var checkInteger = makeCheckArgumentType(
|
var checkInteger = makeCheckArgumentType(
|
||||||
baselib.numbers.isInteger,
|
baselib.numbers.isInteger,
|
||||||
|
@ -271,7 +271,6 @@
|
||||||
exports.testArgument = testArgument;
|
exports.testArgument = testArgument;
|
||||||
exports.testArity = testArity;
|
exports.testArity = testArity;
|
||||||
exports.makeCheckArgumentType = makeCheckArgumentType;
|
exports.makeCheckArgumentType = makeCheckArgumentType;
|
||||||
exports.makeCheckParameterizedArgumentType = makeCheckParameterizedArgumentType;
|
|
||||||
exports.makeCheckListofArgumentType = makeCheckListofArgumentType;
|
exports.makeCheckListofArgumentType = makeCheckListofArgumentType;
|
||||||
exports.checkOutputPort = checkOutputPort;
|
exports.checkOutputPort = checkOutputPort;
|
||||||
exports.checkInputPort = checkInputPort;
|
exports.checkInputPort = checkInputPort;
|
||||||
|
|
|
@ -834,12 +834,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var checkedAdd = function(M, x, y) {
|
var checkedAdd = function(M, x, y) {
|
||||||
var i;
|
|
||||||
var sum;
|
var sum;
|
||||||
// fast path optimization: binop addition on fixnums
|
// fast path optimization: binop addition on fixnums
|
||||||
if (arguments.length === 3) {
|
if (arguments.length === 3) {
|
||||||
if (typeof(x) === 'number' &&
|
if (typeof(x) === 'number' && typeof(y) === 'number') {
|
||||||
typeof(y) === 'number') {
|
|
||||||
sum = x + y;
|
sum = x + y;
|
||||||
if (sum < -9e15 || sum > 9e15) {
|
if (sum < -9e15 || sum > 9e15) {
|
||||||
return checkedAddSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
return checkedAddSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
|
@ -847,19 +845,7 @@
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sum = 0;
|
|
||||||
for (i = 1; i < arguments.length; i++) {
|
|
||||||
if (typeof(arguments[i]) === 'number') {
|
|
||||||
sum += arguments[i];
|
|
||||||
if (sum < -9e15 || sum > 9e15) {
|
|
||||||
return checkedAddSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
return checkedAddSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return checkedAddSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var checkedAddSlowPath = function(M, args) {
|
var checkedAddSlowPath = function(M, args) {
|
||||||
|
@ -874,24 +860,20 @@
|
||||||
return sum;
|
return sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
var checkedSub = function(M) {
|
var checkedSub = function(M, x, y) {
|
||||||
// Assumption: at least two arguments to subtract.
|
// Assumption: at least two arguments to subtract.
|
||||||
var i;
|
var sum;
|
||||||
if (typeof(arguments[1]) !== 'number') {
|
// fast path optimization: binop subtraction on fixnums
|
||||||
return checkedSubSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
if (arguments.length === 3) {
|
||||||
}
|
if (typeof(x) === 'number' && typeof(y) === 'number') {
|
||||||
var sum = arguments[1];
|
sum = x - y;
|
||||||
for (i = 2; i < arguments.length; i++) {
|
|
||||||
if (typeof(arguments[i]) === 'number') {
|
|
||||||
sum -= arguments[i];
|
|
||||||
if (sum < -9e15 || sum > 9e15) {
|
if (sum < -9e15 || sum > 9e15) {
|
||||||
return checkedSubSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
return checkedSubSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return checkedSubSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum;
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return checkedSubSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
};
|
};
|
||||||
|
|
||||||
var checkedSubSlowPath = function(M, args) {
|
var checkedSubSlowPath = function(M, args) {
|
||||||
|
@ -917,27 +899,35 @@
|
||||||
return x > y;
|
return x > y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return checkedGreaterThanSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
|
};
|
||||||
|
|
||||||
// Slow path.
|
var checkedGreaterThanSlowPath = function(M, args) {
|
||||||
if (! isNumber(arguments[1])) {
|
if (! isNumber(args[0])) {
|
||||||
raiseArgumentTypeError(M, '>', 'number', 0, arguments[1]);
|
raiseArgumentTypeError(M, '>', 'number', 0, args[0]);
|
||||||
}
|
}
|
||||||
|
for (i = 1; i < args.length ; i++) {
|
||||||
for (i = 2; i < arguments.length ; i++) {
|
if (! isNumber(args[i])) {
|
||||||
if (! isNumber(arguments[i])) {
|
raiseArgumentTypeError(M, '>', 'number', i, args[i]);
|
||||||
raiseArgumentTypeError(M, '>', 'number', i-1, arguments[i]);
|
|
||||||
}
|
}
|
||||||
if (! plt.baselib.numbers.greaterThan(arguments[i-1],
|
if (! plt.baselib.numbers.greaterThan(args[i-1], args[i])) {
|
||||||
arugments[i])) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var checkedNumEquals = function(M) {
|
|
||||||
|
var checkedNumEquals = function(M, x, y) {
|
||||||
// Assumption: at least two arguments to compare
|
// Assumption: at least two arguments to compare
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
|
// fast path optimization: binop comparison on fixnums
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
if (typeof(x) === 'number' && typeof(y) === 'number') {
|
||||||
|
return x === y;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (typeof(arguments[1]) !== 'number') {
|
if (typeof(arguments[1]) !== 'number') {
|
||||||
return checkedNumEqualsSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
return checkedNumEqualsSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
}
|
}
|
||||||
|
@ -1126,6 +1116,7 @@
|
||||||
exports['checkedNumEquals'] = checkedNumEquals;
|
exports['checkedNumEquals'] = checkedNumEquals;
|
||||||
exports['checkedNumEqualsSlowPath'] = checkedNumEqualsSlowPath;
|
exports['checkedNumEqualsSlowPath'] = checkedNumEqualsSlowPath;
|
||||||
exports['checkedGreaterThan'] = checkedGreaterThan;
|
exports['checkedGreaterThan'] = checkedGreaterThan;
|
||||||
|
exports['checkedGreaterThanSlowPath'] = checkedGreaterThanSlowPath;
|
||||||
exports['checkedCar'] = checkedCar;
|
exports['checkedCar'] = checkedCar;
|
||||||
exports['checkedCdr'] = checkedCdr;
|
exports['checkedCdr'] = checkedCdr;
|
||||||
}(this.plt, this.plt.baselib));
|
}(this.plt, this.plt.baselib));
|
Loading…
Reference in New Issue
Block a user