CompiledCode.st
author claus
Mon, 01 May 1995 23:30:32 +0200
changeset 328 7b542c0bf1dd
parent 326 d2902942491d
child 345 cf2301210c47
permissions -rw-r--r--
.

"
 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.
"

ExecutableFunction subclass:#CompiledCode
       instanceVariableNames:'byteCode literals'
       classVariableNames:'NoByteCodeSignal InvalidByteCodeSignal
			   InvalidInstructionSignal BadLiteralsSignal
			   NonBooleanReceiverSignal ArgumentSignal'
       poolDictionaries:''
       category:'Kernel-Methods'
!

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

$Header: /cvs/stx/stx/libbasic/CompiledCode.st,v 1.12 1995-05-01 21:29:03 claus Exp $
'!

!CompiledCode 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/libbasic/CompiledCode.st,v 1.12 1995-05-01 21:29:03 claus Exp $
"
!

documentation
"
    This is an abstract class, to merge common attributes of Blocks and
    Methods i.e. describe all objects consisting of either compiled or 
    interpreted code.

    Instance variables:

      byteCode    <ByteArray>       bytecode if its an interpreted codeobject
      literals    <Array>           the block/methods literal array


    Class variables:

      NoByteCodeSignal              raised if a codeObject is about to be executed
				    which has neither code nor byteCode (i.e. both are nil)
      InvalidByteCodeSignal         raised if byteCode is not an instance of ByteArray
      InvalidInstructionSignal      raised if an invalid instruction opcode is encountered
      BadLiteralsSignal             raised if literalArray is not an array
      NonBooleanReceiverSignal      raised for conditional jumps where receiver is not a boolean
      ArgumentSignal                raised if argument count is not what the codeObject expects

    all of these signals are children of ExecutionErrorSignal.

    NOTICE: layout known by runtime system and compiler - do not change
"
! !

!CompiledCode class methodsFor:'initialization'!

initialize
    NoByteCodeSignal isNil ifTrue:[
	NoByteCodeSignal := ExecutionErrorSignal newSignalMayProceed:true.
	NoByteCodeSignal nameClass:self message:#noByteCodeSignal.
	NoByteCodeSignal notifierString:'nil byteCode in code-object - not executable'.

	InvalidByteCodeSignal := ExecutionErrorSignal newSignalMayProceed:true.
	InvalidByteCodeSignal nameClass:self message:#invalidByteCodeSignal.
	InvalidByteCodeSignal notifierString:'invalid byteCode in code-object - not executable'.

	InvalidInstructionSignal := ExecutionErrorSignal newSignalMayProceed:true.
	InvalidInstructionSignal nameClass:self message:#invalidInstructionSignal.
	InvalidInstructionSignal notifierString:'invalid instruction in code-object - not executable'.

	BadLiteralsSignal := ExecutionErrorSignal newSignalMayProceed:true.
	BadLiteralsSignal nameClass:self message:#badLiteralsSignal.
	BadLiteralsSignal notifierString:'bad literal table in code-object - should not happen'.

	NonBooleanReceiverSignal := ExecutionErrorSignal newSignalMayProceed:true.
	NonBooleanReceiverSignal nameClass:self message:#nonBooleanReceiverSignal.
	NonBooleanReceiverSignal notifierString:'if/while on non-boolean receiver'.

	ArgumentSignal := ExecutionErrorSignal newSignalMayProceed:true.
	ArgumentSignal nameClass:self message:#argumentSignal.
	ArgumentSignal notifierString:'bad argument(s)'.
    ]
! !

!CompiledCode class methodsFor:'signal access'!

executionErrorSignal
    "return the parent-signal of all execution errors"

    ^ ExecutionErrorSignal
!

argumentSignal
    "return the signal raised when something's wrong with the
     arguments"

    ^ ArgumentSignal
! !

!CompiledCode class methodsFor:'queries'!

isBuiltInClass
    "this class is known by the run-time-system"

    ^ true
! !

!CompiledCode methodsFor:'accessing'!

byteCode
    "return the bytecode (a ByteArray)"

    ^ byteCode
!

literals
    "return the literal array"

    ^ literals
! !

!CompiledCode methodsFor:'queries'!

messages
    "return a Set of all symbols referenced by this thingy.
     (this is more than the message selectors, since also global names
     and symbols found in immediate arrays are included)."

    |symbolSet|

    symbolSet := IdentitySet new.
    literals notNil ifTrue:[
	literals do: [ :lit |
	    (lit isSymbol) ifTrue: [
		symbolSet add: lit
	    ] ifFalse: [
		(lit isKindOf:Array) ifTrue: [
		    lit traverse: [ :el |
			(el isSymbol) ifTrue: [symbolSet add: el]
		    ]
		]
	    ]
	]
    ].
    ^ symbolSet

    "
     (CompiledCode compiledMethodAt:#messages) messages 
    "
! !

!CompiledCode methodsFor:'private accessing'!

byteCode:aByteArray
    "set the bytecode field - DANGER ALERT"

    byteCode := aByteArray
!

literals:aLiteralArray 
    "set the literal array for evaluation - DANGER ALERT"

    literals := aLiteralArray
! !

!CompiledCode methodsFor:'error handling'!

noByteCode
    "this error is triggered when the interpreter tries to execute a
     code object, where the byteCode is nil.
     Can only happen when Compiler/runtime system is broken or
     someone played around with a block/method.
     (late news: also used for lazy compilation of methods)"

    ^ NoByteCodeSignal raise.
!

invalidByteCode
    "this error is triggered when the interpreter tries to execute a
     code object, where the byteCode is nonNil, but not a ByteArray.
     Can only happen when Compiler/runtime system is broken or
     someone played around with a block/method."

    ^ InvalidByteCodeSignal raise.
!

invalidInstruction
    "this error is triggered when the bytecode-interpreter tries to
     execute an invalid bytecode instruction.
     Can only happen when Compiler/runtime system is broken or
     someone played around with the block/methods code."

    ^ InvalidInstructionSignal raise.
!

badLiteralTable
    "this error is triggered, when a block/method is called with a bad literal
     array (i.e. non-array) - this can only happen, if the
     compiler is broken or someone played around with a block/methods
     literal table or the GC is broken and corrupted it."

    ^ BadLiteralsSignal raise.
!

receiverNotBoolean:anObject
    "this error is triggered when the bytecode-interpreter tries to
     execute ifTrue:/ifFalse or whileTrue: type of expressions where the
     receiver is neither true nor false."

    ^ NonBooleanReceiverSignal raise.
!

tooManyArguments
    "this error is triggered, when a method/block tries to perform a send with
     more arguments than supported by the interpreter. This can only happen,
     if the compiler has been changed without updating the VM."

    ^ ArgumentSignal
	raiseRequestWith:self
	errorString:'too many args in send'
!

badArgumentArray
    "this error is triggered, if a non array is passed to 
     #valueWithReceiver:.. methods"

    ^ ArgumentSignal
	raiseRequestWith:self
	errorString:'argumentArray must be an Array'
! !