Skip to content

Commit 85b1ef4

Browse files
committed
Runtime: split hash
1 parent 1da1ad3 commit 85b1ef4

File tree

2 files changed

+176
-119
lines changed

2 files changed

+176
-119
lines changed

runtime/core_kernel.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,21 @@ function core_kernel_gc_top_heap_words () { return 0 }
100100
//Provides: clear_caml_backtrace_pos
101101
function clear_caml_backtrace_pos () { return 0 }
102102

103+
//Provides: internalhash_fold_int64
104+
//Requires: caml_hash_mix_int64
105+
var internalhash_fold_int64 = caml_hash_mix_int64
106+
//Provides: internalhash_fold_int
107+
//Requires: caml_hash_mix_int
108+
var internalhash_fold_int = caml_hash_mix_int
109+
//Provides: internalhash_fold_float
110+
//Requires: caml_hash_mix_float
111+
var internalhash_fold_float = caml_hash_mix_float
112+
//Provides: internalhash_fold_string
113+
//Requires: caml_hash_mix_string
114+
var internalhash_fold_string = caml_hash_mix_string
115+
//Provides: internalhash_get_hash_value
116+
//Requires: caml_hash_mix_final
117+
function internalhash_get_hash_value (seed) {
118+
var h = caml_hash_mix_final(seed);
119+
return h & 0x3FFFFFFF;
120+
}

runtime/stdlib.js

Lines changed: 158 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,19 @@ function caml_wrap_exception(e) {
166166
return [0,caml_global_data.Failure,caml_js_to_string (String(e))];
167167
}
168168

169+
// Experimental
170+
//Provides: caml_exn_with_js_backtrace
171+
//Requires: caml_global_data
172+
function caml_exn_with_js_backtrace(exn, force) {
173+
if(!exn.js_error || force) exn.js_error = new joo_global_object.Error("Js exception containing backtrace");
174+
return exn;
175+
}
176+
//Provides: caml_js_error_of_exception
177+
function caml_js_error_of_exception(exn) {
178+
if(exn.js_error) { return exn.js_error; }
179+
return null;
180+
}
181+
169182
//Provides: caml_invalid_argument (const)
170183
//Requires: caml_raise_with_string, caml_global_data
171184
function caml_invalid_argument (msg) {
@@ -702,141 +715,167 @@ function caml_hash_univ_param (count, limit, obj) {
702715
return hash_accu & 0x3FFFFFFF;
703716
}
704717

705-
//Provides: caml_hash mutable
706-
//Requires: MlString, caml_convert_string_to_bytes
707-
//Requires: caml_int64_bits_of_float, caml_mul
708-
var caml_hash =
709-
function () {
710-
var HASH_QUEUE_SIZE = 256;
711-
function ROTL32(x,n) { return ((x << n) | (x >>> (32-n))); }
712-
function MIX(h,d) {
713-
d = caml_mul(d, 0xcc9e2d51|0);
714-
d = ROTL32(d, 15);
715-
d = caml_mul(d, 0x1b873593);
716-
h ^= d;
717-
h = ROTL32(h, 13);
718-
return (((h + (h << 2))|0) + (0xe6546b64|0))|0;
719-
}
720-
function FINAL_MIX(h) {
721-
h ^= h >>> 16;
722-
h = caml_mul (h, 0x85ebca6b|0);
723-
h ^= h >>> 13;
724-
h = caml_mul (h, 0xc2b2ae35|0);
725-
h ^= h >>> 16;
726-
return h;
718+
//function ROTL32(x,n) { return ((x << n) | (x >>> (32-n))); }
719+
//Provides: caml_hash_mix_int
720+
//Requires: caml_mul
721+
function caml_hash_mix_int(h,d) {
722+
d = caml_mul(d, 0xcc9e2d51|0);
723+
d = ((d << 15) | (d >>> (32-15))); // ROTL32(d, 15);
724+
d = caml_mul(d, 0x1b873593);
725+
h ^= d;
726+
h = ((h << 13) | (h >>> (32-13))); //ROTL32(h, 13);
727+
return (((h + (h << 2))|0) + (0xe6546b64|0))|0;
728+
}
729+
730+
//Provides: caml_hash_mix_final
731+
//Requires: caml_mul
732+
function caml_hash_mix_final(h) {
733+
h ^= h >>> 16;
734+
h = caml_mul (h, 0x85ebca6b|0);
735+
h ^= h >>> 13;
736+
h = caml_mul (h, 0xc2b2ae35|0);
737+
h ^= h >>> 16;
738+
return h;
739+
}
740+
741+
//Provides: caml_hash_mix_float
742+
//Requires: caml_hash_mix_int, caml_int64_bits_of_float
743+
function caml_hash_mix_float (h, v0) {
744+
var v = caml_int64_bits_of_float (v0);
745+
var lo = v[1] | (v[2] << 24);
746+
var hi = (v[2] >>> 8) | (v[3] << 16);
747+
h = caml_hash_mix_int(h, lo);
748+
h = caml_hash_mix_int(h, hi);
749+
return h;
750+
}
751+
//Provides: caml_hash_mix_int64
752+
//Requires: caml_hash_mix_int
753+
function caml_hash_mix_int64 (h, v) {
754+
var lo = v[1] | (v[2] << 24);
755+
var hi = (v[2] >>> 8) | (v[3] << 16);
756+
h = caml_hash_mix_int(h, hi ^ lo);
757+
return h;
758+
}
759+
760+
//Provides: caml_hash_mix_string_str
761+
//Requires: caml_hash_mix_int
762+
function caml_hash_mix_string_str(h, s) {
763+
var len = s.length, i, w;
764+
for (i = 0; i + 4 <= len; i += 4) {
765+
w = s.charCodeAt(i)
766+
| (s.charCodeAt(i+1) << 8)
767+
| (s.charCodeAt(i+2) << 16)
768+
| (s.charCodeAt(i+3) << 24);
769+
h = caml_hash_mix_int(h, w);
727770
}
728-
function caml_hash_mix_int64 (h, v) {
729-
var lo = v[1] | (v[2] << 24);
730-
var hi = (v[2] >>> 8) | (v[3] << 16);
731-
h = MIX(h, lo);
732-
h = MIX(h, hi);
733-
return h;
771+
w = 0;
772+
switch (len & 3) {
773+
case 3: w = s.charCodeAt(i+2) << 16;
774+
case 2: w |= s.charCodeAt(i+1) << 8;
775+
case 1: w |= s.charCodeAt(i);
776+
h = caml_hash_mix_int(h, w);
777+
default:
734778
}
735-
function caml_hash_mix_int64_2 (h, v) {
736-
var lo = v[1] | (v[2] << 24);
737-
var hi = (v[2] >>> 8) | (v[3] << 16);
738-
h = MIX(h, hi ^ lo);
739-
return h;
779+
h ^= len;
780+
return h;
781+
}
782+
783+
//Provides: caml_hash_mix_string_arr
784+
//Requires: caml_hash_mix_int
785+
function caml_hash_mix_string_arr(h, s) {
786+
var len = s.length, i, w;
787+
for (i = 0; i + 4 <= len; i += 4) {
788+
w = s[i]
789+
| (s[i+1] << 8)
790+
| (s[i+2] << 16)
791+
| (s[i+3] << 24);
792+
h = caml_hash_mix_int(h, w);
740793
}
741-
function caml_hash_mix_string_str(h, s) {
742-
var len = s.length, i, w;
743-
for (i = 0; i + 4 <= len; i += 4) {
744-
w = s.charCodeAt(i)
745-
| (s.charCodeAt(i+1) << 8)
746-
| (s.charCodeAt(i+2) << 16)
747-
| (s.charCodeAt(i+3) << 24);
748-
h = MIX(h, w);
749-
}
750-
w = 0;
751-
switch (len & 3) {
752-
case 3: w = s.charCodeAt(i+2) << 16;
753-
case 2: w |= s.charCodeAt(i+1) << 8;
754-
case 1: w |= s.charCodeAt(i);
755-
h = MIX(h, w);
756-
default:
757-
}
758-
h ^= len;
759-
return h;
794+
w = 0;
795+
switch (len & 3) {
796+
case 3: w = s[i+2] << 16;
797+
case 2: w |= s[i+1] << 8;
798+
case 1: w |= s[i];
799+
h = caml_hash_mix_int(h, w);
800+
default:
760801
}
761-
function caml_hash_mix_string_arr(h, s) {
762-
var len = s.length, i, w;
763-
for (i = 0; i + 4 <= len; i += 4) {
764-
w = s[i]
765-
| (s[i+1] << 8)
766-
| (s[i+2] << 16)
767-
| (s[i+3] << 24);
768-
h = MIX(h, w);
769-
}
770-
w = 0;
771-
switch (len & 3) {
772-
case 3: w = s[i+2] << 16;
773-
case 2: w |= s[i+1] << 8;
774-
case 1: w |= s[i];
775-
h = MIX(h, w);
802+
h ^= len;
803+
return h;
804+
}
805+
806+
//Provides: caml_hash_mix_string
807+
//Requires: caml_convert_string_to_bytes
808+
//Requires: caml_hash_mix_string_str
809+
//Requires: caml_hash_mix_string_arr
810+
function caml_hash_mix_string(h, v) {
811+
switch (v.t & 6) {
776812
default:
813+
caml_convert_string_to_bytes (v);
814+
case 0: /* BYTES */
815+
h = caml_hash_mix_string_str(h, v.c);
816+
break;
817+
case 2: /* ARRAY */
818+
h = caml_hash_mix_string_arr(h, v.c);
777819
}
778-
h ^= len;
779-
return h;
780-
}
781-
return function (count, limit, seed, obj) {
820+
return h
821+
}
822+
823+
824+
//Provides: caml_hash mutable
825+
//Requires: MlString
826+
//Requires: caml_int64_bits_of_float, caml_hash_mix_int, caml_hash_mix_final
827+
//Requires: caml_hash_mix_int64, caml_hash_mix_float, caml_hash_mix_string
828+
var HASH_QUEUE_SIZE = 256;
829+
function caml_hash (count, limit, seed, obj) {
782830
var queue, rd, wr, sz, num, h, v, i, len;
783831
sz = limit;
784832
if (sz < 0 || sz > HASH_QUEUE_SIZE) sz = HASH_QUEUE_SIZE;
785833
num = count;
786834
h = seed;
787835
queue = [obj]; rd = 0; wr = 1;
788836
while (rd < wr && num > 0) {
789-
v = queue[rd++];
790-
if (v instanceof Array && v[0] === (v[0]|0)) {
791-
switch (v[0]) {
792-
case 248:
793-
// Object
794-
h = MIX(h, v[2]);
795-
num--;
796-
break;
797-
case 250:
798-
// Forward
799-
queue[--rd] = v[1];
800-
break;
801-
case 255:
802-
// Int64
803-
h = caml_hash_mix_int64_2 (h, v);
804-
num --;
805-
break;
806-
default:
807-
var tag = ((v.length - 1) << 10) | v[0];
808-
h = MIX(h, tag);
809-
for (i = 1, len = v.length; i < len; i++) {
810-
if (wr >= sz) break;
811-
queue[wr++] = v[i];
812-
}
813-
break;
814-
}
815-
} else if (v instanceof MlString) {
816-
switch (v.t & 6) {
817-
default:
818-
caml_convert_string_to_bytes (v);
819-
case 0: /* BYTES */
820-
h = caml_hash_mix_string_str(h, v.c);
821-
break;
822-
case 2: /* ARRAY */
823-
h = caml_hash_mix_string_arr(h, v.c);
837+
v = queue[rd++];
838+
if (v instanceof Array && v[0] === (v[0]|0)) {
839+
switch (v[0]) {
840+
case 248:
841+
// Object
842+
h = caml_hash_mix_int(h, v[2]);
843+
num--;
844+
break;
845+
case 250:
846+
// Forward
847+
queue[--rd] = v[1];
848+
break;
849+
case 255:
850+
// Int64
851+
h = caml_hash_mix_int64 (h, v);
852+
num --;
853+
break;
854+
default:
855+
var tag = ((v.length - 1) << 10) | v[0];
856+
h = caml_hash_mix_int(h, tag);
857+
for (i = 1, len = v.length; i < len; i++) {
858+
if (wr >= sz) break;
859+
queue[wr++] = v[i];
860+
}
861+
break;
862+
}
863+
} else if (v instanceof MlString) {
864+
h = caml_hash_mix_string(h,v)
865+
num--;
866+
} else if (v === (v|0)) {
867+
// Integer
868+
h = caml_hash_mix_int(h, v+v+1);
869+
num--;
870+
} else if (v === +v) {
871+
// Float
872+
h = caml_hash_mix_float(h,v);
873+
num--;
824874
}
825-
num--;
826-
} else if (v === (v|0)) {
827-
// Integer
828-
h = MIX(h, v+v+1);
829-
num--;
830-
} else if (v === +v) {
831-
// Float
832-
h = caml_hash_mix_int64(h, caml_int64_bits_of_float (v));
833-
num--;
834-
}
835875
}
836-
h = FINAL_MIX(h);
876+
h = caml_hash_mix_final(h);
837877
return h & 0x3FFFFFFF;
838-
}
839-
} ();
878+
}
840879

841880
///////////// Sys
842881
//Provides: caml_sys_time mutable

0 commit comments

Comments
 (0)