LazyMethod.st
author claus
Tue, 23 Aug 1994 18:17:46 +0200
changeset 40 45ecd4441edb
parent 27 7e2b3ab54d7c
child 45 e8331ba8ad5d
permissions -rw-r--r--
compilation is donw in critical region - it was not reentrant

"
 COPYRIGHT (c) 1994 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

Method subclass:#LazyMethod
         instanceVariableNames:''
         classVariableNames:'Access'
         poolDictionaries:''
         category:'Kernel-Methods'
!

LazyMethod comment:'
COPYRIGHT (c) 1994 by Claus Gittinger
              All Rights Reserved

$Header: /cvs/stx/stx/libcomp/LazyMethod.st,v 1.4 1994-08-23 16:17:46 claus Exp $
'!

!LazyMethod class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1994 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

version
"
$Header: /cvs/stx/stx/libcomp/LazyMethod.st,v 1.4 1994-08-23 16:17:46 claus Exp $
"
!

documentation
"
    Instances of LazyMethod are created when doing a lazy autoload.
    When executed, these will trigger an error in the VM (noByteCode),
    which is cought here to create a real method from the receiver.
    This allows faster loading of code, which will then be compiled
    when first executed; for classes with a large number of methods, of
    which only a small subset is actually used, this can also save
    lots of memory.
"
! !

!LazyMethod class methodsFor:'initialization'!

initialize
    Access := Semaphore forMutualExclusion
! !

!LazyMethod methodsFor:'queries'!

isLazyMethod
    ^ true
! !

!LazyMethod methodsFor:'error handling'!

noByteCode 
    "this error is triggered by the interpreter when a lazy method
     is about to be executed (by sending the bad method this message);
     hard-compile the method now, install its bytecode in the receiver,
     and call it now."

    |code m lazy sender|

    "compile the method"

    Access wait.

    lazy := Compiler compileLazy:false.
    [
        m := self asByteCodeMethod.
    ] valueOnUnwindDo:[
        Compiler compileLazy:lazy.
	Access signal.
    ].

    m isNil ifTrue:[
	Access signal.
	^ super invalidMethod
    ].
    byteCode := m byteCode.
    sender := thisContext sender.
    byteCode notNil ifTrue:[
        literals := m literals.
        flags := m flags.
        "
         thisContext sender is the original sends (the failed ones)
         context ...
        "
        ObjectMemory flushCaches.
	Access signal.
        ^ self valueWithReceiver:(sender receiver)
                       arguments:(sender args)
                        selector:(sender selector)
    ].
    Access signal.
    ^ self error:'cannot compile method'
! !