-- $Id: java_stat_execution.ty,v 1.13 10/.0/.2 .1:.1:.4 mrusso Exp $ -- /***************************************************************************/ -- /* Copyright (C) 1997-1999 INRIA Sophia-Antipolis */ -- /* I. Attali, D. Caromel and M. Russo */ -- /* Projet OASIS */ -- /* Rt. des Lucioles, BP 93, */ -- /* F-06902 Sophia Antipolis cedex */ -- /* (+33) 4 92 38 76 31 */ -- /* All rights reserved */ -- /***************************************************************************/ program java_stat_execution is use java; use PSP; import executeOneInstruction ( Objects, ClassVariablesL, ObjectId |- Clr -> Objects, ClassVariablesL, Clr, ThreadStatus ) from java_concurrency; import ENVaddTheCrossedReferencesToTheInteractionStacks ( ObjectId, ObjectId ) , ENVchangeObjectStatusInStatusList ( ObjectId ) , ENVsendException ( Exception ) , ENVsendObjectAndClassVariableLists ( Objects, ClassVariablesL ) , ENVsendRemoveLockOnObject ( ObjectId ) , ENVupdateEnvIfNonDormantOrBlockedThreadOnObject ( ObjectId, Objects, integer ) from java_environment; import evaluateExpression ( Objects, ClassVariablesL, Env, ObjectId, ObjectId, Identifier |- SemExpression -> Objects, ClassVariablesL, Env, SemExpression, Insts, ThreadStatus ) , isValue ( SemExpression -> Bool ) from java_expr_evaluation; import isMyAncestor ( Type |- Type -> Bool ) from java_inheritance; import getInstructionsAndLocalVariables ( Insts, Locs |- Block => Insts, Locs ) , getNumberOfDormantAndBlockedThreadsOnTheGivenObject ( ObjectId |- Objects -> integer, integer ) , getObjectLockInformation ( ObjectId |- Objects -> ObjectId, integer ) , releaseObjectLock ( ObjectId |- Objects -> Objects ) , setLock ( ObjectId, ObjectId, Val |- Objects -> Objects ) , getObjectType ( ObjectId |- Objects -> Type ) from java_object_list; import appendtree ( _, _, _ ) , diff ( _, _ ) , emit_tree ( _, _ ) , eq ( _, _ ) , plus ( _, _, _ ) , sub ( _, _, _ ) , not_eq ( _, _ ) from prolog() ; var TVValue: Val; var TVBl: Block; var TVObjId: ObjectId; var TVVarDecl: LocalVariableDeclaration; var TVInitExprs: ArgumentList; set executeANonExpression is --RC: --RC: --RC: Concerned Statements: --RC: * Synchronized methods or blocks --RC: * Return statement --RC: * If, Else Block --RC: * Try, Catch or Finally Blocks --JC: judgement Objects, ClassVariablesL, ObjectId |- Clr -> Objects, ClassVariablesL, Clr, ThreadStatus; SkipEmptyStatement: ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[none().InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; SynchronizedStatement_ConversionIntoASynchroComp: --BSC: Synchronized Statement -- --CS: synchronized(Expr) Statement ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env, insts[synchroBegin(Expr, Statement).InstL]) -> ObjL1_1, ClVarL1_1, Clr, ThStatus -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env, insts[synchro(Expr, Statement).InstL]) -> ObjL1_1, ClVarL1_1, Clr, ThStatus ; SynchronizedStatement_HasTheObjectReference: --CS: synchronized(#8) Statement ObjL1, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[synchroLock(TVObjId, Statement).InstL]) -> ObjL1_1, ClVarL_1, Clr, ThStatus -------------------------------- ObjL1, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[synchroBegin(TVObjId, Statement).InstL]) -> ObjL1_1, ClVarL_1, Clr, ThStatus ; SynchronizedStatement_EvaluateExpressionToGetTheObjectReference: --CS: synchronized(Obj.getObj2()) Statement evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[synchroBegin(Expr1_1, Statement).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env1, insts[synchroBegin(Expr1, Statement).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, Env1_1, InstL3), ThStatus ; SynchronizedStatement_GetTheLockOrBeBlocked: --CS: synchronized(#8) Statement getObjectLockInformation( ObjId2 |- ObjL1 -> OThId2, nbLocks ) & getTheLockOrBeBlocked( OThId1, ObjId2, Statement, ObjL1, ClVarL |- OThId2, nbLocks -> ObjL1_1, Inst, ThStatus ) -------------------------------- ObjL1, ClVarL, OThId1 |- clr(ObjId1, Mode, MethName, Env, insts[synchroLock(ObjId2, Statement).InstL]) -> ObjL1_1, ClVarL, clr(ObjId1, Mode, MethName, Env, insts[Inst.InstL]), ThStatus ; SynchronizedStatement_BeginBlockExecution: appendtree( insts[Statement, synchroEnd(ObjId2)], InstL1, InstL2 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId1, Mode, MethName, Env, insts[synchroExecution(ObjId2, Statement).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL2), runnable() ; SynchronizedStatement_AfterANotify: --RC: The current executing thread retrieves the lock(s) that it had --RC: before the wait() method call on the given object. getObjectLockInformation( ObjId2 |- ObjL1 -> _, 0 ) & setLock( ObjId2, OThId, nbLocks |- ObjL1 -> ObjL1_1 ) -------------------------------- ObjL1, ClVarL, OThId |- clr(ObjId1, Mode, MethName, Env, insts[synchroWaitEndRelock(ObjId2, nbLocks).InstL]) -> ObjL1_1, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL), runnable() ; do ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ); EndSynchronizedStatementWithOneLock_RemoveLock: getObjectLockInformation( ObjId2 |- ObjL1 -> OThId, 1 ) & releaseObjectLock( ObjId2 |- ObjL1 -> ObjL1_1 ) -------------------------------- ObjL1, ClVarL, OThId |- clr(ObjId1, Mode, MethName, Env, insts[synchroEnd(ObjId2).InstL]) -> ObjL1_1, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL), runnable() ; do ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ) & ENVupdateEnvIfNonDormantOrBlockedThreadOnObject( ObjId2, ObjL1_1, 0 ) & ENVchangeObjectStatusInStatusList( ObjId2 ); EndSynchronizedStatementWithSeveralLocks_RemoveOneLock: --ESC: End Synchronized -- getObjectLockInformation( ObjId2 |- ObjL1 -> OThId, nbLocks1 ) & diff( integer nbLocks1, integer 1 ) & sub( nbLocks1, 1, nbLocks1_1 ) & setLock( ObjId2, OThId, integer nbLocks1_1 |- ObjL1 -> ObjL1_1 ) -------------------------------- ObjL1, ClVarL, OThId |- clr(ObjId1, Mode, MethName, Env, insts[synchroEnd(ObjId2).InstL]) -> ObjL1_1, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL), runnable() ; do ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ); ReturnAnExpression_FirstStepExpressionEvaluation: --BSC: Return Statement -- --CS: return(Obj4.foo()); evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[semReturn(Expr1_1).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env1, insts[return(Expr1).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, Env1_1, InstL3), ThStatus ; provided diff( Expr1, none() ); ReturnNothing_LeaveTheBlock_GetTheSynchroEndOfTheBlockAndTheClosure: --RC: Retrieves from the block all the "synchroEnd" instructions before --RC: leaving this block. Retrieves also all the "synchroEnd" instruction --RC: present in the current closure. -- --CS: return; getSynchroEndInstructions( InstL2 -> InstL3 ) & getSynchroEndInstructions( InstL1 -> InstL4 ) & appendtree( insts[semBlock(insts[], blockEnv(ParamL, LocVarL, BlLocVarL)).InstL3], InstL4, InstL5 ) & appendtree( InstL5, insts[return(none())], InstL5_1 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semBlock(insts[return(none()).InstL2], blockEnv(ParamL, LocVarL, BlLocVarL)).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL5_1), runnable() ; ReturnAValue_LeaveTheBlock_GetTheSynchroEndOfTheBlockAndTheClosure: --RC: Retrieves from the block all the "synchroEnd" instructions before --RC: leaving this block. Retrieves also all the "synchroEnd" instruction --RC: present in the current closure. -- --CS: return(33); getSynchroEndInstructions( InstL2 -> InstL3 ) & getSynchroEndInstructions( InstL1 -> InstL4 ) & appendtree( insts[semBlock(insts[], blockEnv(ParamL, LocVarL, BlLocVarL)).InstL3], InstL4, InstL5 ) & appendtree( InstL5, insts[return(TVValue)], InstL5_1 ) -------------------------------- ObjL, ClVarL, _ |- clr( ObjId, Mode, MethName, env(ParamL, LocVarL), insts[semBlock(insts[return(TVValue).InstL2], blockEnv(ParamL, LocVarL, BlLocVarL)).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, env(ParamL, LocVarL), InstL5_1), runnable() ; ReturnAnExpression_ExpressionEvaluation: --CS: return(#5.foo()); evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[semReturn(Expr1_1).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env1, insts[semReturn(Expr1).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, Env1_1, InstL3), ThStatus ; provided diff( Expr1, none() ); ReturnAnEvaluatedExpression_LeaveTheBlock: --CS: return(Obj3); getSynchroEndInstructions( InstL2 -> InstL3 ) & getSynchroEndInstructions( InstL1 -> InstL4 ) & appendtree( insts[semBlock(insts[], blockEnv(ParamL, LocVarL, BlLocVarL)).InstL3], InstL4, InstL5 ) & appendtree( InstL5, insts[semReturn(TVValue)], InstL5_1 ) -------------------------------- ObjL, ClVarL, _ |- clr( ObjId, Mode, MethName, env(ParamL, LocVarL), insts[semBlock(insts[semReturn(TVValue).InstL2], blockEnv(ParamL, LocVarL, BlLocVarL)).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, env(ParamL, LocVarL), InstL5_1), runnable() ; ReturnNothing_LeaveTheClosure: getSynchroEndInstructions( InstL2 -> InstL3 ) & appendtree( insts[clr(ObjId2, Mode2, MethName2, Env2, insts[]).InstL3], InstL1, InstL4 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[return(none()).InstL2]).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode1, MethName1, Env1, InstL4), runnable() ; ReturnAnEvaluatedExpression_LeaveTheClosure: getSynchroEndInstructions( InstL2 -> InstL3 ) & isReturnBeTheFirstLocalVariable( Env1 -> true() ) & appendtree( insts[clr(ObjId2, Mode2, MethName2, Env2, insts[]).InstL3], insts[semAssign(empty(), identifier "7RETURN", assignment(), TVValue).InstL1], InstL4 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[semReturn(TVValue).InstL2]).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode1, MethName1, Env1, InstL4), runnable() ; ReturnAValue_LeaveTheClosure: getSynchroEndInstructions( InstL2 -> InstL3 ) & isReturnBeTheFirstLocalVariable( Env1 -> true() ) & appendtree( insts[clr(ObjId2, Mode2, MethName2, Env2, insts[]).InstL3], insts[binaryAssign(identifier "7RETURN", assignment(), TVValue).InstL1], InstL4 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[return(TVValue).InstL2]).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode1, MethName1, Env1, InstL4), runnable() ; ReturnAnEvaluatedExpressionNotUseful_LeaveTheClosure: getSynchroEndInstructions( InstL2 -> InstL3 ) & isReturnBeTheFirstLocalVariable( Env1 -> false() ) & appendtree( insts[clr(ObjId2, Mode2, MethName2, Env2, insts[]).InstL3], InstL1, InstL4 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[semReturn(TVValue).InstL2]).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode1, MethName1, Env1, InstL4), runnable() ; ReturnAValueNotUseful_LeaveTheClosure: --ESC: Return Statement -- getSynchroEndInstructions( InstL2 -> InstL3 ) & isReturnBeTheFirstLocalVariable( Env1 -> false() ) & appendtree( insts[clr(ObjId2, Mode2, MethName2, Env2, insts[]).InstL3], InstL1, InstL4 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[return(TVValue).InstL2]).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode1, MethName1, Env1, InstL4), runnable() ; IfExpressionThenElse_EvaluateExpression: --BSC: If Statement -- --CS: if(Obj2.foo() > 9) Statement1 else Statement2; evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId1, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[if(Expr1_1, Stat1, Stat2).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId1, Mode, MethName, Env1, insts[if(Expr1, Stat1, Stat2).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId1, Mode, MethName, Env1_1, InstL3), ThStatus ; provided diff( Expr1, true() ) & diff( Expr1, false() ); IfFalseWithoutElse_NothingToDo: --CS: if(false) Statement; ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[if(false(), _, none()).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; IfFalse_ExecuteTheElseStatement: --CS: if(false) Statement1 else Statement2; ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[if(false(), _, ElseStatement).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[ElseStatement.InstL]), runnable() ; IfTrue_ExecuteTheThenStatement: --CS: if(true) Statement; -- --ESC: If Statement -- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[if(true(), ThenStatement, _).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[ThenStatement.InstL]), runnable() ; SwitchExecution_EvaluateExpression: evaluateExpression( ObjL, ClVarL, Env, OThId, ObjId, Mode |- Expr -> ObjL_1, ClVarL_1, Env_1, Expr_1, InstL2, ThStatus ) & appendtree( InstL2, insts[switch(Expr_1, SwitchBlk).InstL1], InstL3 ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[switch(Expr, SwitchBlk).InstL1]) -> ObjL_1, ClVarL_1, clr(ObjId, Mode, MethName, Env_1, InstL3), ThStatus ; provided isValue( Expr -> false() ); SwitchExecution_FindStatements: selectSwitchStatements( Expr, SwitchBlk -> Block ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[switch(Expr, SwitchBlk).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[Block.InstL]), runnable() ; provided isValue( Expr -> true() ); WhileExpression_Conversion: --BSC: While Statement -- --CS: while(Obj.getAttr() == 5) {Statement} ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[while(Expr, WhileStatement).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[semWhile(Expr, WhileStatement, Expr).InstL]), runnable() ; DoExpression_Conversion: --BSC: Do Statement - transform to while. -- --CS: do {Statement} while(Obj.getAttr() == 5) ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[doloop(DoStatement, Expr).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[DoStatement, semWhile(Expr, DoStatement, Expr).InstL]), runnable() ; WhileExpression_EvaluateExpression: --CS: while(Expression) {Statement}; evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[semWhile(Expr1_1, WhileStatement, Expr2).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env1, insts[semWhile(Expr1, WhileStatement, Expr2).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, Env1_1, InstL3), ThStatus ; provided diff( Expr1, true() ) & diff( Expr1, false() ); WhileTrue_ExecuteStatement: --CS: while(true) {Statement}; ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semWhile(true(), WhileStatement, Expr).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[WhileStatement, semWhile(Expr, WhileStatement, Expr).InstL]), runnable() ; WhileFalse_ExecuteStatement: --CS: while(false) {Statement}; -- --ESC: While statement ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semWhile(false(), _, _).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; ForConversion_NoNewLocals: --BSC: Convert a for statement which does not introduce new local --BSC: variables into a (possibly empty) list of initialization --BSC: instructions and a semFor. -- --CS: for (x = 1; x < 10; x++) stmt convertArgumentListToInsts( TVInitExprs -> InitExprs_1 ) & unoptOptExpr( MaybePred, true() -> Pred ) & appendtree( InitExprs_1, insts[semFor(Pred, ForStmt, UpdExprs, Pred).InstL1], InstL2 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[for(TVInitExprs, MaybePred, UpdExprs, ForStmt).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL2), runnable() ; ForConversion_NewLocals: --BSC: Convert a for statement which does introduce new local --BSC: variables into a block containing a semFor. -- --CS: for (int x = 1; x < 10; x++) stmt ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[block[TVVarDecl, for(arguments[], MaybePred, UpdExprs, ForStmt)].InstL]) -> ObjL_1, ClVarL_1, Clr, ThStatus -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[for(TVVarDecl, MaybePred, UpdExprs, ForStmt).InstL]) -> ObjL_1, ClVarL_1, Clr, ThStatus ; ForExecution_EvaluatePredicate: evaluateExpression( ObjL, ClVarL, Env, OThId, ObjId, Mode |- Pred1 -> ObjL_1, ClVarL_1, Env_1, Pred1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[semFor(Pred1_1, ForStmt, UpdExprs, Pred).InstL1], InstL3 ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[semFor(Pred1, ForStmt, UpdExprs, Pred).InstL1]) -> ObjL_1, ClVarL_1, clr(ObjId, Mode, MethName, Env_1, InstL3), ThStatus ; provided diff( Pred1, true() ) & diff( Pred1, false() ); ForExecution_True: convertArgumentListToInsts( UpdExprs -> UpdExprs_1 ) & appendtree( insts[ForStmt.UpdExprs_1], insts[semFor(Pred, ForStmt, UpdExprs, Pred).InstL1], InstL2 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semFor(true(), ForStmt, UpdExprs, Pred).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL2), runnable() ; ForExecution_False: ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semFor(false(), _, _, _).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; Block_GetInstructionsAndEnvironment: getInstructionsAndLocalVariables( insts[], locs[pairs[]] |- TVBl => InstL2, locs[BlLocVarL._] ) & appendtree( insts[semBlock(InstL2, blockEnv(ParamL, LocVarL, BlLocVarL))], InstL1, InstL3 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, env(ParamL, LocVarL), insts[TVBl.InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, env(ParamL, LocVarL), InstL3), runnable() ; NoMoreInstructionInTheBlock: ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semBlock(insts[], _).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; NoMoreClosureInstructionInTheBlock: ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semBlock(insts[clr(_, _, _, _, insts[]).InstL2], EnvBlock).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[semBlock(InstL2, EnvBlock).InstL1]), runnable() ; BreakInBlock_GetSynchroEndInstructions: getSynchroEndInstructions( InstL2 -> InstL3 ) & appendtree( insts[semBlock(insts[], EnvBlock).InstL3], InstL1, InstL4 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[semBlock(insts[break(none()).InstL2], EnvBlock).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL4), runnable() ; Except: getSynchroEndInstructions( InstL1 -> InstL2 ) & appendtree( InstL2, insts[exception(OThId, ObjId1, MethName, except(ClName, ObjId2, ExceptText))], InstL3 ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId1, Mode, MethName, Env, insts[except(ClName, ObjId2, ExceptText).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL3), runnable() ; ExceptInBlock_GetSynchroEndInBlockAndClosure: --RC: Gets the synchronized blocks ends instructions in the current --RC: block and in the current closure. The new instruction list is made --RC: of the empty block, the release locks instructions and of the --RC: exception instruction. getSynchroEndInstructions( InstL2 -> InstL3 ) & getSynchroEndInstructions( InstL1 -> InstL4 ) & appendtree( insts[semBlock(insts[], EnvBlock).InstL3], InstL4, InstL5 ) & appendtree( InstL5, insts[exception(OThId, ObjId1, MethName, except(ClName, ObjId2, ExceptText))], InstL6 ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId1, Mode, MethName, Env, insts[semBlock(insts[except(ClName, ObjId2, ExceptText).InstL2], EnvBlock).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL6), runnable() ; ExceptInClosure_GetSynchroEndInClosure: --RC: Gets the release lock instructions of the current closure. --RC: Put them in front of the instruction list before the empty --RC: closure and the exception. -- --ESC: Except Statement getSynchroEndInstructions( InstL2 -> InstL3 ) & appendtree( InstL3, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[]), exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)).InstL1], InstL4 ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[except(ClName, ObjId3, ExceptText).InstL2]).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode1, MethName1, Env1, InstL4), runnable() ; NonCaughtExceptionInMainMethod: --BSC: Exception Statement -- --RC: As the exception is uncaught, the thread execution --RC: is aborted (empty instruction list) and the exception --RC: is sent to the environment. ObjL, ClVarL, OThId |- clr(OThId, Mode, identifier "main", Env, insts[exception(OThId, ObjId1, MethName, except(ClName, ObjId2, ExceptText))._]) -> ObjL, ClVarL, clr(OThId, Mode, identifier "main", Env, insts[]), runnable() ; do ENVsendException( exception(OThId, ObjId1, MethName, except(ClName, ObjId2, ExceptText)) ); NonCaughtExceptionInRunMethod: --RC: As the exception is uncaught, the thread execution --RC: is aborted (empty instruction list) and the exception --RC: is sent to the environment. ObjL, ClVarL, OThId |- clr(OThId, Mode, identifier "run", Env, insts[exception(OThId, ObjId1, MethName, except(ClName, ObjId2, ExceptText))._]) -> ObjL, ClVarL, clr(OThId, Mode, identifier "run", Env, insts[]), runnable() ; do ENVsendException( exception(OThId, ObjId1, MethName, except(ClName, ObjId2, ExceptText)) ); ExceptionInBlock_GetSynchroEndInBlockAndClosure: --RC: Gets the synchronized blocks ends instructions in the current --RC: block and in the current closure. The new instruction list is made --RC: of the empty block, the release locks instructions and of the --RC: exception instruction. getSynchroEndInstructions( InstL2 -> InstL3 ) & getSynchroEndInstructions( InstL1 -> InstL4 ) & appendtree( insts[semBlock(insts[], EnvBlock).InstL3], InstL4, InstL5 ) & appendtree( InstL5, insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], InstL6 ) -------------------------------- ObjL, ClVarL, OThId |- clr( ObjId1, Mode, MethName1, Env, insts[semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)).InstL2], EnvBlock).InstL1]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName1, Env, InstL6), runnable() ; ExceptionInClosure_GetSynchroEndInClosure: --RC: Gets the synchronized blocks ends instructions in the current --RC: closure. The new instruction list is made of the closure with --RC: the release locks instructions and of the exception instruction. -- --ESC: Exception Statement getSynchroEndInstructions( InstL2 -> InstL3 ) -------------------------------- ObjL, ClVarL, OThId |- clr( ObjId1, Mode1, MethName1, Env1, insts[ clr(ObjId2, Mode2, MethName2, Env2, insts[exception(OThId, ObjId3, MethName3, except(ClName, ObjId4, ExceptText)).InstL2]).InstL1]) -> ObjL, ClVarL, clr( ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, InstL3), exception(OThId, ObjId3, MethName3, except(ClName, ObjId4, ExceptText)).InstL1]), runnable() ; TryExpression_GetInstructionAndLocalVariables: --BSC: Try Statement -- --CS: try{ Bl } --CS: catch(Type){ Bl1 }* --CS: finally{ Bln } getInstructionsAndLocalVariables( insts[], locs[pairs[]] |- TVBl => InstL2, locs[BlLocVarL._] ) & appendtree( insts[tryBlockExecution(semBlock(InstL2, blockEnv(ParamL, LocVarL, BlLocVarL)), CatchL, Final)], InstL1, InstL3 ) -------------------------------- ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, env(ParamL, LocVarL), insts[try(TVBl, CatchL, Final).InstL1]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, env(ParamL, LocVarL), InstL3), runnable() ; EndTryBlockWithoutFinallyBlock: --RC: End of the execution of the try block without an exception. --RC: There is no finally block to execute. -- --CS: try{} --CS: catch(Type){ Bl1 }* --CS: finally{} ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[tryBlockExecution(semBlock(insts[], _), _, none()).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; EndTryBlockWithFinally_ExecuteTheFinallyBlock: --RC: End of the execution of the try block without an exception. --RC: There is a finally block to execute before exiting the try --RC: expression execution. -- --CS: try{ } --CS: catch(Type){ Bl1 }* --CS: finally{ Bln } ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[tryBlockExecution(semBlock(insts[], _), _, TVBl).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[tryFinallyExecutionBegin(TVBl).InstL]), runnable() ; ExceptionInTryBlock_CatchTheException: --RC: There is a good catch clause so it will be executed at the next --RC: execution step of the current executing thread 'OThId'. getTheCatchClauseIfPossible( ClName |- CatchL -> Catch, true() ) -------------------------------- ObjL, ClVarL, OThId |- clr( ObjId1, Mode, MethName1, Env, insts[ tryBlockExecution(semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], EnvBlock), CatchL, Final). InstL]) -> ObjL, ClVarL, clr( ObjId1, Mode, MethName1, Env, insts[ tryBlockExecution(semBlock(insts[], EnvBlock), catches[], none()), tryCatchBlockExecutionBegin(exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)), Catch, Final).InstL]), runnable() ; TryCatchBlock_GetInstructionsAndLocalVariables: --CS: catch(ClName2 Ident){ Bl } --CS: finally{ Fin } getInstructionsAndLocalVariables( insts[], locs[pairs[]] |- TVBl => InstL2, locs[BlLocVarL._] ) -------------------------------- ObjL, ClVarL, OThId |- clr( ObjId1, Mode, MethName1, env(ParamL, LocVarL), insts[ tryCatchBlockExecutionBegin( exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)), catch(parameter(_, _, Param), TVBl), Final).InstL1]) -> ObjL, ClVarL, clr( ObjId1, Mode, MethName1, env(ParamL, LocVarL), insts[ tryCatchBlockExecution( exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)), semBlock(InstL2, blockEnv(pairs[pair(Param, ObjId3).ParamL], LocVarL, BlLocVarL)), Final).InstL1]), runnable() ; EndCatchBlockWithAnException_WithoutFinallyBlock: --RC: End of the execution of the catch block with an exception. --RC: There is no finally block to execute. -- --CS: try{} --CS: catch(Type){ Exception } --CS: finally{} ObjL, ClVarL, _ |- clr( ObjId1, Mode, MethName1, Env, insts[ tryCatchBlockExecution(_, semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], _), none()).InstL]) -> ObjL, ClVarL, clr( ObjId1, Mode, MethName1, Env, insts[ tryCatchBlockExecution(_, semBlock(insts[], _), none()), exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)). InstL]), runnable() ; EndCatchBlockWithAnException_WithFinallyBlock: --RC: End of the execution of the catch block with an exception. --RC: There is a finally block to execute before treating the exception. -- --CS: try{} --CS: catch(Type){ Exception } --CS: finally{ Bl } ObjL, ClVarL, _ |- clr( ObjId1, Mode, MethName1, Env, insts[ tryCatchBlockExecution(_, semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], _), TVBl).InstL]) -> ObjL, ClVarL, clr( ObjId1, Mode, MethName1, Env, insts[ tryCatchBlockExecution(_, semBlock(insts[], _), none()), tryFinallyExecutionBegin(TVBl), exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)).InstL]), runnable() ; EndCatchBlockWithoutFinallyBlock: --RC: End of the execution of the catch block without an exception. --RC: There is no finally block to execute. -- --CS: try{} --CS: catch(Type){ } --CS: finally{} ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[tryCatchBlockExecution(_, semBlock(insts[], _), none()).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; EndCatchBlock_ExecuteTheFinallyBlock: --RC: End of the execution of the catch block without an exception. --RC: There is a finally block to execute before exiting the try --RC: expression execution. -- --CS: try{ Bl } --CS: catch(Type){ } --CS: finally{ Bln } ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, env(ParamL, LocVarL), insts[tryCatchBlockExecution(_, semBlock(insts[], _), TVBl).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, env(ParamL, LocVarL), insts[tryFinallyExecutionBegin(TVBl).InstL]), runnable() ; Catch_ExecuteOneInstruction: --CS: try{ Bl } --CS: catch(Type){ Bl1 }* --CS: finally{ Bln } executeOneInstruction( ObjL1, ClVarL1, OThId |- clr(ObjId1, Mode, MethName1, env(pairs[Param.ParamL1], locs[BlLocVarL1.LocVarL1]), insts[Inst.InstL2]) -> ObjL1_1, ClVarL1_1, clr(ObjId1, Mode, MethName1, env(pairs[Param.ParamL1_1], locs[BlLocVarL1_1.LocVarL1_1]), InstL3), ThStatus ) -------------------------------- ObjL1, ClVarL1, OThId |- clr( ObjId1, Mode, MethName1, env(ParamL1, LocVarL1), insts[ tryCatchBlockExecution( exception(OThId, ObjId2, MethName2, except(ClName1, ObjId3, ExceptText)), semBlock(insts[Inst.InstL2], blockEnv(pairs[Param], LocVarL1, BlLocVarL1)), Final).InstL1]) -> ObjL1_1, ClVarL1_1, clr( ObjId1, Mode, MethName1, env(ParamL1_1, LocVarL1_1), insts[ tryCatchBlockExecution( exception(OThId, ObjId2, MethName2, except(ClName1, ObjId3, ExceptText)), semBlock(InstL3, blockEnv(pairs[Param], LocVarL1_1, BlLocVarL1_1)), Final).InstL1]), ThStatus ; EndTryWithAnException_NoCorrespondingCatchClauseOrFinally_ThrowTheException: getTheCatchClauseIfPossible( ClName |- CatchL -> _, false() ) -------------------------------- ObjL, ClVarL, OThId |- clr( ObjId1, Mode, MethName1, Env, insts[ tryBlockExecution(semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], _), CatchL, none()).InstL]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName1, Env, insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)).InstL]), runnable() ; EndTryWithAnException_NoCorrespondingCatchClause_ExecuteTheFinallyBlock: getTheCatchClauseIfPossible( ClName |- CatchL -> _, false() ) -------------------------------- ObjL, ClVarL, OThId |- clr( ObjId1, Mode, MethName1, Env, insts[ tryBlockExecution(semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], _), CatchL, Final).InstL]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName1, Env, insts[Final, exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)).InstL]), runnable() ; provided diff( Final, none() ); TryBlock_executeOneInstruction: --CS: try{ Bl } --CS: catch(Type){ Bl1 }* --CS: finally{ Bln } executeOneInstruction( ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, env(ParamL1, locs[BlLocVarL1.LocVarL1]), insts[Inst.InstL2]) -> ObjL1_1, ClVarL1_1, clr(ObjId1, Mode, MethName, env(ParamL1_1, locs[BlLocVarL1_1.LocVarL1_1]), InstL3), ThStatus ) -------------------------------- ObjL1, ClVarL1, OThId |- clr( ObjId, Mode, MethName, env(ParamL1, LocVarL1), insts[tryBlockExecution(semBlock(insts[Inst.InstL2], blockEnv(ParamL1, LocVarL1, BlLocVarL1)), CatchL, Final).InstL1]) -> ObjL1_1, ClVarL1_1, clr( ObjId, Mode, MethName, env(ParamL1_1, LocVarL1_1), insts[tryBlockExecution(semBlock(InstL3, blockEnv(ParamL1_1, LocVarL1_1, BlLocVarL1_1)), CatchL, Final).InstL1]), ThStatus ; EnterInAFinallyBlock: --CS: try{} --CS: catch(Type){ Bl1 }* --CS: finally{ Bl } getInstructionsAndLocalVariables( insts[], locs[pairs[]] |- TVBl => InstL2, locs[BlLocVarL._] ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, env(ParamL, LocVarL), insts[tryFinallyExecutionBegin(TVBl).InstL1]) -> ObjL, ClVarL, clr( ObjId, Mode, MethName, env(ParamL, LocVarL), insts[tryFinallyExecution(semBlock(InstL2, blockEnv(ParamL, LocVarL, BlLocVarL))).InstL1]), runnable() ; FinallyBlock_ExecuteOneInstruction: --CS: try{ Bl } --CS: catch(Type){ Bl1 }* --CS: finally{ Bln } executeOneInstruction( ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, env(ParamL1, locs[BlLocVarL1.LocVarL1]), insts[Inst.InstL2]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, env(ParamL1_1, locs[BlLocVarL1_1.LocVarL1_1]), InstL3), ThStatus ) -------------------------------- ObjL1, ClVarL1, OThId |- clr( ObjId, Mode, MethName, env(ParamL1, LocVarL1), insts[tryFinallyExecution(semBlock(insts[Inst.InstL2], blockEnv(ParamL1, LocVarL1, BlLocVarL1))).InstL1]) -> ObjL1_1, ClVarL1_1, clr( ObjId, Mode, MethName, env(ParamL1_1, LocVarL1_1), insts[tryFinallyExecution(semBlock(InstL3, blockEnv(ParamL1_1, LocVarL1_1, BlLocVarL1_1))).InstL1]), ThStatus ; ExceptionDuringFinallyBlockExecution: --CS: finally{ Exception } ObjL, ClVarL, _ |- clr( ObjId1, Mode, MethName1, Env, insts[tryFinallyExecution(semBlock(insts[exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText))], EnvBlock)).InstL]) -> ObjL, ClVarL, clr( ObjId1, Mode, MethName1, Env, insts[ tryFinallyExecution(semBlock(insts[], EnvBlock)), exception(OThId, ObjId2, MethName2, except(ClName, ObjId3, ExceptText)).InstL]), runnable() ; EndFinallyBlockExecutionWithoutAnException: --CS: finally{ } -- --ESC: Try statement ObjL, ClVarL, _ |- clr(ObjId, Mode, MethName, Env, insts[tryFinallyExecution(semBlock(insts[], EnvBlock)).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, InstL), runnable() ; ThrowExpression_EvaluatedExpression: --BSC: Throw Statement -- --CS: throw #4 getObjectType( TVObjId |- ObjL -> ClName ) -------------------------------- ObjL, ClVarL, OThId |- clr(ObjId, Mode, MethName, Env, insts[semThrow(TVObjId).InstL]) -> ObjL, ClVarL, clr(ObjId, Mode, MethName, Env, insts[except(ClName, TVObjId, exceptText "thrown exception").InstL]), runnable() ; ThrowExpression_EvaluateExpression: --CS: throw Expr; evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[semThrow(Expr1_1).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env1, insts[semThrow(Expr1).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, Env1_1, InstL3), ThStatus ; ThrowExpression_EvaluateExpression: --CS: throw Expr; -- --ESC: Throw Statement evaluateExpression( ObjL1, ClVarL1, Env1, OThId, ObjId, Mode |- Expr1 -> ObjL1_1, ClVarL1_1, Env1_1, Expr1_1, InstL2, ThStatus ) & appendtree( InstL2, insts[semThrow(Expr1_1).InstL1], InstL3 ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, Env1, insts[throw(Expr1).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, Env1_1, InstL3), ThStatus ; NoMoreInstructionInTheClosure: ObjL, ClVarL, OThId |- clr(ObjId1, Mode, MethName, Env, insts[clr(ObjId2, _, _, _, insts[]).InstL]) -> ObjL, ClVarL, clr(ObjId1, Mode, MethName, Env, InstL), runnable() ; do ENVaddTheCrossedReferencesToTheInteractionStacks( OThId, ObjId2 ); InstructionInBlock: --CS: {Inst1;InstL2} executeOneInstruction( ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, env(ParamL1, locs[BlLocVarL1.LocVarL1]), insts[Inst.InstL2]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, env(ParamL1_1, locs[BlLocVarL1_1.LocVarL1_1]), InstL3), ThStatus ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId, Mode, MethName, env(ParamL1, LocVarL1), insts[semBlock(insts[Inst.InstL2], blockEnv(ParamL1, LocVarL1, BlLocVarL1)).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId, Mode, MethName, env(ParamL1_1, LocVarL1_1), insts[semBlock(InstL3, blockEnv(ParamL1_1, LocVarL1_1, BlLocVarL1_1)).InstL1]), ThStatus ; InstructionInClosure: executeOneInstruction( ObjL1, ClVarL1, OThId |- clr(ObjId2, Mode2, MethName2, Env2, insts[Inst.InstL2]) -> ObjL1_1, ClVarL1_1, clr(ObjId2, Mode2, MethName2, Env2_1, InstL3), ThStatus ) -------------------------------- ObjL1, ClVarL1, OThId |- clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2, insts[Inst.InstL2]).InstL1]) -> ObjL1_1, ClVarL1_1, clr(ObjId1, Mode1, MethName1, Env1, insts[clr(ObjId2, Mode2, MethName2, Env2_1, InstL3).InstL1]), ThStatus ; provided ENVaddTheCrossedReferencesToTheInteractionStacks( OThId, ObjId2 ); set getTheLockOrBeBlocked is --SC: Locks the given object if it is not already locked. --SC: If the given object is already locked by --SC: 1] by the current thread, the number of locks on this object is --SC: increased by one. --SC: 2] by an other thread, the current existing thread is blocked to --SC: wait the unlock of the object -- --JC: Current executing thread reference, Reference of the object to lock, --JC: Statement, Objects, Class variables (only used for the environment) --JC: |- Thread that demands the lock on the given object, --JC: Number of existing locks on the given object --JC: -> modified object list, Instruction, --JC: New current executing thread status judgement ObjectId, ObjectId, Statement, Objects, ClassVariablesL |- ObjectId, integer -> Objects, Inst, ThreadStatus; UnlockedObject: setLock( ObjId, OThId, integer 1 |- ObjL1 -> ObjL1_1 ) -------------------------------- OThId, ObjId, Statement, ObjL1, ClVarL |- _, 0 -> ObjL1_1, synchroExecution(ObjId, Statement), runnable() ; do ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ); ObjectLockedByAnotherThread: OThId1, ObjId, Statement, ObjL1, _ |- OThId2, nbLocks -> ObjL1, synchroLock(ObjId, Statement), blocked(ObjId) ; provided diff( nbLocks, 0 ) & diff( OThId1, OThId2 ); ObjectLockedByTheCurrentThread: plus( nbLocks1, 1, nbLocks1_1 ) & setLock( ObjId, OThId, integer nbLocks1_1 |- ObjL1 -> ObjL1_1 ) -------------------------------- OThId, ObjId, Statement, ObjL1, ClVarL |- OThId, nbLocks1 -> ObjL1_1, synchroExecution(ObjId, Statement), runnable() ; provided diff( nbLocks, 0 ); do ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ); end getTheLockOrBeBlocked ; end executeANonExpression; set getTheCatchClauseIfPossible is --SC: Retrives from the catch blocks the first catch block that has the --SC: corresponding exception type (or sub-type) as argument --SC: Returns false if no corresponding catch block is found. -- --JC: Class name of the exception that needs to be catched --JC: |- Catch blocks of the try --JC: -> found catch block, true/false if not found judgement Identifier |- Catches -> Catch, Bool; NoMoreCatchBlock: ClName |- catches[] -> _, false() ; HasFoundTheCatchBlock_SameType: ClName |- catches[catch(parameter(ModL, ClName, ParamName), TVBl)._] -> catch(parameter(ModL, ClName, ParamName), TVBl), true() ; HasFoundTheCatchBlock_SubType: isMyAncestor( ClName2 |- ClName1 -> true() ) -------------------------------- ClName1 |- catches[catch(parameter(ModL, ClName2, Ident), TVBl)._] -> catch(parameter(ModL, ClName2, Ident), TVBl), true() ; provided diff( ClName1, ClName2 ); RecursiveRule: isMyAncestor( ClName2 |- ClName1 -> false() ) & ClName1 |- CatchL -> Catch, TV -------------------------------- ClName1 |- catches[catch(parameter(_, ClName2, _), _).CatchL] -> Catch, TV ; provided diff( ClName1, ClName2 ); end getTheCatchClauseIfPossible; set getSynchroEndInstructions is --SC: Retrieves from an instruction list, all the "synchroEnd" instructions --SC: useful for removing locks set for a synchronized block or method. --SC: (the "synchroEnd" instructions are added during the program --SC: interpretation) -- --JC: Instruction list --JC: -> Instruction list that only contains the synchroEnd instructions. judgement (Insts -> Insts); NoMoreInstruction: (insts[] -> insts[]) ; SynchroEndAddedToTheInstrL_RecursiveRule: (InstL1 -> InstL2) -------------------------------- (insts[synchroEnd(ObjId1).InstL1] -> insts[synchroEnd(ObjId1).InstL2]) ; NotASynchroEndInst_RecursiveRule: (InstL1 -> InstL2) -------------------------------- (insts[Inst.InstL1] -> InstL2) ; provided not_eq( Inst, synchroEnd(_) ); end getSynchroEndInstructions; set isReturnBeTheFirstLocalVariable is --SC: Checks if the 7RETURN variable (used to return a value from a closure) --SC: is the first variable in the current local variable list -- --JC1: Closure environment (i.e. parameters and local variables) --JC1: -> True if 7RETURN present/False otherwise judgement (Env -> Bool); --JC2: set of local variable lists (only the first one is checked) --JC2: => True/False judgement (Locs => Bool); --JC3: current local variable list (only the first variable will be checked) --JC3: =:> True/false judgement (Pairs =:> Bool); GetSetOfLocalVariableLists: (LocVarL => TF) -------------------------------- (env(_, LocVarL) -> TF) ; GetTheFirstLocalVariableList: (LocVarL =:> TF) -------------------------------- (locs[LocVarL._] => TF) ; TheFirstLocalVariableIsNotTheRETURN: (pairs[pair(LocVarName, _)._] =:> false()) ; provided diff( LocVarName, identifier "7RETURN" ); EmptyList_RETURNAbsent: (pairs[] =:> false()) ; RETURNPresentAsFirstLocalVariable: (pairs[pair(identifier "7RETURN", _)._] =:> true()) ; end isReturnBeTheFirstLocalVariable; set selectSwitchStatements is --SC: Computes a block of the relevant declarations and instructions --SC: from a switch block given the value of the switch expressions. --SC: Note that declarations that are not executed are still in scope! --SC: --SC: Limitation: The case labels are assumed to be literal constants. --SC: The reason is that they must be compile time constants. Thus --SC: it is strictly speaking wrong to evaluate them dynamically using --SC: a small-setp semantics. A large-step constant expression evaluation --SC: relation would be needed. Furthermore, evaluating using a small --SC: step semantics and searching simultaneously seems complicated. --SC: Maybe a pre-pass which evaluated all labels would be an adequate --SC: temporary solution. judgement (SemExpression, SwitchStatements -> Block); SelectSwitchStatements_LabelFound: getDeclsBeforeLabel( Label, SwStmts -> Decls, SwStmts_1 ) & convertSwitchStatementsToBlock( SwStmts_1 -> SelStmts ) & appendtree( Decls, SelStmts, DeclsAndSelStmts ) -------------------------------- (Label, SwStmts -> DeclsAndSelStmts) ; provided labelInSwitchBlock( Label, SwStmts -> true() ); --RC: This rule applies even if there is no default. SelectSwitchStatements_LabelNotFound: getDeclsBeforeDefault( SwStmts -> Decls, SwStmts_1 ) & convertSwitchStatementsToBlock( SwStmts_1 -> SelStmts ) & appendtree( Decls, SelStmts, DeclsAndSelStmts ) -------------------------------- (Label, SwStmts -> DeclsAndSelStmts) ; provided labelInSwitchBlock( Label, SwStmts -> false() ); end selectSwitchStatements; set getDeclsBeforeLabel is --SC: Extracts all declarations from a switch block which occurs before --SC: the given label, less their initializations. Returns the --SC: remaining part of the switch block as well as the declarations in --SC: the form of a Block. judgement (SemExpression, SwitchStatements -> Block, SwitchStatements); GetDeclsBeforeLabel_LabelNotFound: (_, switchStatements[] -> block[], switchStatements[]) ; GetDeclsBeforeLabel_LabelFound: (Label, switchStatements[case(Labels, Block).SwStmts] -> block[], switchStatements[case(Labels, Block).SwStmts]) ; provided labelInLabelGroup( Label, Labels -> true() ); GetDeclsBeforeLabel_RecursiveCase: getDeclsFromBlock( Block -> Decls1 ) & (Label, SwStmts -> Decls2, SwStmts_1) & appendtree( Decls1, Decls2, Decls3 ) -------------------------------- (Label, switchStatements[case(Labels, Block).SwStmts] -> Decls3, SwStmts_1) ; provided labelInLabelGroup( Label, Labels -> false() ); end getDeclsBeforeLabel; set getDeclsBeforeDefault is --SC: Extracts all declarations from a switch block which occurs before --SC: the default label, less their initializations. Returns the --SC: remaining part of the switch block as well as the declarations in --SC: the form of a Block. judgement (SwitchStatements -> Block, SwitchStatements); GetDeclsBeforeDefault_DefaultNotFound: (switchStatements[] -> block[], switchStatements[]) ; GetDeclsBeforeDefault_DefaultFound: (switchStatements[case(Labels, Block).SwStmts] -> block[], switchStatements[case(Labels, Block).SwStmts]) ; provided defaultInLabelGroup( Labels -> true() ); GetDeclsBeforeDefault_RecursiveCase: getDeclsFromBlock( Block -> Decls1 ) & (SwStmts -> Decls2, SwStmts_1) & appendtree( Decls1, Decls2, Decls3 ) -------------------------------- (switchStatements[case(Labels, Block).SwStmts] -> Decls3, SwStmts_1) ; provided defaultInLabelGroup( Labels -> false() ); end getDeclsBeforeDefault; set getDeclsFromBlock is --SC: Extracts and declarationsfrom a block, less initialization --SC: expressions. judgement (Block -> Block); (block[] -> block[]) ; (Stmts -> Decls) -------------------------------- (block[Stmt.Stmts] -> Decls) ; provided not_eq( Stmt, localVariableDeclaration(_, _, _) ); (Stmts -> Decls) & removeInitializers( VarDecls -> VarDecls_1 ) -------------------------------- (block[localVariableDeclaration(OptMod, Type, VarDecls).Stmts] -> block[localVariableDeclaration(OptMod, Type, VarDecls_1).Decls]) ; end getDeclsFromBlock; set removeInitializers is judgement (VariableDeclarators -> VariableDeclarators); RemoveInitializers_BaseCase1: (variableDeclarators[initializedVariable(VarDeclId, _)] -> variableDeclarators[VarDeclId]) ; RemoveInitializers_BaseCase2: (variableDeclarators[VarDecl] -> variableDeclarators[VarDecl]) ; provided not_eq( VarDecl, initializedVariable(_, _) ); RemoveInitializers_RecursiveCase1: (VarDecls -> VarDecls_1) -------------------------------- (variableDeclarators[initializedVariable(VarDeclId, _).VarDecls] -> variableDeclarators[VarDeclId.VarDecls_1]) ; RemoveInitializers_RecursiveCase2: (VarDecls -> VarDecls_1) -------------------------------- (variableDeclarators[VarDecl.VarDecls] -> variableDeclarators[VarDecl.VarDecls_1]) ; provided not_eq( VarDecl, initializedVariable(_, _) ); end removeInitializers; set convertSwitchStatementsToBlock is --SC: Extracts and concatenates all blocks in a sequence of switch --SC: statements. judgement (SwitchStatements -> Block); (switchStatements[] -> block[]) ; (SwStmts -> Block2) & appendtree( Block1, Block2, Block3 ) -------------------------------- (switchStatements[case(_, Block1).SwStmts] -> Block3) ; end convertSwitchStatementsToBlock; set labelInSwitchBlock is --SC: Checks if the label occurs among the labels in SwitchStatements. judgement (SemExpression, SwitchStatements -> Bool); LabelInSwitchBlock_NotFound: (_, switchStatements[] -> false()) ; LabelInSwitchBlock_Found: labelInLabelGroup( Label, Labels -> true() ) -------------------------------- (Label, switchStatements[case(Labels, _)._] -> true()) ; LabelInSwitchBlock_Found: labelInLabelGroup( Label, Labels -> false() ) & (Label, SwitchStatements -> TF) -------------------------------- (Label, switchStatements[case(Labels, _).SwitchStatements] -> TF) ; end labelInSwitchBlock; set labelInLabelGroup is --SC: Predicates which tests for a given label in a group of labels. judgement (SemExpression, SwitchLabels -> Bool); labelInLabelGroup_NotFound: (_, switchLabels[] -> false()) ; labelInLabelGroup_Found: (Label, switchLabels[switchLabel(Label)._] -> true()) ; labelInLabelGroup_RecursiveCase1: (Label1, Labels -> TF) -------------------------------- (Label1, switchLabels[switchLabel(Label2).Labels] -> TF) ; provided diff( Label1, Label2 ); labelInLabelGroup_RecursiveCase2: (Label1, Labels -> TF) -------------------------------- (Label1, switchLabels[default().Labels] -> TF) ; end labelInLabelGroup; set defaultInLabelGroup is --SC: Predicates which tests for a default label in a group of labels. judgement (SwitchLabels -> Bool); defaultInLabelGroup_NotFound: (switchLabels[] -> false()) ; defaultInLabelGroup_Found: (switchLabels[default()._] -> true()) ; defaultInLabelGroup_RecursiveCase: (Labels -> TF) -------------------------------- (switchLabels[Label.Labels] -> TF) ; provided diff( Label, default() ); end defaultInLabelGroup; set convertArgumentListToInsts is --SC: Converts an argument list (i.e. an expression list which may be --SC: empty) into an instruction list. -- judgement (ArgumentList -> Insts); EmptyExpressionList: (arguments[] -> insts[]) ; RecursiveConversionRule: (ExprL -> InstL) -------------------------------- (arguments[Expr.ExprL] -> insts[Expr.InstL]) ; end convertArgumentListToInsts; set unoptOptExpr is --SC: Substitutes the given default expression for none(). -- judgement (OptExpression, Expression -> Expression); NoExpression: (none(), Default -> Default) ; AnExpression: (Expr, _ -> Expr) ; provided diff( Expr, none() ); end unoptOptExpr; end java_stat_execution