summaryrefslogtreecommitdiff
path: root/rts/js
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2023-04-27 16:58:21 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-05-04 14:58:51 -0400
commit2d5c1ddecf195da9a8ee4f7b38fbb79d3b680aeb (patch)
tree6e9ac73ed4cc48a196f2eefb313ab7fcafd0e28b /rts/js
parent116d7312ec4c76f75a26bd0ad2b2815710049e0e (diff)
downloadhaskell-2d5c1ddecf195da9a8ee4f7b38fbb79d3b680aeb.tar.gz
Fix remaining issues with bound checking (#23123)
While fixing these I've also changed the way we store addresses into ByteArray#. Addr# are composed of two parts: a JavaScript array and an offset (32-bit number). Suppose we want to store an Addr# in a ByteArray# foo at offset i. Before this patch, we were storing both fields as a tuple in the "arr" array field: foo.arr[i] = [addr_arr, addr_offset]; Now we only store the array part in the "arr" field and the offset directly in the array: foo.dv.setInt32(i, addr_offset): foo.arr[i] = addr_arr; It avoids wasting space for the tuple.
Diffstat (limited to 'rts/js')
-rw-r--r--rts/js/environment.js23
-rw-r--r--rts/js/mem.js31
-rw-r--r--rts/js/profiling.js7
-rw-r--r--rts/js/staticpointer.js7
-rw-r--r--rts/js/string.js41
5 files changed, 40 insertions, 69 deletions
diff --git a/rts/js/environment.js b/rts/js/environment.js
index 193d6a6029..1cd4e6cfbb 100644
--- a/rts/js/environment.js
+++ b/rts/js/environment.js
@@ -158,20 +158,19 @@ function h$getProgArgv(argc_v,argc_off,argv_v,argv_off) {
} else {
argc_v.dv.setInt32(argc_off, c, true);
var argv = h$newByteArray(4*c);
- argv.arr = [];
for(var i=0;i<h$programArgs().length;i++) {
- argv.arr[4*i] = [ h$encodeUtf8(h$programArgs()[i]), 0 ];
+ PUT_ADDR(argv,4*i,h$encodeUtf8(h$programArgs()[i]),0);
}
- if(!argv_v.arr) { argv_v.arr = []; }
- argv_v.arr[argv_off] = [argv, 0];
+ PUT_ADDR(argv_v,argv_off,argv,0);
}
}
function h$setProgArgv(n, ptr_d, ptr_o) {
args = [];
for(var i=0;i<n;i++) {
- var p = ptr_d.arr[ptr_o+4*i];
- var arg = h$decodeUtf8z(p[0], p[1]);
+ var off = ptr_o+4*i;
+ GET_ADDR(ptr_d,off,p,o);
+ var arg = h$decodeUtf8z(p, o);
args.push(arg);
}
h$programArgs_ = args;
@@ -218,9 +217,10 @@ function h$__hscore_environ() {
}
if(env.length === 0) return null;
var p = h$newByteArray(4*env.length+1);
- p.arr = [];
- for(i=0;i<env.length;i++) p.arr[4*i] = [h$encodeUtf8(env[i]), 0];
- p.arr[4*env.length] = [null, 0];
+ for(i=0;i<env.length;i++) {
+ PUT_ADDR(p,4*i,h$encodeUtf8(env[i]),0);
+ }
+ PUT_ADDR(p,4*env.length,null,0);
RETURN_UBX_TUP2(p, 0);
}
#endif
@@ -435,9 +435,8 @@ function h$localtime_r(timep_v, timep_o, result_v, result_o) {
result_v.dv.setInt32(result_o + 28, 0, true); // fixme yday 1-365 (366?)
result_v.dv.setInt32(result_o + 32, -1, true); // dst information unknown
result_v.dv.setInt32(result_o + 40, 0, true); // gmtoff?
- if(!result_v.arr) result_v.arr = [];
- result_v.arr[result_o + 40] = [h$myTimeZone, 0];
- result_v.arr[result_o + 48] = [h$myTimeZone, 0];
+ PUT_ADDR(result_v,result_o+40, h$myTimeZone, 0);
+ PUT_ADDR(result_v,result_o+48, h$myTimeZone, 0);
RETURN_UBX_TUP2(result_v, result_o);
}
var h$__hscore_localtime_r = h$localtime_r;
diff --git a/rts/js/mem.js b/rts/js/mem.js
index 73e6f9aecd..43c0ea6122 100644
--- a/rts/js/mem.js
+++ b/rts/js/mem.js
@@ -563,6 +563,20 @@ function h$copyMutableByteArray(a1,o1,a2,o2,n) {
a2.u8[o2+i] = a1.u8[o1+i];
}
}
+
+ // also update sub-array for Addr# support
+ if (!a1.arr) return;
+ if (!a2.arr) { a2.arr = [] };
+
+ if (o1 < o2) {
+ for (var i=n-1;i>=0;i--) {
+ a2.arr[o2+i] = a1.arr[o1+i] || null;
+ }
+ } else {
+ for (var i=0;i<n;i++) {
+ a2.arr[o2+i] = a1.arr[o1+i] || null;
+ }
+ }
}
//////////////////////////////////////////////////////////
@@ -961,7 +975,7 @@ function h$strlen(a_v, a_o) {
}
function h$newArray(len, e) {
- var r = [];
+ var r = new Array(len);
r.__ghcjsArray = true;
r.m = 0;
if(e === null) e = r;
@@ -986,6 +1000,7 @@ function h$newByteArray(len) {
, f3: new Float32Array(buf)
, f6: new Float64Array(buf)
, dv: new DataView(buf)
+ , arr: [] // for Addr# array part
, m: 0
}
}
@@ -1457,13 +1472,11 @@ function h$pext64(src_b, src_a, mask_b, mask_a) {
}
function h$checkOverlapByteArray(a1, o1, a2, o2, n) {
- if (n == 0) return true;
- if (a1 == a2) {
- if (o1 < o2) {
- return o1 + n - 1 < o2;
- } else {
- return o2 + n - 1 < o1;
- }
- }
+ if (n == 0) return true;
+ if (a1 !== a2) return true;
+ if (o1 === o2) return true;
+
+ if (o1 < o2) return o2 - o1 >= n;
+ if (o1 > o2) return o1 - o2 >= n;
return true;
}
diff --git a/rts/js/profiling.js b/rts/js/profiling.js
index f972642658..e6433e36d6 100644
--- a/rts/js/profiling.js
+++ b/rts/js/profiling.js
@@ -302,10 +302,9 @@ function h$buildCCPtr(o) {
#ifdef GHCJS_TRACE_PROF
cc.myTag = "cc pointer";
#endif
- cc.arr = [];
- cc.arr[h$ccLabel_offset] = [h$encodeUtf8(o.label), 0];
- cc.arr[h$ccModule_offset] = [h$encodeUtf8(o.module), 0];
- cc.arr[h$ccsrcloc_offset] = [h$encodeUtf8(o.srcloc), 0];
+ PUT_ADDR(cc, h$ccLabel_offset, h$encodeUtf8(o.label), 0);
+ PUT_ADDR(cc, h$ccModule_offset, h$encodeUtf8(o.module), 0);
+ PUT_ADDR(cc, h$ccsrcloc_offset, h$encodeUtf8(o.srcloc), 0);
return cc;
}
diff --git a/rts/js/staticpointer.js b/rts/js/staticpointer.js
index 9733490df5..80eda18dff 100644
--- a/rts/js/staticpointer.js
+++ b/rts/js/staticpointer.js
@@ -16,7 +16,7 @@ function h$hs_spt_insert(key1,key2,key3,key4,ref) {
ba.i3[1] = key1;
ba.i3[2] = key4;
ba.i3[3] = key3;
- h$static_pointer_table_keys.push([ba,0]);
+ h$static_pointer_table_keys.push(ba);
h$retain({ root: ref, _key: -1 });
}
var s = h$static_pointer_table;
@@ -33,8 +33,9 @@ function h$hs_spt_key_count() {
function h$hs_spt_keys(tgt_d, tgt_o, n) {
var ks = h$static_pointer_table_keys;
- if(!tgt_d.arr) tgt_d.arr = [];
- for(var i=0;(i<n&&i<ks.length);i++) tgt_d.arr[tgt_o+4*i] = ks[i];
+ for(var i=0;(i<n&&i<ks.length);i++) {
+ PUT_ADDR(tgt_d, tgt_o+4*i, ks[i], 0);
+ }
return Math.min(n,ks.length);
}
diff --git a/rts/js/string.js b/rts/js/string.js
index da5e0c610e..fd76e4405d 100644
--- a/rts/js/string.js
+++ b/rts/js/string.js
@@ -602,47 +602,6 @@ function h$hs_iconv_close(iconv) {
return 0;
}
-// ptr* -> ptr (array)
-function h$derefPtrA(ptr, ptr_off) {
- return ptr.arr[ptr_off][0];
-}
-// ptr* -> ptr (offset)
-function h$derefPtrO(ptr, ptr_off) {
- return ptr.arr[ptr_off][1];
-}
-
-// word** -> word ptr[x][y]
-function h$readPtrPtrU32(ptr, ptr_off, x, y) {
- x = x || 0;
- y = y || 0;
- var arr = ptr.arr[ptr_off + 4 * x];
- return arr[0].dv.getInt32(arr[1] + 4 * y, true);
-}
-
-// char** -> char ptr[x][y]
-function h$readPtrPtrU8(ptr, ptr_off, x, y) {
- x = x || 0;
- y = y || 0;
- var arr = ptr.arr[ptr_off + 4 * x];
- return arr[0].dv.getUint8(arr[1] + y);
-}
-
-// word** ptr[x][y] = v
-function h$writePtrPtrU32(ptr, ptr_off, v, x, y) {
- x = x || 0;
- y = y || 0;
- var arr = ptr.arr[ptr_off + 4 * x];
- arr[0].dv.putInt32(arr[1] + y, v);
-}
-
-// unsigned char** ptr[x][y] = v
-function h$writePtrPtrU8(ptr, ptr_off, v, x, y) {
- x = x || 0;
- y = y || 0;
- var arr = ptr.arr[ptr_off+ 4 * x];
- arr[0].dv.putUint8(arr[1] + y, v);
-}
-
// convert JavaScript String to a Haskell String
#ifdef GHCJS_PROF
function h$toHsString(str, cc) {