All files / transpiler/output/codegen/helpers BitRangeHelper.ts

100% Statements 13/13
100% Branches 8/8
100% Functions 5/5
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                                                    10x     10x       10x 4x       6x 6x               10x   10x 3x   7x             8x             9x                   2x          
/**
 * Helper utilities for generating bit range access code.
 * Extracted from CodeGenerator to improve testability.
 */
 
/**
 * Options for generating float bit read expressions.
 */
interface IFloatBitReadOptions {
  shadowName: string;
  varName: string;
  start: string;
  mask: string;
  shadowIsCurrent: boolean;
}
 
/**
 * Options for generating integer bit read expressions.
 */
interface IIntegerBitReadOptions {
  varName: string;
  start: string;
  mask: string;
}
 
/**
 * Helper class for bit range access code generation.
 */
class BitRangeHelper {
  /**
   * Build the bit read expression for floats.
   * Uses memcpy pattern to safely reinterpret float bits.
   */
  static buildFloatBitReadExpr(options: IFloatBitReadOptions): string {
    const { shadowName, varName, start, mask, shadowIsCurrent } = options;
 
    const shiftedRead =
      start === "0"
        ? `(${shadowName} & ${mask})`
        : `((${shadowName} >> ${start}) & ${mask})`;
 
    if (shadowIsCurrent) {
      return shiftedRead;
    }
 
    // Need memcpy to update shadow
    const memcpyPrefix = `memcpy(&${shadowName}, &${varName}, sizeof(${varName}))`;
    return `(${memcpyPrefix}, ${shiftedRead})`;
  }
 
  /**
   * Generate integer bit range read: ((value >> start) & mask)
   * Optimizes away the shift when start is 0.
   */
  static buildIntegerBitReadExpr(options: IIntegerBitReadOptions): string {
    const { varName, start, mask } = options;
 
    if (start === "0") {
      return `((${varName}) & ${mask})`;
    }
    return `((${varName} >> ${start}) & ${mask})`;
  }
 
  /**
   * Generate the shadow variable name for float bit access.
   */
  static getShadowVarName(rawName: string): string {
    return `__bits_${rawName}`;
  }
 
  /**
   * Get the shadow type for a float type.
   */
  static getShadowType(baseType: string): string {
    return baseType === "f64" ? "uint64_t" : "uint32_t";
  }
 
  /**
   * Generate a shadow variable declaration.
   */
  static buildShadowDeclaration(
    shadowName: string,
    shadowType: string,
  ): string {
    return `${shadowType} ${shadowName};`;
  }
}
 
export default BitRangeHelper;