LazyMethod.st
author claus
Tue, 02 May 1995 01:04:40 +0200
changeset 84 ecb74f0507fd
parent 83 10c73a059351
child 88 202c3b1fbc0b
permissions -rw-r--r--
.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     1
"
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     2
 COPYRIGHT (c) 1994 by Claus Gittinger
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
     3
	      All Rights Reserved
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     4
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     5
 This software is furnished under a license and may be used
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     6
 only in accordance with the terms of that license and with the
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     7
 inclusion of the above copyright notice.   This software may not
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     8
 be provided or otherwise made available to, or used by, any
343ca93df0e0 Initial revision
claus
parents:
diff changeset
     9
 other person.  No title to or ownership of the software is
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    10
 hereby transferred.
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    11
"
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    12
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    13
Method subclass:#LazyMethod
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    14
	 instanceVariableNames:''
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    15
	 classVariableNames:'Access CompilationFailedSignal'
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    16
	 poolDictionaries:''
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    17
	 category:'Kernel-Methods'
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    18
!
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    19
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    20
LazyMethod comment:'
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    21
COPYRIGHT (c) 1994 by Claus Gittinger
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    22
	      All Rights Reserved
27
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    23
84
claus
parents: 83
diff changeset
    24
$Header: /cvs/stx/stx/libcomp/LazyMethod.st,v 1.9 1995-05-01 23:04:00 claus Exp $
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    25
'!
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    26
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    27
!LazyMethod class methodsFor:'documentation'!
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    28
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    29
copyright
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    30
"
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    31
 COPYRIGHT (c) 1994 by Claus Gittinger
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    32
	      All Rights Reserved
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    33
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    34
 This software is furnished under a license and may be used
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    35
 only in accordance with the terms of that license and with the
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    36
 inclusion of the above copyright notice.   This software may not
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    37
 be provided or otherwise made available to, or used by, any
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    38
 other person.  No title to or ownership of the software is
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    39
 hereby transferred.
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    40
"
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    41
!
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    42
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    43
version
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    44
"
84
claus
parents: 83
diff changeset
    45
$Header: /cvs/stx/stx/libcomp/LazyMethod.st,v 1.9 1995-05-01 23:04:00 claus Exp $
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    46
"
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    47
!
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    48
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    49
documentation
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    50
"
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    51
    Instances of LazyMethod are created when doing a lazy autoload.
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    52
    They do not contain any code (neither byte- nor machinecode), but
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    53
    keep their sourcecode only.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    54
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    55
    When executed, these will trigger an error in the VM (noByteCode),
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    56
    which is cought here to create a real method from the receiver,
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    57
    amd re-execute the method.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    58
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    59
    This allows faster loading of code, which will be later compiled
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    60
    when first executed; for classes with a large number of methods, of
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    61
    which only a small subset is actually used, this can also save
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    62
    lots of memory (beside making autoloading faster).
20
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    63
"
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    64
! !
f8dd8ba75205 *** empty log message ***
claus
parents: 18
diff changeset
    65
40
45ecd4441edb compilation is donw in critical region - it was not reentrant
claus
parents: 27
diff changeset
    66
!LazyMethod class methodsFor:'initialization'!
45ecd4441edb compilation is donw in critical region - it was not reentrant
claus
parents: 27
diff changeset
    67
45ecd4441edb compilation is donw in critical region - it was not reentrant
claus
parents: 27
diff changeset
    68
initialize
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    69
    CompilationFailedSignal isNil ifTrue:[
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    70
	CompilationFailedSignal := ExecutionErrorSignal newSignalMayProceed:true.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    71
	CompilationFailedSignal nameClass:self message:#compilationFailedSignal.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    72
	CompilationFailedSignal notifierString:'compilation of lazy method failed'.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    73
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    74
	Access := Semaphore forMutualExclusion.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    75
    ]
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    76
! !
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    77
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    78
!LazyMethod class methodsFor:'signal access'!
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    79
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    80
compilationFailedSignal
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
    81
    ^ CompilationFailedSignal
40
45ecd4441edb compilation is donw in critical region - it was not reentrant
claus
parents: 27
diff changeset
    82
! !
45ecd4441edb compilation is donw in critical region - it was not reentrant
claus
parents: 27
diff changeset
    83
27
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    84
!LazyMethod methodsFor:'queries'!
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    85
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    86
isLazyMethod
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    87
    ^ true
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    88
! !
7e2b3ab54d7c *** empty log message ***
claus
parents: 20
diff changeset
    89
54
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
    90
!LazyMethod methodsFor:'compiling'!
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    91
54
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
    92
makeRealMethod
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
    93
    "make the receiver a real method; i.e. compile the sourcecode and
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
    94
     fill in the bytecode. This must be done in order to execute the receiver."
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    95
54
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
    96
    |m|
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    97
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    98
    "compile the method"
343ca93df0e0 Initial revision
claus
parents:
diff changeset
    99
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   100
    "we have to sequentialize this using a lock-semaphore,
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   101
     to make sure only one method is compiled at a time.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   102
     Otherwise, we might get into trouble, if (due to a timeout)
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   103
     another recompile is forced while compiling this one ...
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   104
     (happened when autoloading animation demos)
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   105
    "
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
   106
    [
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   107
	Access wait.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   108
	[
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   109
	    m := self asByteCodeMethod.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   110
	] valueNowOrOnUnwindDo:[
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   111
	    Access signal.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   112
	].
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   113
    ] valueUninterruptably.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   114
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   115
    (m isNil or:[(byteCode := m byteCode) isNil]) ifTrue:[
47
f861ad42703e *** empty log message ***
claus
parents: 45
diff changeset
   116
	"
f861ad42703e *** empty log message ***
claus
parents: 45
diff changeset
   117
	 compilation failed
f861ad42703e *** empty log message ***
claus
parents: 45
diff changeset
   118
	"
54
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   119
	^ nil
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   120
    ].
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   121
    literals := m literals.
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   122
    flags := m flags.
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   123
    self changeClassToThatOf:m.
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   124
    ^ self
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   125
! !
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   126
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   127
!LazyMethod methodsFor:'error handling'!
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   128
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   129
noByteCode 
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   130
    "this is triggered by the interpreter when a lazy method is about to 
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   131
     be executed (by sending the to-be executed  method this message).
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   132
     Hard-compile the method, install its bytecode in the receiver,
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   133
     and recall it."
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   134
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   135
    |sender spec class selector|
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   136
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   137
    "compile the method"
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   138
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   139
    self makeRealMethod isNil ifTrue:[
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   140
	"
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   141
	 compilation failed
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   142
	"
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   143
	selector := thisContext sender selector.
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   144
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   145
	class := self containingClass.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   146
	class notNil ifTrue:[
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   147
	    spec := class name , '>>' , selector
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   148
	] ifFalse:[
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   149
	    spec := 'unknown>>' , selector
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   150
	].
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   151
	"
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   152
	 this error is triggered, if the compilation of a lazy method
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   153
	 failed - this happens for example, if a lazy methods code has been
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   154
	 changed in a fileBrowser without checking the code for syntactical
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   155
	 correctnes, or if the instvars of an autoloaded classes superclass 
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   156
	 have been changed without changing the subclasses code ...
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   157
	 You should enter the SystemBrowser on this method, and try accepting 
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   158
	 to see what the problem is.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   159
	 The methods class is found in the local 'class',
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   160
	 the selector is found in the local 'selector'.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   161
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   162
	 As a general rule: never edit autoloaded classes from anything
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   163
	 except the browser - to check that they work and are compilable.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   164
	"
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   165
	^ CompilationFailedSignal raiseRequestWith:self
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   166
				  errorString:('compilation of lazy method ' , spec , ' failed')
40
45ecd4441edb compilation is donw in critical region - it was not reentrant
claus
parents: 27
diff changeset
   167
    ].
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   168
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   169
    "
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   170
     Now, the receiver method has mutated into a real (non-lazy) one.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   171
     Get the original message receiver and args, and execute the method.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   172
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   173
     ThisContext sender is the context of the original send (the failed one)
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   174
    "
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
   175
    sender := thisContext sender.
45
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   176
    ObjectMemory flushCaches.
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   177
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   178
    ^ self valueWithReceiver:(sender receiver)
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   179
		   arguments:(sender args)
e8331ba8ad5d *** empty log message ***
claus
parents: 40
diff changeset
   180
		    selector:(sender selector)
54
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   181
		      search:nil
86c5b39c2eca *** empty log message ***
claus
parents: 47
diff changeset
   182
		      sender:nil
18
343ca93df0e0 Initial revision
claus
parents:
diff changeset
   183
! !