special-casing vector-ref and vector-set
This commit is contained in:
parent
def882c23d
commit
018f1b2559
|
@ -1303,6 +1303,8 @@
|
||||||
(box? (Const-const knowledge))]
|
(box? (Const-const knowledge))]
|
||||||
[(list)
|
[(list)
|
||||||
(list? (Const-const knowledge))]
|
(list? (Const-const knowledge))]
|
||||||
|
[(vector)
|
||||||
|
(vector? (Const-const knowledge))]
|
||||||
[(pair)
|
[(pair)
|
||||||
(pair? (Const-const knowledge))]
|
(pair? (Const-const knowledge))]
|
||||||
[(caarpair)
|
[(caarpair)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"../type-helpers.rkt")
|
"../type-helpers.rkt")
|
||||||
(define-type OperandDomain (U 'number
|
(define-type OperandDomain (U 'number
|
||||||
'string
|
'string
|
||||||
|
'vector
|
||||||
'box
|
'box
|
||||||
'list
|
'list
|
||||||
'pair
|
'pair
|
||||||
|
@ -178,6 +179,8 @@
|
||||||
'null?
|
'null?
|
||||||
'not
|
'not
|
||||||
'eq?
|
'eq?
|
||||||
|
'vector-ref
|
||||||
|
'vector-set!
|
||||||
))
|
))
|
||||||
|
|
||||||
(ensure-type-subsetof KernelPrimitiveName/Inline KernelPrimitiveName)
|
(ensure-type-subsetof KernelPrimitiveName/Inline KernelPrimitiveName)
|
||||||
|
@ -288,4 +291,10 @@
|
||||||
(list 'any)]
|
(list 'any)]
|
||||||
|
|
||||||
[(eq? prim 'eq?)
|
[(eq? prim 'eq?)
|
||||||
(list 'any 'any)]))
|
(list 'any 'any)]
|
||||||
|
|
||||||
|
[(eq? prim 'vector-ref)
|
||||||
|
(list 'vector 'number)]
|
||||||
|
|
||||||
|
[(eq? prim 'vector-set!)
|
||||||
|
(list 'vector 'number 'any)]))
|
|
@ -52,8 +52,10 @@
|
||||||
[(*)
|
[(*)
|
||||||
(cond [(empty? checked-operands)
|
(cond [(empty? checked-operands)
|
||||||
(assemble-numeric-constant 1)]
|
(assemble-numeric-constant 1)]
|
||||||
|
[(< (length operands) MAX-JAVASCRIPT-ARGS-AT-ONCE)
|
||||||
|
(format "RT.checkedMul(M, ~a)" (string-join operands ","))]
|
||||||
[else
|
[else
|
||||||
(assemble-binop-chain "plt.baselib.numbers.multiply" checked-operands)])]
|
(format "RT.checkedMulSlowPath(M, [~a])" (string-join operands ","))])]
|
||||||
|
|
||||||
[(/)
|
[(/)
|
||||||
(assemble-binop-chain "plt.baselib.numbers.divide" checked-operands)]
|
(assemble-binop-chain "plt.baselib.numbers.divide" checked-operands)]
|
||||||
|
@ -111,6 +113,14 @@
|
||||||
[(list?)
|
[(list?)
|
||||||
(format "RT.isList(~a)"
|
(format "RT.isList(~a)"
|
||||||
(first checked-operands))]
|
(first checked-operands))]
|
||||||
|
|
||||||
|
[(vector-ref)
|
||||||
|
(format "RT.checkedVectorRef(M, ~a)"
|
||||||
|
(string-join operands ","))]
|
||||||
|
|
||||||
|
[(vector-set!)
|
||||||
|
(format "RT.checkedVectorSet(M, ~a)"
|
||||||
|
(string-join operands ","))]
|
||||||
|
|
||||||
[(pair?)
|
[(pair?)
|
||||||
(format "RT.isPair(~a)"
|
(format "RT.isPair(~a)"
|
||||||
|
@ -186,7 +196,9 @@
|
||||||
[(caarpair)
|
[(caarpair)
|
||||||
(format "RT.isCaarPair")]
|
(format "RT.isCaarPair")]
|
||||||
[(box)
|
[(box)
|
||||||
(format "RT.isBox")])])
|
(format "RT.isBox")]
|
||||||
|
[(vector)
|
||||||
|
(format "RT.isVector")])])
|
||||||
(format "RT.testArgument(M,~s,~a,~a,~a,~s)"
|
(format "RT.testArgument(M,~s,~a,~a,~a,~s)"
|
||||||
(symbol->string domain)
|
(symbol->string domain)
|
||||||
predicate
|
predicate
|
||||||
|
|
|
@ -1057,7 +1057,8 @@
|
||||||
2,
|
2,
|
||||||
function (M) {
|
function (M) {
|
||||||
var elts = checkVector(M, 'vector-ref', 0).elts;
|
var elts = checkVector(M, 'vector-ref', 0).elts;
|
||||||
var index = M.e[M.e.length-2];
|
var index = baselib.numbers.toFixnum(
|
||||||
|
checkNaturalInRange(M, 'vector-ref', 1, 0, elts.length));
|
||||||
return elts[index];
|
return elts[index];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -860,6 +860,34 @@
|
||||||
return sum;
|
return sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var checkedMul = function(M, x, y) {
|
||||||
|
var prod;
|
||||||
|
// fast path optimization: binop addition on fixnums
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
if (typeof(x) === 'number' && typeof(y) === 'number') {
|
||||||
|
prod = x * y;
|
||||||
|
if (prod < -9e15 || prod > 9e15) {
|
||||||
|
return checkedMulSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
|
}
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return checkedMulSlowPath(M, Array.prototype.slice.call(arguments, 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
var checkedMulSlowPath = function(M, args) {
|
||||||
|
var i;
|
||||||
|
var prod = 1;
|
||||||
|
for (i = 0; i < args.length; i++) {
|
||||||
|
if (! isNumber(args[i])) {
|
||||||
|
raiseArgumentTypeError(M, '*', 'number', i, args[i]);
|
||||||
|
}
|
||||||
|
prod = plt.baselib.numbers.multiply(prod, args[i]);
|
||||||
|
}
|
||||||
|
return prod;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var checkedSub = function(M, x, y) {
|
var checkedSub = function(M, x, y) {
|
||||||
// Assumption: at least two arguments to subtract.
|
// Assumption: at least two arguments to subtract.
|
||||||
var sum;
|
var sum;
|
||||||
|
@ -969,6 +997,51 @@
|
||||||
raiseArgumentTypeError(M, 'cdr', 'pair', 0, v);
|
raiseArgumentTypeError(M, 'cdr', 'pair', 0, v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var checkedVectorRef = function(M, vec, i) {
|
||||||
|
var expectedTypeName;
|
||||||
|
if (isVector(vec)) {
|
||||||
|
if (typeof(i) === 'number') {
|
||||||
|
if (i >= 0 && i < vec.elts.length) {
|
||||||
|
return vec.elts[i];
|
||||||
|
}
|
||||||
|
} else if (isNumber(i)) {
|
||||||
|
i = baselib.numbers.toFixnum(i);
|
||||||
|
if (i >= 0 && i < vec.elts.length) {
|
||||||
|
return vec.elts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectedTypeName = baselib.format.format('natural between 0 and ~a',
|
||||||
|
[vec.elts.length]);
|
||||||
|
raiseArgumentTypeError(M, 'vector-ref', expectedTypeName, 1, i);
|
||||||
|
} else {
|
||||||
|
raiseArgumentTypeError(M, 'vector-ref', 'vector', 0, vec);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var checkedVectorSet = function(M, vec, i, val) {
|
||||||
|
var expectedTypeName;
|
||||||
|
if (isVector(vec)) {
|
||||||
|
if (typeof(i) === 'number') {
|
||||||
|
if (i >= 0 && i < vec.elts.length) {
|
||||||
|
vec.elts[i] = val;
|
||||||
|
return VOID;
|
||||||
|
}
|
||||||
|
} else if (isNumber(i)) {
|
||||||
|
i = baselib.numbers.toFixnum(i);
|
||||||
|
if (i >= 0 && i < vec.elts.length) {
|
||||||
|
vec.elts[i] = val;
|
||||||
|
return VOID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectedTypeName = baselib.format.format('natural between 0 and ~a',
|
||||||
|
[vec.elts.length]);
|
||||||
|
raiseArgumentTypeError(M, 'vector-set!', expectedTypeName, 1, i);
|
||||||
|
} else {
|
||||||
|
raiseArgumentTypeError(M, 'vector-set!', 'vector', 0, vec);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1111,6 +1184,8 @@
|
||||||
exports['checkedNegate'] = checkedNegate;
|
exports['checkedNegate'] = checkedNegate;
|
||||||
exports['checkedAdd'] = checkedAdd;
|
exports['checkedAdd'] = checkedAdd;
|
||||||
exports['checkedAddSlowPath'] = checkedAddSlowPath;
|
exports['checkedAddSlowPath'] = checkedAddSlowPath;
|
||||||
|
exports['checkedMul'] = checkedMul;
|
||||||
|
exports['checkedMulSlowPath'] = checkedMulSlowPath;
|
||||||
exports['checkedSub'] = checkedSub;
|
exports['checkedSub'] = checkedSub;
|
||||||
exports['checkedSubSlowPath'] = checkedSubSlowPath;
|
exports['checkedSubSlowPath'] = checkedSubSlowPath;
|
||||||
exports['checkedNumEquals'] = checkedNumEquals;
|
exports['checkedNumEquals'] = checkedNumEquals;
|
||||||
|
@ -1119,4 +1194,6 @@
|
||||||
exports['checkedGreaterThanSlowPath'] = checkedGreaterThanSlowPath;
|
exports['checkedGreaterThanSlowPath'] = checkedGreaterThanSlowPath;
|
||||||
exports['checkedCar'] = checkedCar;
|
exports['checkedCar'] = checkedCar;
|
||||||
exports['checkedCdr'] = checkedCdr;
|
exports['checkedCdr'] = checkedCdr;
|
||||||
|
exports['checkedVectorRef'] = checkedVectorRef;
|
||||||
|
exports['checkedVectorSet'] = checkedVectorSet;
|
||||||
}(this.plt, this.plt.baselib));
|
}(this.plt, this.plt.baselib));
|
Loading…
Reference in New Issue
Block a user