@@ -205,13 +205,13 @@ function makeInlineCalculation(expression, value, tempVar) {
205205
206206// Splits a number (an integer in a double, possibly > 32 bits) into an i64 
207207// value, represented by a low and high i32 pair. 
208- // Will suffer from rounding. 
208+ // Will suffer from rounding and truncation . 
209209function  splitI64 ( value )  { 
210210  // general idea: 
211211  // 
212212  //  $1$0 = ~~$d >>> 0; 
213213  //  $1$1 = Math.abs($d) >= 1 ? ( 
214-   //     $d > 0 ? Math.floor(($d)/ 4294967296.0) >>> 0,  
214+   //     $d > 0 ? Math.floor(($d)/ 4294967296.0) >>> 0 
215215  //            : Math.ceil(Math.min(-4294967296.0, $d - $1$0)/ 4294967296.0) 
216216  //  ) : 0; 
217217  // 
@@ -363,12 +363,23 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, sep) {
363363  assert ( typeof  align  ===  'undefined' ,  'makeSetValue no longer supports align parameter' ) ; 
364364  assert ( typeof  noNeedFirst  ===  'undefined' ,  'makeSetValue no longer supports noNeedFirst parameter' ) ; 
365365  assert ( typeof  sep  ===  'undefined' ,  'makeSetValue no longer supports sep parameter' ) ; 
366+ 
367+   var  rtn  =  makeSetValueImpl ( ptr ,  pos ,  value ,  type ) ; 
368+   if  ( ASSERTIONS  ==  2  &&  ( type . startsWith ( 'i' )  ||  type . startsWith ( 'u' ) ) )  { 
369+     const  width  =  getBitWidth ( type ) ; 
370+     const  assertion  =  `check${ width }  (${ value }  )` ; 
371+     rtn  +=  ';'  +  assertion 
372+   } 
373+   return  rtn ; 
374+ } 
375+ 
376+ function  makeSetValueImpl ( ptr ,  pos ,  value ,  type )  { 
366377  if  ( type  ==  'i64'  &&  ! WASM_BIGINT )  { 
367378    // If we lack either BigInt we must fall back to an reading a pair of I32 
368379    // values. 
369380    return  '(tempI64 = ['  +  splitI64 ( value )  +  '], '  + 
370-             makeSetValue ( ptr ,  pos ,  'tempI64[0]' ,  'i32' )  +  ','  + 
371-             makeSetValue ( ptr ,  getFastValue ( pos ,  '+' ,  getNativeTypeSize ( 'i32' ) ) ,  'tempI64[1]' ,  'i32' )  +  ')' ; 
381+             makeSetValueImpl ( ptr ,  pos ,  'tempI64[0]' ,  'i32' )  +  ','  + 
382+             makeSetValueImpl ( ptr ,  getFastValue ( pos ,  '+' ,  getNativeTypeSize ( 'i32' ) ) ,  'tempI64[1]' ,  'i32' )  +  ')' ; 
372383  } 
373384
374385  const  offset  =  calcFastOffset ( ptr ,  pos ) ; 
@@ -381,7 +392,8 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, sep) {
381392  if  ( slab  ==  'HEAPU64'  ||  slab  ==  'HEAP64' )  { 
382393    value  =  `BigInt(${ value }  )` ; 
383394  } 
384-   return  slab  +  '['  +  getHeapOffset ( offset ,  type )  +  '] = '  +  value ; 
395+   var  rtn  =  slab  +  '['  +  getHeapOffset ( offset ,  type )  +  '] = '  +  value ; 
396+   return  rtn ; 
385397} 
386398
387399function  makeHEAPView ( which ,  start ,  end )  { 
@@ -448,6 +460,25 @@ function calcFastOffset(ptr, pos) {
448460  return  getFastValue ( ptr ,  '+' ,  pos ) ; 
449461} 
450462
463+ function  getBitWidth ( type )  { 
464+   if  ( isPointerType ( type ) )  { 
465+     type  =  POINTER_TYPE ; 
466+   } 
467+   switch  ( type )  { 
468+     case  'i1' :     return  1 ; 
469+     case  'i8' :     // fallthrough 
470+     case  'u8' :     return  8 ; 
471+     case  'i16' :    // fallthrough 
472+     case  'u16' :    return  16 ; 
473+     case  'i32' :    // fallthrough 
474+     case  'u32' :    return  32 
475+     case  'i53' :    // fallthrough 
476+     case  'u53' :    return  53 
477+     case  'i64' :    // fallthrough 
478+     case  'u64' :    return  64 ; 
479+   } 
480+ } 
481+ 
451482function  getHeapForType ( type )  { 
452483  assert ( type ) ; 
453484  if  ( isPointerType ( type ) )  { 
0 commit comments