-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Description
I'm implementing the last operators for the wasm runtime. I came across the implementation of EJsonRuntimeCompare in qcert-runtime-core.js. It looks a bit suspicious to me. I cannot judge whether it's a bug or not.
qcert/runtimes/javascript/qcert-runtime-core.js
Lines 79 to 133 in 0f07b1c
| function compare(v1, v2) { | |
| var t1 = typeof v1, t2 = typeof v2; | |
| if (t1 === 'object' && v1 !== null) { | |
| if (isNat(v1)) { t1 = 'number'; v1 = unboxNat(v1); } | |
| if (isBoxColl(v1)) { | |
| v1 = unboxColl(v1).slice(0, collLength(v1)); | |
| } | |
| }; | |
| if (t2 === 'object' && v2 !== null) { | |
| if (isNat(v2)) { t2 = 'number'; v2 = unboxNat(v2); } | |
| if (isBoxColl(v2)) { | |
| v2 = unboxColl(v2).slice(0, collLength(v2)); | |
| } | |
| } | |
| if (t1 != t2) { | |
| return t1 < t2 ? -1 : +1; | |
| } | |
| var a1 = {}.toString.apply(v1), a2 = {}.toString.apply(v2); | |
| if (a1 != a2) { | |
| return a1 < a2 ? -1 : +1; | |
| } | |
| if (a1 === '[object Array]') { | |
| v1 = v1.slice(); /* Sorting in place leads to inconsistencies, notably as it re-orders the input WM in the middle of processing */ | |
| v2 = v2.slice(); /* So we do the sort/compare on a clone of the original array */ | |
| v1.sort(compare); | |
| v2.sort(compare); | |
| } | |
| if (t1 === 'object') { | |
| var fields1 = []; | |
| var fields2 = []; | |
| for (var f1 in v1) { fields1.push(f1); } | |
| for (var f2 in v2) { fields2.push(f2); } | |
| fields1 = fields1.sort(compare); | |
| fields2 = fields2.sort(compare); | |
| for (var i = 0; i < fields1.length; i=i+1) { | |
| if (!(Object.prototype.hasOwnProperty.call(v2,fields1[i]))) { | |
| return -1; | |
| } | |
| var fc = compare(v1[fields1[i]], v2[fields1[i]]); | |
| if (fc != 0) { | |
| return fc; | |
| } | |
| } | |
| for (var i = 0; i < fields2.length; i=i+1) { | |
| if (!(Object.prototype.hasOwnProperty.call(v1,fields2[i]))) { | |
| return +1; | |
| } | |
| } | |
| return 0; | |
| } | |
| if (v1 != v2) { | |
| return v1 < v2 ? -1 : +1; | |
| } | |
| return 0; | |
| } |
> compare({'a': true}, {'b': true})
-1
> compare({'b': true}, {'a': true})
-1
Coq/ImpEJson specifies this compare only for floats and integers. The JS runtime uses the compare on other types (and combinations of two different types) to speed up set union and intersection (function min and function max in the linked JS file).
Metadata
Metadata
Assignees
Labels
No labels