@@ -2400,3 +2400,108 @@ class TranslatedCilStoreIndirect extends TranslatedCilInstruction, TTranslatedCi
24002400 result = getTranslatedCilInstruction ( instr .getABackwardPredecessor ( ) ) .getStackElement ( i + 2 )
24012401 }
24022402}
2403+
2404+ // Translate a `nobjc<constructor>` CIL instruction to:
2405+ // 1. x = init
2406+ // 2. call co constructor(x, args...)
2407+ class TranslatedNewObject extends TranslatedCilInstruction , TTranslatedNewObject {
2408+ override Raw:: CilNewobj instr ;
2409+
2410+ TranslatedNewObject ( ) { this = TTranslatedNewObject ( instr ) }
2411+
2412+ final override predicate hasInstruction (
2413+ Opcode opcode , InstructionTag tag , Option< Variable > :: Option v
2414+ ) {
2415+ not exists ( instr .getConstructor ( ) ) and
2416+ opcode instanceof Opcode:: ExternalRef and
2417+ tag = CilNewObjExternalRefTag ( ) and
2418+ v .asSome ( ) = this .getTempVariable ( CilNewObjCallExternalVarTag ( ) )
2419+ or
2420+ opcode instanceof Opcode:: Init and
2421+ tag = CilNewObjInitTag ( ) and
2422+ v .asSome ( ) = this .getTempVariable ( CilNewObjInitVarTag ( ) )
2423+ or
2424+ opcode instanceof Opcode:: Call and
2425+ tag = CilNewObjCallTag ( ) and
2426+ v .isNone ( )
2427+ }
2428+
2429+ override string getExternalName ( InstructionTag tag ) {
2430+ not exists ( instr .getConstructor ( ) ) and
2431+ tag = CilCallTargetTag ( ) and
2432+ result = instr .getExternalName ( )
2433+ }
2434+
2435+ override predicate hasTempVariable ( TempVariableTag tag ) {
2436+ tag = CilNewObjInitVarTag ( )
2437+ or
2438+ not exists ( instr .getConstructor ( ) ) and tag = CilNewObjCallExternalVarTag ( )
2439+ }
2440+
2441+ override predicate producesResult ( ) { any ( ) }
2442+
2443+ override Variable getVariableOperand ( InstructionTag tag , OperandTag operandTag ) {
2444+ tag = CilNewObjCallTag ( ) and
2445+ (
2446+ not exists ( instr .getConstructor ( ) ) and
2447+ operandTag instanceof CallTargetTag and
2448+ result = this .getInstruction ( CilNewObjExternalRefTag ( ) ) .getResultVariable ( )
2449+ or
2450+ exists ( int i | i = operandTag .( CilOperandTag ) .getCilIndex ( ) |
2451+ // The 0'th argument to the constructor is the just-zero-initialized new object
2452+ if i = 0
2453+ then result = this .getInstruction ( CilNewObjInitTag ( ) ) .getResultVariable ( )
2454+ else
2455+ // And the other arguments are the constructor arguments
2456+ result =
2457+ getTranslatedCilInstruction ( instr .getABackwardPredecessor ( ) ) .getStackElement ( i - 1 )
2458+ )
2459+ )
2460+ }
2461+
2462+ override Instruction getChildSuccessor ( TranslatedElement child , SuccessorType succType ) { none ( ) }
2463+
2464+ override Instruction getSuccessor ( InstructionTag tag , SuccessorType succType ) {
2465+ tag = CilNewObjInitTag ( ) and
2466+ succType instanceof DirectSuccessor and
2467+ (
2468+ if exists ( instr .getConstructor ( ) )
2469+ then result = this .getInstruction ( CilNewObjCallTag ( ) )
2470+ else result = this .getInstruction ( CilNewObjExternalRefTag ( ) )
2471+ )
2472+ or
2473+ not exists ( instr .getConstructor ( ) ) and
2474+ (
2475+ tag = CilNewObjExternalRefTag ( ) and
2476+ succType instanceof DirectSuccessor and
2477+ result = this .getInstruction ( CilNewObjCallTag ( ) )
2478+ )
2479+ or
2480+ tag = CilNewObjCallTag ( ) and
2481+ succType instanceof DirectSuccessor and
2482+ result = getTranslatedInstruction ( instr .getASuccessor ( ) ) .getEntry ( )
2483+ }
2484+
2485+ override Instruction getEntry ( ) { result = this .getInstruction ( CilNewObjInitTag ( ) ) }
2486+
2487+ override Variable getResultVariable ( ) { result = this .getTempVariable ( CilNewObjInitVarTag ( ) ) }
2488+
2489+ final override TranslatedCilMethod getStaticCallTarget ( InstructionTag tag ) {
2490+ tag = CilNewObjCallTag ( ) and
2491+ result = getTranslatedFunction ( instr .getConstructor ( ) )
2492+ }
2493+
2494+ final override Variable getStackElement ( int i ) {
2495+ // The new top element is the constructed object
2496+ if i = 0
2497+ then result = this .getTempVariable ( CilNewObjInitVarTag ( ) )
2498+ else
2499+ // And the other arguments have been popped off the stack.
2500+ // Note: We don't subtract 1 because the number of arguments is actually
2501+ // one more than `instr.getNumberOfArguments()` since we the 0'th
2502+ // argument is the newly-constructed object.
2503+ result =
2504+ getTranslatedCilInstruction ( instr .getABackwardPredecessor ( ) )
2505+ .getStackElement ( i + instr .getNumberOfArguments ( ) )
2506+ }
2507+ }
0 commit comments