-- $Id: java_object_list.ty,v 1.12 10/.0/.2 .1:.1:.3 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_object_list is use java; use PSP; use messargs; import ENVaddCreatedSimpleObjectToStatusList ( ObjectId ) , ENVaddCreatedThreadToStatusList ( ObjectId ) , ENVchangeObjectStatusInStatusList ( ObjectId ) , ENVinitializeStatusAndStackAndExceptionLists ( ) , ENVsendNewObject ( Object ) , ENVsendObjectAndClassVariableLists ( Objects, ClassVariablesL ) , ENVsendObjectList ( Objects ) , ENVupdateThreadStatusList ( ObjectId, ThreadStatus, ThreadStatus ) from java_environment; import getFieldDeclaration ( Objects, OptTypeName, Vals, Bool |- Identifier -> FieldDeclaration, Identifier, Bool ) , getInitialValueForAGivenType ( Type -> Val ) , isAThread ( Object -> Bool ) , isAThread ( OptTypeName => Bool ) , isThisModifierInTheList ( Modifier |- Modifiers -> Bool ) , makeAttributeList ( |- OptTypeName -> Pairs ) from java_inheritance; import appendtree ( _, _, _ ) , diff ( _, _ ) , not_eq ( _, _ ) , succ ( _, _ ) from prolog() ; var TVValue: Val; var TVArrayInit: ArrayInitializer; var TVLocVarDec: LocalVariableDeclaration; var TVStatement: Statement; var TVMethodDecl: MethodDeclarator; set loadClasses is --SC: Retrieves all the class names and their associated class variables --SC: (name/value) contained in the program. Even if a class does --SC: not contain any class variable, it is set in the class variable list. -- --JC: Type declarations contained in the program --JC: -> List containing all the classes and their variables judgement (TypeDeclarations -> ClassVariablesL); --iJC: Type declaration (interface or class) --iJC: => Class variable list judgement (TypeDeclaration => ClassVariablesL); NoMoreTypeDeclaration_EndOfTheLoad: (typeDeclarations[] -> classVariablesL[]) ; RecursiveRuleOnTypeDeclaration: (TDec => ClVarL1) & (TDecL -> ClVarL2) & appendtree( ClVarL1, ClVarL2, ClVarL3 ) -------------------------------- (typeDeclarations[TDec.TDecL] -> ClVarL3) ; InterfaceDeclaration_NotAClass: (interfaceDeclaration(_, _, _, _) => classVariablesL[]) ; ClassDeclaration_GetItsStaticVariables: getStaticVariableList( FDeclL -> ClVarL ) -------------------------------- (classDeclaration(_, ClName, _, _, FDeclL) => classVariablesL[classVariables(ClName, ClVarL)]) ; end loadClasses; set getStaticVariables is --SC: Get the static variables of the given class (this list can be empty) -- --JC: Sought class --JC: |- Class variable list --JC: -> Class variables of the given class judgement OptTypeName |- ClassVariablesL -> Pairs; NoMoreClassVariableInTheList: --RC: This case is normally impossible because each class should be --RC: referenced in this list _ |- classVariablesL[] -> pairs[] ; RecursiveRuleOnClassVariableList: ClName1 |- StaticVarsL -> StaticVarL -------------------------------- ClName1 |- classVariablesL[classVariables(ClName2, _).StaticVarsL] -> StaticVarL ; provided diff( ClName1, ClName2 ); HasFoundTheClassVariablesInTheList: ClName |- classVariablesL[classVariables(ClName, StaticVarL)._] -> StaticVarL ; end getStaticVariables; set getStaticVariableList is --SC: Retrieves all the static variables and their values (if a variable is --SC: not initialized, a default value depending on the variable type is --SC: assigned) contained in a class. -- --JC: Fields contained in a class declaration --JC: -> List of static variable names and their values judgement (FieldDeclarations -> Pairs); --iJC1: Field declaration --iJC1: -> static variable list corresponding to the field declaration judgement (FieldDeclaration => Pairs); --iJC2: The common (part of) the type --iJC2: |- variables declaration --iJC2: => static variable list corresponding to the given variables declara judgement Type |- VariableDeclarators => Pairs; NoMoreFieldDeclarations: (fieldDeclarations[] -> pairs[]) ; RecursiveRuleOnFieldDeclarations: (FDec => ClVarL1) & (FDecL -> ClVarL2) & appendtree( ClVarL1, ClVarL2, ClVarL3 ) -------------------------------- (fieldDeclarations[FDec.FDecL] -> ClVarL3) ; MethodDeclaration_NotAStaticVariable: (methodDeclaration(_, _, _, _, _) => pairs[]) ; ConstructorDeclaration_NotAStaticVariable: (constructorDeclaration(_, _, _, _) => pairs[]) ; StaticVariables: isThisModifierInTheList( static() |- ModL -> true() ) & Type |- StaticVarDecL => StaticPairL -------------------------------- (fieldVariableDeclaration(ModL, Type, StaticVarDecL) => StaticPairL) ; NotStaticVariables: isThisModifierInTheList( static() |- ModL -> false() ) -------------------------------- (fieldVariableDeclaration(ModL, _, _) => pairs[]) ; InitializedStaticVariable: getRealTypeAndName( Type, StaticVarName -> _, RealName ) -------------------------------- Type |- variableDeclarators[initializedVariable(StaticVarName, TVValue)] => pairs[pair(RealName, TVValue)] ; NotInitializedStaticVariable: getRealTypeAndName( Type, StaticVarName -> RealType, RealName ) & getInitialValueForAGivenType( RealType -> Value ) -------------------------------- Type |- variableDeclarators[StaticVarName] => pairs[pair(RealName, Value)] ; InitializedStaticVariable_OtherStaticVariablesToRetrieve: getRealTypeAndName( Type, StaticVarName -> _, RealName ) & Type |- StaticVarDecL => ClVarL -------------------------------- Type |- variableDeclarators[initializedVariable(StaticVarName, TVValue).StaticVarDecL] => pairs[pair(RealName, TVValue).ClVarL] ; NotInitializedStaticVariable_OtherStaticVariablesToRetrieve: getRealTypeAndName( Type, StaticVarName -> RealType, RealName ) & getInitialValueForAGivenType( RealType -> Value ) & Type |- StaticVarDecL => ClVarL -------------------------------- Type |- variableDeclarators[StaticVarName.StaticVarDecL] => pairs[pair(RealName, Value).ClVarL] ; end getStaticVariableList; set getMainThread is --SC: Creates the thread that will execute the main() method (by default, its --SC: class declaration is the first type declaration). --SC: ********************************************************************** --SC: Be careful, the main() method must always be implemented in the first --SC: class of the program --SC: ********************************************************************** -- --JC: |- Program Type Declarations --JC: -> New thread that will execute the main() method judgement |- TypeDeclarations -> Object; CreateTheMainThread: --RC: The main thread has the number zero as reference. createObject( objectId(true(), objectNumber 0) |- objectNumber 0, ClName -> Obj, _ ) -------------------------------- |- typeDeclarations[classDeclaration(_, ClName, _, _, _)._] -> Obj ; do ENVinitializeStatusAndStackAndExceptionLists( ); end getMainThread; set generateANumberForTheNewObject is --SC: Determines the reference of the created object. This reference is the --SC: number of objects in the list before this new object addition. -- --JC: object list --JC: -> object number judgement |- Objects -> ObjectNumber; --iJC: intermediate object number --iJC: |- object list --iJC: => object number judgement integer |- Objects => integer; CountsTheObjects: 0 |- ObjL => ObjectsNumber -------------------------------- |- ObjL -> objectNumber ObjectsNumber ; NoMoreObjectInTheList: ObjectsNumber |- objects[] => ObjectsNumber ; RecursiveRule_CountsTheObjects: n |- ObjL => k & succ( k, m ) -------------------------------- n |- objects[_.ObjL] => m ; end generateANumberForTheNewObject; set createObject is --SC: Create an object depending on its nature (i.e. a simple object or a --SC: thread). -- --JC: Reference of the thread that creates this new object (this reference is --JC: useful in case of thread creation) --JC: |- Generated reference for this new object, Object type --JC: -> new created object, its identifier judgement ObjectId |- ObjectNumber, OptTypeName -> Object, ObjectId; SimpleObjectCreation: isAThread( ClName => false() ) & createSimpleObject( objectId(false(), ObjNb), ClName -> Obj ) -------------------------------- _ |- ObjNb, ClName -> Obj, objectId(false(), ObjNb) ; provided diff( ObjNb, objectNumber 0 ); do ENVsendNewObject( Obj ) & ENVaddCreatedSimpleObjectToStatusList( objectId(false(), ObjNb) ); ThreadCreation: isAThread( ClName => true() ) & createThreadObject( objectId(true(), ObjNb), ClName, OThId -> Obj ) -------------------------------- OThId |- ObjNb, ClName -> Obj, objectId(true(), ObjNb) ; provided diff( ObjNb, objectNumber 0 ); do ENVsendNewObject( Obj ) & ENVaddCreatedThreadToStatusList( objectId(true(), ObjNb) ); MainThreadCreation: --RC: This thread has 0 as number and owns the main() method createThreadObject( objectId(true(), objectNumber 0), ClName -> Obj ) -------------------------------- _ |- objectNumber 0, ClName -> Obj, objectId(true(), objectNumber 0) ; do ENVsendNewObject( Obj ); end createObject; set createSimpleObject is --SC: Creates a simple object (i.e. not a thread) with its attributes. -- --JC: Object identifier, its type --JC: -> created object judgement (ObjectId, OptTypeName -> Object); SimpleObjectCreation_GetAttributeList: makeAttributeList( |- ClName -> AttrL ) -------------------------------- (ObjId, ClName -> object(ObjId, ClName, AttrL, unlocked(), waits[], empty())) ; end createSimpleObject; set createThreadObject is --SC: Creates a thread with its attributes and its closure (if it is the main --SC: thread, this closure is the main() method code, otherwise it is the --SC: run() method code). The new thread status is runnable for the main --SC: thread, otherwise it is created by the given thread. -- --JC1: Identifier for this thread, Its type, Identifier of the thread that --JC1: creates this new thread --JC1: -> New thread judgement (ObjectId, Type, ObjectId -> Object); --JC2: This judgement must only be used for the main thread (that is the --JC2: thread that will execute the main() method) creation. --JC2: Identifier for this thread, Its type --JC2: -> The new main thread judgement (ObjectId, Type -> Object); ThreadCreation: makeAttributeList( |- ClName1 -> AttrL ) & getFieldDeclaration( objects[], ClName1, vals[], false() |- identifier "run" -> FieldDecl, ClName2, true() ) & makeClosure( ClName2, vals[], OThId1 |- FieldDecl -> Clr ) -------------------------------- (OThId1, ClName1, OThId2 -> object(OThId1, ClName1, AttrL, unlocked(), waits[], activity(created(OThId2), Clr))) ; provided diff( OThId1, objectId(true(), objectNumber 0) ); MainThreadCreation: makeAttributeList( |- ClName1 -> AttrL ) & getFieldDeclaration( objects[], ClName1, vals[], false() |- identifier "main" -> FieldDecl, ClName2, true() ) & makeClosure( ClName2, vals[], objectId(true(), objectNumber 0) |- FieldDecl -> clr(_, _, MethName, Env, InstL) ) -------------------------------- (objectId(true(), objectNumber 0), ClName1 -> object( objectId(true(), objectNumber 0), ClName1, AttrL, unlocked(), waits[], activity(runnable(), clr(objectId(true(), objectNumber 0), identifier "none", MethName, Env, InstL)))) ; end createThreadObject; set createExceptionObject is --SC: Creates an instance of an exception and adds it to the object list. -- --JC: Object list (this list contains all the objects created by the program --JC: interpretation), current executing thread id --JC: |- exception class name, exception text --JC: -> new exception object id, modified object list (the new --JC: exception object has been appended), next instructions to execute --JC: (constructor call of the exception + except statment) judgement Objects, ObjectId |- Identifier, ExceptText -> ObjectId, Objects, Insts; --JC: ^, ^ |- ^, ^, id of the object that has thrown this exception, --JC: name of the method where the exception occured -> ^, ^, ^ --JC: (ie constructor call of the exception + exception statement) judgement Objects, ObjectId |- Identifier, ExceptText, ObjectId, Identifier -> ObjectId, Objects, Insts; --JC: ^ (only useful to generate the exception object id), ^ --JC: |- ^, ^ => ^, exception object, ^ (ie constructor call of the exception --JC: + except statement) judgement Objects, ObjectId |- Identifier, ExceptText => ObjectId, Object, Insts; --JC: ^, ^ |- ^, ^, ^, ^ => ^, ^, ^ --JC: (ie constructor call of the exception + exception statement) judgement Objects, ObjectId |- Identifier, ExceptText, ObjectId, Identifier => ObjectId, Object, Insts; CreateAnExceptionObject_AddItToObjectList: ObjL1, OThId |- ExceptName, Text => ExObjId, ExObj, Insts & appendtree( ObjL1, objects[ExObj], ObjL1_1 ) -------------------------------- ObjL1, OThId |- ExceptName, Text -> ExObjId, ObjL1_1, Insts ; CreateExceptionObject_ReturnItAndExcept: generateANumberForTheNewObject( |- ObjL1 -> i ) & createObject( OThId |- i, ExceptName -> ExObj, ExObjId ) -------------------------------- ObjL1, OThId |- ExceptName, Text => ExObjId, ExObj, insts[constructorCall1(ExceptName, arguments[], ExObjId), except(ExceptName, ExObjId, Text)] ; CreateAnExceptionObject_AddItToObjectList: ObjL1, OThId |- ExceptName, Text, ObjId, MethodName => ExObjId, ExObj, Insts & appendtree( ObjL1, objects[ExObj], ObjL1_1 ) -------------------------------- ObjL1, OThId |- ExceptName, Text, ObjId, MethodName -> ExObjId, ObjL1_1, Insts ; CreateExceptionObject_ReturnItAndExcept: generateANumberForTheNewObject( |- ObjL1 -> i ) & createObject( OThId |- i, ExceptName -> ExObj, ExObjId ) -------------------------------- ObjL1, OThId |- ExceptName, Text, ObjId, MethodName => ExObjId, ExObj, insts[constructorCall1(ExceptName, arguments[], ExObjId), exception(OThId, ObjId, MethodName, except(ExceptName, ExObjId, Text))] ; end createExceptionObject; set getObjectLockInformation is --SC: Returns how many times the given object is locked and by which thread. -- --JC: The object reference for which the lock information is required --JC: |- objects --JC: -> The reference of the thread that has locked the object, --JC: lock(s) number judgement ObjectId |- Objects -> ObjectId, integer; LockedObject: getObject( ObjId |- ObjL -> object(ObjId, _, _, locked(OThId, integer nbLocks), _, _) ) -------------------------------- ObjId |- ObjL -> OThId, nbLocks ; UnlockedObject: getObject( ObjId |- ObjL -> object(ObjId, _, _, unlocked(), _, _) ) -------------------------------- ObjId |- ObjL -> _, 0 ; end getObjectLockInformation; set getThreadCurrentMethod is --SC: Returns the given thread current method name (gets the continuation --SC: and passes through all the closures to find the most inner one (only --SC: the first instruction is checked)). -- --JC1: Thread reference --JC1: |- Objects --JC1: -> Current method name judgement ObjectId |- Objects -> Identifier; --JC2: Thread reference --JC2: |- Objects --JC2: => first instruction judgement ObjectId |- Objects => Inst; --iJC1: |- Closure --iJC1: -> Current method name, current instruction judgement |- Clr -> Identifier, Inst; --iJC2: |- Instruction --iJC2: => Current method name or undefined, current instruction, True if the instruction contains --iJC2: a closure/ False otherwise judgement |- Inst => Identifier, Inst, Bool; GetTheThreadContinuation: |- Cont -> MethName, Inst -------------------------------- OThId |- objects[object(OThId, _, _, _, _, activity(_, Cont))._] -> MethName ; SeekTheGivenThread: OThId |- ObjL -> MethName -------------------------------- OThId |- objects[object(ObjId, _, _, _, _, _).ObjL] -> MethName ; provided diff( ObjId, OThId ); GetTheThreadContinuation: |- Cont -> _, Inst -------------------------------- OThId |- objects[object(OThId, _, _, _, _, activity(_, Cont))._] => Inst ; SeekTheGivenThread: OThId |- ObjL -> Inst -------------------------------- OThId |- objects[object(ObjId, _, _, _, _, _).ObjL] => Inst ; provided diff( ObjId, OThId ); BlockIntoAClosure_FindTheMethodNameInTheBlockInstL: |- semBlock(insts[Inst1.InstL], Env) => MethName, Inst2, true() -------------------------------- |- clr(_, _, _, _, insts[semBlock(insts[Inst1.InstL], Env)._]) -> MethName, Inst2 ; BlockIntoAClosure_NoMoreMethod_SoTheCurrentMethodIsThisOne: --RC: No more closure => no more method. So the current method is the one --RC: we are looking for. |- semBlock(insts[Inst.InstL], Env) => _, _, false() -------------------------------- |- clr(_, _, MethName, _, insts[semBlock(insts[Inst.InstL], Env)._]) -> MethName, Inst ; ClosureIntoAClosure_FindTheMethodNameInTheClosure: |- clr(ObjId, Mode, MethName1, Env, InstL) -> MethName2, Inst -------------------------------- |- clr(_, _, _, _, insts[clr(ObjId, Mode, MethName1, Env, InstL)._]) -> MethName2, Inst ; NoMoreInstructionInTheCurrentClosure_TheCurrentMethodIsThisOne: |- clr(_, _, MethName, _, insts[]) -> MethName, _ ; NoMoreClosureInTheCurrentClosure_TheCurrentMethodIsThisOne: |- clr(_, _, MethName, _, insts[Inst._]) -> MethName, Inst ; provided not_eq( Inst, clr(_, _, _, _, _) ) & not_eq( Inst, semBlock(_, _) ); NoMoreInstructionInTheCurrentBlock_NoMoreMethod: |- semBlock(insts[], _) => _, _, false() ; BlockIntoTheCurrentBlock_LookForTheMethodName: |- semBlock(InstL, Env) => MethName, Inst, TF -------------------------------- |- semBlock(insts[semBlock(InstL, Env)._], _) => MethName, Inst, TF ; ClosureIntoTheBlock_FindTheMethodNameInTheClosure: |- clr(ObjId, Mode, MethName1, Env, InstL) -> MethName2, Inst -------------------------------- |- semBlock(insts[clr(ObjId, Mode, MethName1, Env, InstL)._], _) => MethName2, Inst, true() ; NoMoreClosureInTheCurrentBlock_NoMoreMethod: |- semBlock(insts[Inst._], _) => _, Inst, false() ; provided not_eq( Inst, clr(_, _, _, _, _) ) & not_eq( Inst, semBlock(_, _) ); end getThreadCurrentMethod; set getObjectType is --SC: Returns the given object type. -- --JC: Object reference --JC: |- Objects --JC: -> Type of the given object judgement ObjectId |- Objects -> Type; GetObjectType: getObject( ObjId |- ObjL -> object(ObjId, Type, _, _, _, _) ) -------------------------------- ObjId |- ObjL -> Type ; end getObjectType; set isTheObjectLocked is --SC: Checks if the given object is locked or not. -- --JC: Object reference --JC: |- Objects --JC: -> True/False judgement ObjectId |- Objects -> Bool; --iJC: Locks number --iJC: -> True/False judgement (integer -> Bool); getObjectLockInfo: getObjectLockInformation( ObjId |- ObjL -> _, NbLocks ) & (NbLocks -> TF) -------------------------------- ObjId |- ObjL -> TF ; NoLock: (0 -> false()) ; Lock: (NbLocks -> true()) ; provided diff( NbLocks, 0 ); end isTheObjectLocked; set areAllThreadsDead is --SC: Checks that all threads are "dead". -- --JC: Objects --JC: -> True if all the threads are dead/False otherwise judgement (Objects -> Bool); NoAliveThread: (objects[] -> true()) ; AtLeastOneAliveThread: isAThread( Obj -> true() ) & isTheThreadDead( Obj -> false() ) -------------------------------- (objects[Obj._] -> false()) ; NotAThread_RecursiveRule: isAThread( Obj -> false() ) & (ObjL -> TF) -------------------------------- (objects[Obj.ObjL] -> TF) ; NotAnAliveThread_RecursiveRule: isAThread( Obj -> true() ) & isTheThreadDead( Obj -> true() ) & (ObjL -> TF) -------------------------------- (objects[Obj.ObjL] -> TF) ; end areAllThreadsDead; set isTheThreadDead is --SC: Determines if the given thread is "dead" or not. -- --JC: Thread --JC: -> True if dead/ False if alive judgement (Object -> Bool); AliveThread: (object(_, _, _, _, _, activity(ThStatus, _)) -> false()) ; provided diff( ThStatus, dead() ); DeadThread: (object(_, _, _, _, _, activity(dead(), _)) -> true()) ; end isTheThreadDead; set releaseObjectLock is --SC : Removes a lock on an object. -- --JC: Locked object reference --JC: |- Objects --JC: -> Updated object list judgement ObjectId |- Objects -> Objects; FindTheObject_RemoveTheLock: ObjId |- objects[object(ObjId, ClName, AttrL, locked(_, integer 1), Wait_L, Activity).ObjL] -> objects[object(ObjId, ClName, AttrL, unlocked(), Wait_L, Activity).ObjL] ; LookForTheObject: ObjId1 |- ObjL1 -> ObjL1_1 -------------------------------- ObjId1 |- objects[object(ObjId2, ClName2, AttrL2, Locked2, Wait_L2, Activity2).ObjL1] -> objects[object(ObjId2, ClName2, AttrL2, Locked2, Wait_L2, Activity2).ObjL1_1] ; provided diff( ObjId1, ObjId2 ); end releaseObjectLock; set getNumberOfDormantAndBlockedThreadsOnTheGivenObject is --SC: Computes the number of threads "blocked" and "dormant", waiting for a --SC: lock on the given object. -- --JC: Object reference --JC: |- Objects --JC: -> number of threads dormant and blocked on the given object judgement ObjectId |- Objects -> integer, integer; --iJC: intermediate number of threads dormant or blocked on the given object --iJC: |- Objects, Sought object reference --iJC: -> Number of dormant and blocked threads on the given object judgement integer, integer |- Objects, ObjectId -> integer, integer; EntryPoint: 0, 0 |- ObjL, OjbId -> nbDormantThread, nbBlockedThread -------------------------------- OjbId |- ObjL -> nbDormantThread, nbBlockedThread ; NoMoreObject: nbDormantThread, nbBlockedThread |- objects[], _ -> nbDormantThread, nbBlockedThread ; BlockedThreadOnTheGivenObject_RecursiveRule: succ( nbBlockedThread1, nbBlockedThread1_1 ) & nbDormantThread1, nbBlockedThread1_1 |- ObjL, OjbId -> nbDormantThread1_1, nbBlockedThread1_2 -------------------------------- nbDormantThread1, nbBlockedThread1 |- objects[object(_, _, _, _, _, activity(blocked(OjbId), _)).ObjL], OjbId -> nbDormantThread1_1, nbBlockedThread1_2 ; DormantThreadOnTheGivenObject_RecursiveRule: succ( nbDormantThread1, nbDormantThread1_1 ) & nbDormantThread1_1, nbBlockedThread1 |- ObjL, OjbId -> nbDormantThread1_2, nbBlockedThread1_1 -------------------------------- nbDormantThread1, nbBlockedThread1 |- objects[object(_, _, _, _, _, activity(dormant(OjbId, _), _)).ObjL], OjbId -> nbDormantThread1_2, nbBlockedThread1_1 ; NotADormantOrBlockedThread_RecursiveRule: nbDormantThread1, nbBlockedThread1 |- ObjL, OjbId -> nbDormantThread1_1, nbBlockedThread1_1 -------------------------------- nbDormantThread1, nbBlockedThread1 |- objects[object(_, _, _, _, _, activity(ThStatus, _)).ObjL], OjbId -> nbDormantThread1_1, nbBlockedThread1_1 ; provided not_eq( ThStatus, blocked(OjbId) ) & not_eq( ThStatus, dormant(OjbId, _) ); SimpleObject_CanNotBeBlockedOrDormant: nbDormantThread1, nbBlockedThread1 |- ObjL, OjbId -> nbDormantThread1_1, nbBlockedThread1_1 -------------------------------- nbDormantThread1, nbBlockedThread1 |- objects[object(_, _, _, _, _, empty()).ObjL], OjbId -> nbDormantThread1_1, nbBlockedThread1_1 ; end getNumberOfDormantAndBlockedThreadsOnTheGivenObject; set setLock is --SC: Sets a lock on the given object. (this set should be used only if the --SC: object does not have any lock or if it is already locked by the given --SC: thread (in this case the lock value is higher than 1)) -- --JC: Object reference on which the lock must be set, --JC: Thread reference (i.e. the owner of the lock), --JC: the number of times that the thread locked this object --JC: |- Objects --JC: -> modified object list judgement ObjectId, ObjectId, Val |- Objects -> Objects; --iJC: (same judgements. The first one is used for the env) judgement ObjectId, ObjectId, Val |- Objects => Objects; EntryPoint_SendInfoToEnv: ObjId, OThId, LocValue |- ObjL1 => ObjL1_1 -------------------------------- ObjId, OThId, LocValue |- ObjL1 -> ObjL1_1 ; do ENVsendObjectList( ObjL1_1 ); setLock: ObjId, OThId, LocValue |- objects[object(ObjId, ClName, AttrL, unlocked(), WaitSet, Act).ObjL] => objects[object(ObjId, ClName, AttrL, locked(OThId, LocValue), WaitSet, Act).ObjL] ; do ENVchangeObjectStatusInStatusList( ObjId ); setNewLockValue_WhenItIsAlreadyLockedByThisSameObject: ObjId, OThId, LocValue |- objects[object(ObjId, ClName, AttrL, locked(OThId, _), WaitSet, Act).ObjL] => objects[object(ObjId, ClName, AttrL, locked(OThId, LocValue), WaitSet, Act).ObjL] ; LookForTheObject: ObjId1, OThId, LocValue |- ObjL1 => ObjL1_1 -------------------------------- ObjId1, OThId, LocValue |- objects[object(ObjId2, ClName, AttrL, Lock, WaitSet, Act).ObjL1] => objects[object(ObjId2, ClName, AttrL, Lock, WaitSet, Act).ObjL1_1] ; provided diff( ObjId1, ObjId2 ); end setLock; set setNewClosure is --SC: sets the new closure in the activity of the given thread. -- --JC: Thread reference that will have this new closure, the new closure, --JC: class variables (only used for the environment) --JC: |- objects --JC: -> modified object list judgement ObjectId, Clr, ClassVariablesL |- Objects -> Objects; --JC: (same as the previous one without the class variables) judgement ObjectId, Clr |- Objects -> Objects; EntryPoint_SendInfoToEnv: OThId, Clr |- ObjL1 -> ObjL1_1 -------------------------------- OThId, Clr, ClVarL |- ObjL1 -> ObjL1_1 ; do ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ); SetTheNewClosureToTheGivenThread: OThId, Clr |- objects[object(OThId, ClName, AttrL, Lock, WaitSet, activity(ThStatus, _)).ObjL] -> objects[object(OThId, ClName, AttrL, Lock, WaitSet, activity(ThStatus, Clr)).ObjL] ; LookForTheGivenThread: OThId, Clr1 |- ObjL1 -> ObjL1_1 -------------------------------- OThId, Clr1 |- objects[object(ObjId, ClName, AttrL, Lock, WaitSet, Act).ObjL1] -> objects[object(ObjId, ClName, AttrL, Lock, WaitSet, Act).ObjL1_1] ; provided diff( OThId, ObjId ); end setNewClosure; set setNewThreadStatus is --SC: sets the new status to the given thread. -- --JC: Thread reference that will have the new status, the new status, --JC: class variables (only used for the environment) --JC: |- objects --JC: -> modified object list judgement ObjectId, ThreadStatus, ClassVariablesL |- Objects -> Objects; --iJC: (same as above without the class variables) judgement ObjectId, ThreadStatus, Objects |- Objects => Objects; EntryPoint_SendInfoToEnv: OThId, ThStatus, ObjL1 |- ObjL1 => ObjL1_1 -------------------------------- OThId, ThStatus, ClVarL |- ObjL1 -> ObjL1_1 ; do ENVsendObjectList( ObjL1_1 ) & ENVsendObjectAndClassVariableLists( ObjL1_1, ClVarL ); SetNewStatusToTheGivenThread: OThId, NewThStatus, _ |- objects[object(OThId, ClName, AttrL, Lock, WaitSet, activity(OldThStatus, Clr)).ObjL] => objects[object(OThId, ClName, AttrL, Lock, WaitSet, activity(NewThStatus, Clr)).ObjL] ; do ENVupdateThreadStatusList( OThId, OldThStatus, NewThStatus ); LookForTheGivenThread: OThId, ThStatus, ObjL |- ObjL1 => ObjL1_1 -------------------------------- OThId, ThStatus, ObjL |- objects[object(ObjId, ClName, AttrL, Lock, WaitSet, Act).ObjL1] => objects[object(ObjId, ClName, AttrL, Lock, WaitSet, Act).ObjL1_1] ; provided diff( OThId, ObjId ); end setNewThreadStatus; set getObject is --SC: gets the object specified by its reference -- --JC: Sought object reference --JC: |- Objects --JC: -> the wanted object judgement ObjectId |- Objects -> Object; HasFoundTheObject: ObjId |- objects[object(ObjId, ClName, AttrL, Lock, WaitSet, Act)._] -> object(ObjId, ClName, AttrL, Lock, WaitSet, Act) ; LookForTheObject: ObjId1 |- ObjL -> Obj -------------------------------- ObjId1 |- objects[object(ObjId2, _, _, _, _, _).ObjL] -> Obj ; provided diff( ObjId1, ObjId2 ); end getObject; set makeClosure is --SC: Makes the closure corresponding to the method call. A synchronized --SC: instruction is added if the method has the "synchronized" modifier in --SC: its declaration. A Closure is composed of the reference of the object --SC: on which the method is executed, the method name, if it is a static or --SC: non static method, the parameters name and value list, the environment --SC: (i.e. the parameters and the local variables of the method body) and --SC: the method instructions -- --JC: Class name of the object that has called this method, Parameter values, --JC: Reference of the object that has invoked this method --JC: |- Method declaration --JC: -> Closure for this method judgement OptTypeName, Vals, ObjectId |- FieldDeclaration -> Clr; SynchronizedMethod: --RC: Gets the closure for this synchronized method (the instruction list --RC: contains a synchro_ref instruction as first instruction followed by --RC: the instructions of the method body) isThisModifierInTheList( synchronized() |- ModL -> true() ) & getMethodNameAndParameters( TVMethodDecl -> MethName, ParamL ) & makeBindedParamList( ParamValueL |- ParamL -> BindParamL ) & getModeAndTargetClass( ClName |- ModL -> _, TargetClName ) & getInstructionsAndLocalVariables( insts[], locs[pairs[]] |- MBlock => InstL, LocVarL ) -------------------------------- ClName, ParamValueL, ObjId |- methodDeclaration(ModL, _, TVMethodDecl, _, MBlock) -> clr( ObjId, TargetClName, MethName, env(BindParamL, LocVarL), insts[synchroLock(ObjId, semBlock(InstL, blockEnv(BindParamL, LocVarL, pairs[])))]) ; NonSynchronizedMethod: --RC: Gets the closure for this non synchronized method isThisModifierInTheList( synchronized() |- ModL -> false() ) & getMethodNameAndParameters( TVMethodDecl -> MethName, ParamL ) & makeBindedParamList( ParamValueL |- ParamL -> BindParamL ) & getModeAndTargetClass( ClName |- ModL -> _, TargetClName ) & getInstructionsAndLocalVariables( insts[], locs[pairs[]] |- MBlock => InstL, LocVarL ) -------------------------------- ClName, ParamValueL, ObjId |- methodDeclaration(ModL, _, TVMethodDecl, _, MBlock) -> clr(ObjId, TargetClName, MethName, env(BindParamL, LocVarL), InstL) ; end makeClosure; set getInstructionsAndLocalVariables is --SC: Gets all the instructions and local variables contained in the given --SC: block. -- --JC1: Instructions, Local variables --JC1: |- Block to analyse --JC1: => Increased instruction list, Increased local --JC1: variable list judgement Insts, Locs |- Block => Insts, Locs; --JC2: Instructions, Local variables --JC2: |- Block Statement (i.e. a statement or a local variable declaration) --JC2: => Increased instruction list, Increased local variable list judgement Insts, Locs |- BlockStatement -> Insts, Locs; NoMoreElementInTheBlock: InstL, LocVarL |- block[] => InstL, LocVarL ; BlockWithABlockAsFirstInstruction: --RC: Treats the next elements of the block --RC: (the first block is not analyse) InstL1, LocVarL1 |- BlElemL2 => InstL1_1, LocVarL1_1 & appendtree( insts[block[BlElem1.BlElemL1]], InstL1_1, InstL1_2 ) -------------------------------- InstL1, LocVarL1 |- block[block[BlElem1.BlElemL1].BlElemL2] => InstL1_2, LocVarL1_1 ; BlockWithoutABlockAsFirstInstruction: --RC: Treats the first statement and goes on --RC: with the next elements of the block InstL1, LocVarL1 |- BlElem -> InstL1_1, LocVarL1_1 & InstL1_1, LocVarL1_1 |- BlElemL => InstL1_2, LocVarL1_2 -------------------------------- InstL1, LocVarL1 |- block[BlElem.BlElemL] => InstL1_2, LocVarL1_2 ; provided not_eq( BlElem, block[_] ); LocalVariableDeclaration_AddLocalVariableAndInstruction: addToLocalVariableList( LocVarL1 |- TVLocVarDec -> LocVarL1_1, InstL2 ) & appendtree( InstL1, InstL2, InstL3 ) -------------------------------- InstL1, locs[LocVarL1.LocVarLL] |- TVLocVarDec -> InstL3, locs[LocVarL1_1.LocVarLL] ; Statement_AddItToTheInstructionList: appendtree( InstL1, insts[TVStatement], InstL1_1 ) -------------------------------- InstL1, LocVarL |- TVStatement -> InstL1_1, LocVarL ; end getInstructionsAndLocalVariables; set getModeAndTargetClass is --SC: Gets the mode ("static", "nonvirtual" or "virtual") and the target --SC: (the given class name if it is a static method or "none" otherwise) -- --JC: Class Name --JC: |- Method modifiers --JC: -> Mode ("static", "nonvirtual" or "virtual"), the target judgement OptTypeName |- Modifiers -> Identifier, Identifier; Static: isThisModifierInTheList( static() |- ModL -> true() ) -------------------------------- ClName |- ModL -> identifier "static", ClName ; Private: isThisModifierInTheList( private() |- ModL -> true() ) -------------------------------- _ |- ModL -> identifier "nonvirtual", identifier "none" ; Other: _ |- _ -> identifier "virtual", identifier "none" ; end getModeAndTargetClass; set makeBindedParamList is --SC: Build a list that contains all the parameter names and their associated --SC: values. -- --JC: Parameter values --JC: |- Parameter declaration --JC: -> parameter (name/value) list judgement Vals |- Parameters -> Pairs; NoMoreValue: vals[] |- _ -> pairs[] ; RecursiveRule: getRealTypeAndName( Type, VarDeclId -> _, RealName ) & ValueL |- ParamDecL -> ParamL -------------------------------- vals[Value.ValueL] |- parameters[parameter(_, Type, VarDeclId).ParamDecL] -> pairs[pair(RealName, Value).ParamL] ; end makeBindedParamList; set addToLocalVariableList is --SC: Adds a/many new local variables to the local variable list. A local --SC: variable has no value (i.e. "empty()") if it is not initialized or it --SC: has been initialized with an expression that needs to be evaluated --SC: before the assignment (in this case, an instruction needs to be added --SC: at the top of the instruction list). -- --JC: Existing local variables --JC: |- a local variable declaration --JC: -> Increased local variable list, Instruction that needs to be executed --JC: to evaluate an expression judgement Pairs |- LocalVariableDeclaration -> Pairs, Insts; --iJC: type, initial Value |- variable declarator --iJC: => local variable list, Instruction that needs to be executed to --iJC: evaluate an expression judgement Type, Val |- VariableDeclarators => Pairs, Insts; EntryPoint_LocalVariablesDeclaration_PrimitiveType: Type, empty() |- LocVarNameL => LocVarL2, InstL & appendtree( LocVarL1, LocVarL2, LocVarL3 ) -------------------------------- LocVarL1 |- localVariableDeclaration(_, Type, LocVarNameL) -> LocVarL3, InstL ; InitializedVariableWithAValue_AddToLocalVariableList: getRealTypeAndName( Type, VarDeclId -> _, Name ) -------------------------------- Type, _ |- variableDeclarators[initializedVariable(VarDeclId, TVValue)] => pairs[pair(Name, TVValue)], insts[] ; InitializedVariableWithAnArrayInitializer_AddToInstrAndLocalVariableLists: --RC: Local variables do not have default values getRealTypeAndName( Type, VarDeclId -> RealType, Name ) & getElementTypeAndNDims( RealType -> ElementType, NDims ) -------------------------------- Type, Value |- variableDeclarators[initializedVariable(VarDeclId, TVArrayInit)] => pairs[pair(Name, Value)], insts[binaryAssign(Name, assignment(), newArray(ElementType, dims[], NDims, TVArrayInit))] ; InitializedVariableWithAnExpression_AddToInstrAndLocalVariableLists: --RC: Local variables do not have default values getRealTypeAndName( Type, VarDeclId -> _, Name ) -------------------------------- Type, Value |- variableDeclarators[initializedVariable(VarDeclId, Expr)] => pairs[pair(Name, Value)], insts[binaryAssign(Name, assignment(), Expr)] ; NonInitializedVariable: getRealTypeAndName( Type, VarDeclId -> _, Name ) -------------------------------- Type, Value |- variableDeclarators[VarDeclId] => pairs[pair(Name, Value)], insts[] ; provided not_eq( initializedVariable(_, _), Name ); RecursiveRule: Type, Value |- variableDeclarators[VarDecl] => LocVarL1, InstL1 & Type, Value |- VarDeclL => LocVarL2, InstL2 & appendtree( LocVarL1, LocVarL2, LocVarL3 ) & appendtree( InstL1, InstL2, InstL3 ) -------------------------------- Type, Value |- variableDeclarators[VarDecl.VarDeclL] => LocVarL3, InstL3 ; set getElementTypeAndNDims is judgement (Type -> Type, Dims); GetElementTypeAndNdims_BaseCase: (Type -> Type, dims[]) ; provided not_eq( Type, arrayof(_) ); GetElementTypeAndNDims_Recurse: (Type -> ElementType, NDims) -------------------------------- (arrayof(Type) -> ElementType, dims[dim().NDims]) ; end getElementTypeAndNDims ; end addToLocalVariableList; set getRealTypeAndName is --SC: Computes the real type and name of a parameter, variable, etc. --SC: given a type and a variable declarator id. judgement (Type, VariableDeclaratorId -> Type, Identifier); GetRealTypeAndName_BaseCase: (Type, identifier i -> Type, identifier i) ; GetRealTypeAndName_Recurse: (arrayof(Type), VarDeclId -> RealType, Name) -------------------------------- (Type, array(VarDeclId) -> RealType, Name) ; end getRealTypeAndName; set getRealName is --SC: Computes the real name of a parameter, variable, etc. --SC: given a variable declarator id. judgement (VariableDeclaratorId -> Identifier); GetRealName_BaseCase: (identifier i -> identifier i) ; GetRealName_Recurse: (VarDeclId -> Name) -------------------------------- (array(VarDeclId) -> Name) ; end getRealName; set getMethodNameAndParameters is --SC: Extracts the name of a method and the parameter list. --SC: The real return type could also be computed here, in the same --SC: fashion as for getRealTypeAndName, but currently the return type --SC: does not seem to be used. judgement (MethodDeclarator -> Identifier, Parameters); getMethodNameAndParameters_BaseCase: (methodDeclarator(Name, Params) -> Name, Params) ; getMethodNameAndParameters_Recurse: (mtdDecl -> Name, Params) -------------------------------- (arrayMethodDeclarator(mtdDecl) -> Name, Params) ; end getMethodNameAndParameters; end java_object_list