diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2023-04-27 16:58:21 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-05-04 14:58:51 -0400 |
commit | 2d5c1ddecf195da9a8ee4f7b38fbb79d3b680aeb (patch) | |
tree | 6e9ac73ed4cc48a196f2eefb313ab7fcafd0e28b /rts/js | |
parent | 116d7312ec4c76f75a26bd0ad2b2815710049e0e (diff) | |
download | haskell-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.js | 23 | ||||
-rw-r--r-- | rts/js/mem.js | 31 | ||||
-rw-r--r-- | rts/js/profiling.js | 7 | ||||
-rw-r--r-- | rts/js/staticpointer.js | 7 | ||||
-rw-r--r-- | rts/js/string.js | 41 |
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) { |