@@ -233,51 +233,60 @@ fn binary_operation_evaluate_value_to<'a>(
233233 }
234234 None
235235 }
236- BinaryOperator :: Subtraction
237- | BinaryOperator :: Division
238- | BinaryOperator :: Remainder
239- | BinaryOperator :: Multiplication
240- | BinaryOperator :: Exponential => {
236+ BinaryOperator :: Subtraction => {
241237 let lval = left. evaluate_value_to_number ( ctx) ?;
242238 let rval = right. evaluate_value_to_number ( ctx) ?;
243- let val = match operator {
244- BinaryOperator :: Subtraction => lval - rval,
245- BinaryOperator :: Division => lval / rval,
246- BinaryOperator :: Remainder => {
247- if rval. is_zero ( ) {
248- f64:: NAN
249- } else {
250- lval % rval
251- }
252- }
253- BinaryOperator :: Multiplication => lval * rval,
254- BinaryOperator :: Exponential => {
255- let result = lval. powf ( rval) ;
256- // For now, ignore the result if it large or has a decimal part
257- // so that the output does not become bigger than the input.
258- if result. is_finite ( ) && ( result. fract ( ) != 0.0 || result. log10 ( ) > 4.0 ) {
259- return None ;
260- }
261- result
262- }
263- _ => unreachable ! ( ) ,
264- } ;
265- Some ( ConstantValue :: Number ( val) )
239+ Some ( ConstantValue :: Number ( lval - rval) )
240+ }
241+ BinaryOperator :: Division => {
242+ let lval = left. evaluate_value_to_number ( ctx) ?;
243+ let rval = right. evaluate_value_to_number ( ctx) ?;
244+ Some ( ConstantValue :: Number ( lval / rval) )
245+ }
246+ BinaryOperator :: Remainder => {
247+ let lval = left. evaluate_value_to_number ( ctx) ?;
248+ let rval = right. evaluate_value_to_number ( ctx) ?;
249+ Some ( ConstantValue :: Number ( if rval. is_zero ( ) { f64:: NAN } else { lval % rval } ) )
250+ }
251+ BinaryOperator :: Multiplication => {
252+ let lval = left. evaluate_value_to_number ( ctx) ?;
253+ let rval = right. evaluate_value_to_number ( ctx) ?;
254+ Some ( ConstantValue :: Number ( lval * rval) )
255+ }
256+ BinaryOperator :: Exponential => {
257+ let lval = left. evaluate_value_to_number ( ctx) ?;
258+ let rval = right. evaluate_value_to_number ( ctx) ?;
259+ let result = lval. powf ( rval) ;
260+ // For now, ignore the result if it large or has a decimal part
261+ // so that the output does not become bigger than the input.
262+ if result. is_finite ( ) && ( result. fract ( ) != 0.0 || result. log10 ( ) > 4.0 ) {
263+ return None ;
264+ }
265+ Some ( ConstantValue :: Number ( result) )
266266 }
267267 #[ expect( clippy:: cast_sign_loss) ]
268- BinaryOperator :: ShiftLeft
269- | BinaryOperator :: ShiftRight
270- | BinaryOperator :: ShiftRightZeroFill => {
268+ BinaryOperator :: ShiftLeft => {
271269 let left = left. evaluate_value_to_number ( ctx) ?;
272270 let right = right. evaluate_value_to_number ( ctx) ?;
273271 let left = left. to_int_32 ( ) ;
274272 let right = ( right. to_int_32 ( ) as u32 ) & 31 ;
275- Some ( ConstantValue :: Number ( match operator {
276- BinaryOperator :: ShiftLeft => f64:: from ( left << right) ,
277- BinaryOperator :: ShiftRight => f64:: from ( left >> right) ,
278- BinaryOperator :: ShiftRightZeroFill => f64:: from ( ( left as u32 ) >> right) ,
279- _ => unreachable ! ( ) ,
280- } ) )
273+ Some ( ConstantValue :: Number ( f64:: from ( left << right) ) )
274+ }
275+ #[ expect( clippy:: cast_sign_loss) ]
276+ BinaryOperator :: ShiftRight => {
277+ let left = left. evaluate_value_to_number ( ctx) ?;
278+ let right = right. evaluate_value_to_number ( ctx) ?;
279+ let left = left. to_int_32 ( ) ;
280+ let right = ( right. to_int_32 ( ) as u32 ) & 31 ;
281+ Some ( ConstantValue :: Number ( f64:: from ( left >> right) ) )
282+ }
283+ #[ expect( clippy:: cast_sign_loss) ]
284+ BinaryOperator :: ShiftRightZeroFill => {
285+ let left = left. evaluate_value_to_number ( ctx) ?;
286+ let right = right. evaluate_value_to_number ( ctx) ?;
287+ let left = left. to_int_32 ( ) ;
288+ let right = ( right. to_int_32 ( ) as u32 ) & 31 ;
289+ Some ( ConstantValue :: Number ( f64:: from ( ( left as u32 ) >> right) ) )
281290 }
282291 BinaryOperator :: LessThan => is_less_than ( ctx, left, right) . map ( |value| match value {
283292 ConstantValue :: Undefined => ConstantValue :: Boolean ( false ) ,
@@ -303,33 +312,35 @@ fn binary_operation_evaluate_value_to<'a>(
303312 _ => unreachable ! ( ) ,
304313 } )
305314 }
306- BinaryOperator :: BitwiseAnd | BinaryOperator :: BitwiseOR | BinaryOperator :: BitwiseXOR => {
315+ BinaryOperator :: BitwiseAnd => {
307316 if left. value_type ( ctx) . is_bigint ( ) && right. value_type ( ctx) . is_bigint ( ) {
308- let left_val = left. evaluate_value_to_bigint ( ctx) ?;
309- let right_val = right. evaluate_value_to_bigint ( ctx) ?;
310- let result_val: BigInt = match operator {
311- BinaryOperator :: BitwiseAnd => left_val & right_val,
312- BinaryOperator :: BitwiseOR => left_val | right_val,
313- BinaryOperator :: BitwiseXOR => left_val ^ right_val,
314- _ => unreachable ! ( ) ,
315- } ;
316- return Some ( ConstantValue :: BigInt ( result_val) ) ;
317+ let left_biginit = left. evaluate_value_to_bigint ( ctx) ?;
318+ let right_bigint = right. evaluate_value_to_bigint ( ctx) ?;
319+ return Some ( ConstantValue :: BigInt ( left_biginit & right_bigint) ) ;
317320 }
318- let left_num = left. evaluate_value_to_number ( ctx) ;
319- let right_num = right. evaluate_value_to_number ( ctx) ;
320- if let ( Some ( left_val) , Some ( right_val) ) = ( left_num, right_num) {
321- let left_val_int = left_val. to_int_32 ( ) ;
322- let right_val_int = right_val. to_int_32 ( ) ;
323-
324- let result_val: f64 = match operator {
325- BinaryOperator :: BitwiseAnd => f64:: from ( left_val_int & right_val_int) ,
326- BinaryOperator :: BitwiseOR => f64:: from ( left_val_int | right_val_int) ,
327- BinaryOperator :: BitwiseXOR => f64:: from ( left_val_int ^ right_val_int) ,
328- _ => unreachable ! ( ) ,
329- } ;
330- return Some ( ConstantValue :: Number ( result_val) ) ;
321+ let left_int = left. evaluate_value_to_number ( ctx) ?. to_int_32 ( ) ;
322+ let right_int = right. evaluate_value_to_number ( ctx) ?. to_int_32 ( ) ;
323+ Some ( ConstantValue :: Number ( f64:: from ( left_int & right_int) ) )
324+ }
325+ BinaryOperator :: BitwiseOR => {
326+ if left. value_type ( ctx) . is_bigint ( ) && right. value_type ( ctx) . is_bigint ( ) {
327+ let left_biginit = left. evaluate_value_to_bigint ( ctx) ?;
328+ let right_bigint = right. evaluate_value_to_bigint ( ctx) ?;
329+ return Some ( ConstantValue :: BigInt ( left_biginit | right_bigint) ) ;
331330 }
332- None
331+ let left_int = left. evaluate_value_to_number ( ctx) ?. to_int_32 ( ) ;
332+ let right_int = right. evaluate_value_to_number ( ctx) ?. to_int_32 ( ) ;
333+ Some ( ConstantValue :: Number ( f64:: from ( left_int | right_int) ) )
334+ }
335+ BinaryOperator :: BitwiseXOR => {
336+ if left. value_type ( ctx) . is_bigint ( ) && right. value_type ( ctx) . is_bigint ( ) {
337+ let left_biginit = left. evaluate_value_to_bigint ( ctx) ?;
338+ let right_bigint = right. evaluate_value_to_bigint ( ctx) ?;
339+ return Some ( ConstantValue :: BigInt ( left_biginit ^ right_bigint) ) ;
340+ }
341+ let left_int = left. evaluate_value_to_number ( ctx) ?. to_int_32 ( ) ;
342+ let right_int = right. evaluate_value_to_number ( ctx) ?. to_int_32 ( ) ;
343+ Some ( ConstantValue :: Number ( f64:: from ( left_int ^ right_int) ) )
333344 }
334345 BinaryOperator :: Instanceof => {
335346 if let Expression :: Identifier ( right_ident) = right {
@@ -348,24 +359,21 @@ fn binary_operation_evaluate_value_to<'a>(
348359 }
349360 None
350361 }
351- BinaryOperator :: StrictEquality
352- | BinaryOperator :: StrictInequality
353- | BinaryOperator :: Equality
354- | BinaryOperator :: Inequality => {
355- let value = match operator {
356- BinaryOperator :: StrictEquality | BinaryOperator :: StrictInequality => {
357- strict_equality_comparison ( ctx, left, right) ?
358- }
359- BinaryOperator :: Equality | BinaryOperator :: Inequality => {
360- abstract_equality_comparison ( ctx, left, right) ?
361- }
362- _ => unreachable ! ( ) ,
363- } ;
364- Some ( ConstantValue :: Boolean ( match operator {
365- BinaryOperator :: StrictEquality | BinaryOperator :: Equality => value,
366- BinaryOperator :: StrictInequality | BinaryOperator :: Inequality => !value,
367- _ => unreachable ! ( ) ,
368- } ) )
362+ BinaryOperator :: StrictEquality => {
363+ let value = strict_equality_comparison ( ctx, left, right) ?;
364+ Some ( ConstantValue :: Boolean ( value) )
365+ }
366+ BinaryOperator :: StrictInequality => {
367+ let value = strict_equality_comparison ( ctx, left, right) ?;
368+ Some ( ConstantValue :: Boolean ( !value) )
369+ }
370+ BinaryOperator :: Equality => {
371+ let value = abstract_equality_comparison ( ctx, left, right) ?;
372+ Some ( ConstantValue :: Boolean ( value) )
373+ }
374+ BinaryOperator :: Inequality => {
375+ let value = abstract_equality_comparison ( ctx, left, right) ?;
376+ Some ( ConstantValue :: Boolean ( !value) )
369377 }
370378 BinaryOperator :: In => None ,
371379 }
0 commit comments