@@ -54,13 +54,27 @@ impl Opts {
5454#[ derive( Copy , Clone , Ord , PartialOrd , Eq , PartialEq ) ]
5555enum Intrinsic {
5656 ClampGuest ,
57- ClampHost ,
58- ClampHost64 ,
5957 DataView ,
6058 ValidateGuestChar ,
6159 ValidateHostChar ,
6260 ValidateFlags ,
6361 ValidateFlags64 ,
62+ /// Implementation of https://tc39.es/ecma262/#sec-toint32.
63+ ToInt32 ,
64+ /// Implementation of https://tc39.es/ecma262/#sec-touint32.
65+ ToUint32 ,
66+ /// Implementation of https://tc39.es/ecma262/#sec-toint16.
67+ ToInt16 ,
68+ /// Implementation of https://tc39.es/ecma262/#sec-touint16.
69+ ToUint16 ,
70+ /// Implementation of https://tc39.es/ecma262/#sec-toint8.
71+ ToInt8 ,
72+ /// Implementation of https://tc39.es/ecma262/#sec-touint8.
73+ ToUint8 ,
74+ /// Implementation of https://tc39.es/ecma262/#sec-tobigint64.
75+ ToBigInt64 ,
76+ /// Implementation of https://tc39.es/ecma262/#sec-tobiguint64.
77+ ToBigUint64 ,
6478 /// Implementation of https://tc39.es/ecma262/#sec-tostring.
6579 ToString ,
6680 I32ToF32 ,
@@ -80,13 +94,19 @@ impl Intrinsic {
8094 fn name ( & self ) -> & ' static str {
8195 match self {
8296 Intrinsic :: ClampGuest => "clamp_guest" ,
83- Intrinsic :: ClampHost => "clamp_host" ,
84- Intrinsic :: ClampHost64 => "clamp_host64" ,
8597 Intrinsic :: DataView => "data_view" ,
8698 Intrinsic :: ValidateGuestChar => "validate_guest_char" ,
8799 Intrinsic :: ValidateHostChar => "validate_host_char" ,
88100 Intrinsic :: ValidateFlags => "validate_flags" ,
89101 Intrinsic :: ValidateFlags64 => "validate_flags64" ,
102+ Intrinsic :: ToInt32 => "to_int32" ,
103+ Intrinsic :: ToUint32 => "to_uint32" ,
104+ Intrinsic :: ToInt16 => "to_int16" ,
105+ Intrinsic :: ToUint16 => "to_uint16" ,
106+ Intrinsic :: ToInt8 => "to_int8" ,
107+ Intrinsic :: ToUint8 => "to_uint8" ,
108+ Intrinsic :: ToBigInt64 => "to_int64" ,
109+ Intrinsic :: ToBigUint64 => "to_uint64" ,
90110 Intrinsic :: ToString => "to_string" ,
91111 Intrinsic :: F32ToI32 => "f32ToI32" ,
92112 Intrinsic :: I32ToF32 => "i32ToF32" ,
@@ -1207,22 +1227,6 @@ impl FunctionBindgen<'_> {
12071227 results. push ( format ! ( "{}({}, {}, {})" , clamp, operands[ 0 ] , min, max) ) ;
12081228 }
12091229
1210- fn clamp_host < T > ( & mut self , results : & mut Vec < String > , operands : & [ String ] , min : T , max : T )
1211- where
1212- T : std:: fmt:: Display ,
1213- {
1214- let clamp = self . gen . intrinsic ( Intrinsic :: ClampHost ) ;
1215- results. push ( format ! ( "{}({}, {}, {})" , clamp, operands[ 0 ] , min, max) ) ;
1216- }
1217-
1218- fn clamp_host64 < T > ( & mut self , results : & mut Vec < String > , operands : & [ String ] , min : T , max : T )
1219- where
1220- T : std:: fmt:: Display ,
1221- {
1222- let clamp = self . gen . intrinsic ( Intrinsic :: ClampHost64 ) ;
1223- results. push ( format ! ( "{}({}, {}n, {}n)" , clamp, operands[ 0 ] , min, max) ) ;
1224- }
1225-
12261230 fn load ( & mut self , method : & str , offset : i32 , operands : & [ String ] , results : & mut Vec < String > ) {
12271231 self . needs_memory = true ;
12281232 let view = self . gen . intrinsic ( Intrinsic :: DataView ) ;
@@ -1334,16 +1338,38 @@ impl Bindgen for FunctionBindgen<'_> {
13341338
13351339 // All values coming from the host and going to wasm need to have
13361340 // their ranges validated, since the host could give us any value.
1337- Instruction :: I32FromU8 => self . clamp_host ( results, operands, u8:: MIN , u8:: MAX ) ,
1338- Instruction :: I32FromS8 => self . clamp_host ( results, operands, i8:: MIN , i8:: MAX ) ,
1339- Instruction :: I32FromU16 => self . clamp_host ( results, operands, u16:: MIN , u16:: MAX ) ,
1340- Instruction :: I32FromS16 => self . clamp_host ( results, operands, i16:: MIN , i16:: MAX ) ,
1341+ Instruction :: I32FromU8 => {
1342+ let conv = self . gen . intrinsic ( Intrinsic :: ToUint8 ) ;
1343+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1344+ }
1345+ Instruction :: I32FromS8 => {
1346+ let conv = self . gen . intrinsic ( Intrinsic :: ToInt8 ) ;
1347+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1348+ }
1349+ Instruction :: I32FromU16 => {
1350+ let conv = self . gen . intrinsic ( Intrinsic :: ToUint16 ) ;
1351+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1352+ }
1353+ Instruction :: I32FromS16 => {
1354+ let conv = self . gen . intrinsic ( Intrinsic :: ToInt16 ) ;
1355+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1356+ }
13411357 Instruction :: I32FromU32 => {
1342- self . clamp_host ( results, operands, u32:: MIN , u32:: MAX ) ;
1358+ let conv = self . gen . intrinsic ( Intrinsic :: ToUint32 ) ;
1359+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1360+ }
1361+ Instruction :: I32FromS32 => {
1362+ let conv = self . gen . intrinsic ( Intrinsic :: ToInt32 ) ;
1363+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1364+ }
1365+ Instruction :: I64FromU64 => {
1366+ let conv = self . gen . intrinsic ( Intrinsic :: ToBigUint64 ) ;
1367+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
1368+ }
1369+ Instruction :: I64FromS64 => {
1370+ let conv = self . gen . intrinsic ( Intrinsic :: ToBigInt64 ) ;
1371+ results. push ( format ! ( "{conv}({op})" , op = operands[ 0 ] ) )
13431372 }
1344- Instruction :: I32FromS32 => self . clamp_host ( results, operands, i32:: MIN , i32:: MAX ) ,
1345- Instruction :: I64FromU64 => self . clamp_host64 ( results, operands, u64:: MIN , u64:: MAX ) ,
1346- Instruction :: I64FromS64 => self . clamp_host64 ( results, operands, i64:: MIN , i64:: MAX ) ,
13471373
13481374 // The native representation in JS of f32 and f64 is just a number,
13491375 // so there's nothing to do here. Everything wasm gives us is
@@ -2388,15 +2414,6 @@ impl Js {
23882414 return i;
23892415 }
23902416 " ) ,
2391- Intrinsic :: ClampHost => self . src . js ( "
2392- export function clamp_host(i, min, max) {
2393- if (!Number.isInteger(i)) \
2394- throw new TypeError(`must be an integer`);
2395- if (i < min || i > max) \
2396- throw new RangeError(`must be between ${min} and ${max}`);
2397- return i;
2398- }
2399- " ) ,
24002417
24012418 Intrinsic :: DataView => self . src . js ( "
24022419 let DATA_VIEW = new DataView(new ArrayBuffer());
@@ -2408,16 +2425,6 @@ impl Js {
24082425 }
24092426 " ) ,
24102427
2411- Intrinsic :: ClampHost64 => self . src . js ( "
2412- export function clamp_host64(i, min, max) {
2413- if (typeof i !== 'bigint') \
2414- throw new TypeError(`must be a bigint`);
2415- if (i < min || i > max) \
2416- throw new RangeError(`must be between ${min} and ${max}`);
2417- return i;
2418- }
2419- " ) ,
2420-
24212428 Intrinsic :: ValidateGuestChar => self . src . js ( "
24222429 export function validate_guest_char(i) {
24232430 if ((i > 0x10ffff) || (i >= 0xd800 && i <= 0xdfff)) \
@@ -2457,6 +2464,64 @@ impl Js {
24572464 }
24582465 " ) ,
24592466
2467+
2468+ Intrinsic :: ToInt32 => self . src . js ( "
2469+ export function to_int32(val) {
2470+ return val >> 0;
2471+ }
2472+ " ) ,
2473+ Intrinsic :: ToUint32 => self . src . js ( "
2474+ export function to_uint32(val) {
2475+ return val >>> 0;
2476+ }
2477+ " ) ,
2478+
2479+ Intrinsic :: ToInt16 => self . src . js ( "
2480+ export function to_int16(val) {
2481+ val >>>= 0;
2482+ val %= 2 ** 16;
2483+ if (val >= 2 ** 15) {
2484+ val -= 2 ** 16;
2485+ }
2486+ return val;
2487+ }
2488+ " ) ,
2489+ Intrinsic :: ToUint16 => self . src . js ( "
2490+ export function to_uint16(val) {
2491+ val >>>= 0;
2492+ val %= 2 ** 16;
2493+ return val;
2494+ }
2495+ " ) ,
2496+ Intrinsic :: ToInt8 => self . src . js ( "
2497+ export function to_int8(val) {
2498+ val >>>= 0;
2499+ val %= 2 ** 8;
2500+ if (val >= 2 ** 7) {
2501+ val -= 2 ** 8;
2502+ }
2503+ return val;
2504+ }
2505+ " ) ,
2506+ Intrinsic :: ToUint8 => self . src . js ( "
2507+ export function to_uint8(val) {
2508+ val >>>= 0;
2509+ val %= 2 ** 8;
2510+ return val;
2511+ }
2512+ " ) ,
2513+
2514+ Intrinsic :: ToBigInt64 => self . src . js ( "
2515+ export function to_int64(val) {
2516+ return BigInt.asIntN(64, val);
2517+ }
2518+ " ) ,
2519+ Intrinsic :: ToBigUint64 => self . src . js ( "
2520+ export function to_uint64(val) {
2521+ return BigInt.asUintN(64, val);
2522+ }
2523+ " ) ,
2524+
24602525 Intrinsic :: ToString => self . src . js ( "
24612526 export function to_string(val) {
24622527 if (typeof val === 'symbol') {
0 commit comments