libs-steptalk/Languages/Smalltalk/STBytecodes.m
Stefan Urbanek 3854adf0a6 Clean warnings
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/steptalk/trunk@17458 72102866-910b-0410-8b05-ffd578937521
2003-08-08 22:35:26 +00:00

286 lines
8.4 KiB
Objective-C

/**
STBytecodes.m
Copyright (c) 2002 Free Software Foundation
This file is part of the StepTalk project.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import "STBytecodes.h"
#import <StepTalk/STExterns.h>
#import "Externs.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSCoder.h>
#import <Foundation/NSData.h>
#import <Foundation/NSException.h>
NSArray *STBytecodeNames;
static void initNamesArray(void)
{
NSString *invalid = @"invalid bytecode";
NSMutableArray *array;
int i;
array = [NSMutableArray arrayWithCapacity:256];
for(i=0;i<256;i++)
{
[array insertObject:invalid atIndex:i];
}
[array replaceObjectAtIndex:STPushReceiverBytecode
withObject:@"push self"];
[array replaceObjectAtIndex:STPushNilBytecode
withObject:@"push nil"];
[array replaceObjectAtIndex:STPushTrueBytecode
withObject:@"push true"];
[array replaceObjectAtIndex:STPushFalseBytecode
withObject:@"push false"];
[array replaceObjectAtIndex:STPushRecVarBytecode
withObject:@"push ivar"];
[array replaceObjectAtIndex:STPushExternBytecode
withObject:@"push extern"];
[array replaceObjectAtIndex:STPushTemporaryBytecode
withObject:@"push temporary"];
[array replaceObjectAtIndex:STPushLiteralBytecode
withObject:@"push literal"];
[array replaceObjectAtIndex:STPopAndStoreRecVarBytecode
withObject:@"pop and store ivar"];
[array replaceObjectAtIndex:STPopAndStoreExternBytecode
withObject:@"pop and store extern"];
[array replaceObjectAtIndex:STPopAndStoreTempBytecode
withObject:@"pop and store temp"];
[array replaceObjectAtIndex:STSendSelectorBytecode
withObject:@"send selector"];
[array replaceObjectAtIndex:STSuperSendSelectorBytecode
withObject:@"send super selector"];
[array replaceObjectAtIndex:STBlockCopyBytecode
withObject:@"block copy"];
[array replaceObjectAtIndex:STDupBytecode
withObject:@"dup"];
[array replaceObjectAtIndex:STPopStackBytecode
withObject:@"pop"];
[array replaceObjectAtIndex:STReturnBytecode
withObject:@"return"];
[array replaceObjectAtIndex:STReturnBlockBytecode
withObject:@"return from block"];
[array replaceObjectAtIndex:STBreakpointBytecode
withObject:@"breakpoint"];
[array replaceObjectAtIndex:STLongJumpBytecode
withObject:@"long jump"];
STBytecodeNames = [[NSArray alloc] initWithArray:array];
}
NSString *STBytecodeName(unsigned short code)
{
static NSString *invalid = @"invalid bytecode";
NSString *name;
if( code > [STBytecodeNames count] )
{
return invalid;
}
name = [STBytecodeNames objectAtIndex:code];
if(name == nil)
{
return invalid;
}
return name;
}
NSString *STDissasembleBytecode(STBytecode bytecode)
{
NSString *str;
str = STBytecodeName(bytecode.code);
switch(bytecode.code)
{
case STLongJumpBytecode:
{
int offset = STLongJumpOffset(bytecode.arg1,bytecode.arg2);
return [NSString stringWithFormat:@"%@ %i (0x%06x)",
str, offset, bytecode.pointer+offset];
}
case STSendSelectorBytecode:
case STSuperSendSelectorBytecode:
return [NSString stringWithFormat:@"%@ %i with %i args",
str, bytecode.arg1, bytecode.arg2];
case STPushRecVarBytecode:
case STPushExternBytecode:
case STPushTemporaryBytecode:
case STPushLiteralBytecode:
case STPopAndStoreRecVarBytecode:
case STPopAndStoreExternBytecode:
case STPopAndStoreTempBytecode:
return [NSString stringWithFormat:@"%@ %i",
str, bytecode.arg1];
case STPushReceiverBytecode:
case STPushNilBytecode:
case STPushTrueBytecode:
case STPushFalseBytecode:
case STBlockCopyBytecode:
case STDupBytecode:
case STPopStackBytecode:
case STReturnBytecode:
case STReturnBlockBytecode:
case STBreakpointBytecode:
return str;
default:
return [NSString stringWithFormat:@"invalid (0x%02x)",
bytecode.code];
}
}
@implementation STBytecodes
+ (void)initialize
{
initNamesArray();
}
/*
- (id) initWithBytesNoCopy: (void*)someBytes
length: (unsigned)length
fromZone: (NSZone*)zone
{
bytes = [[NSData alloc] initWithBytesNoCopy:someBytes
length:length
fromZone:zone];
return self;
}
*/
- (id) initWithBytes: (const void*)someBytes
length: (unsigned int)length
{
bytes = [[NSData alloc] initWithBytes:someBytes
length:length];
return self;
}
- (void)dealloc
{
RELEASE(bytes);
[super dealloc];
}
- (const void *)bytes
{
return [bytes bytes];
}
- (unsigned) length
{
return [bytes length];
}
- (NSString *)description
{
return [bytes description];
}
- (STBytecode)fetchNextBytecodeAtPointer:(unsigned *)pointer
{
STBytecode bytecode;
const char *bytesPtr = (const char *)[bytes bytes];
unsigned length = [self length];
if(*pointer < length)
{
bytecode.pointer = *pointer;
bytecode.code = bytesPtr[(*pointer)++];
switch(bytecode.code)
{
case STLongJumpBytecode:
case STSendSelectorBytecode:
case STSuperSendSelectorBytecode:
if(*pointer + 2 >= length)
{
break;
}
bytecode.arg1 = bytesPtr[(*pointer)++];
bytecode.arg2 = bytesPtr[(*pointer)++];
return bytecode;
case STPushRecVarBytecode:
case STPushExternBytecode:
case STPushTemporaryBytecode:
case STPushLiteralBytecode:
case STPopAndStoreRecVarBytecode:
case STPopAndStoreExternBytecode:
case STPopAndStoreTempBytecode:
if(*pointer + 1 >= length)
{
break;
}
bytecode.arg1 = bytesPtr[(*pointer)++];
bytecode.arg2 = 0;
return bytecode;
case STPushReceiverBytecode:
case STPushNilBytecode:
case STPushTrueBytecode:
case STPushFalseBytecode:
case STBlockCopyBytecode:
case STDupBytecode:
case STPopStackBytecode:
case STReturnBytecode:
case STReturnBlockBytecode:
case STBreakpointBytecode:
bytecode.arg1 = 0;
bytecode.arg2 = 0;
return bytecode;
default:
[NSException raise:STInternalInconsistencyException
format:@"Invalid bytecode 0x%02x at 0x%06x",
bytecode.code,*pointer-1];
}
}
[NSException raise:STInternalInconsistencyException
format:@"Instruction pointer 0x%06x out of bounds (0x%06x)",
*pointer,length];
return bytecode;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
// [super encodeWithCoder: coder];
[coder encodeObject:bytes];
}
- initWithCoder:(NSCoder *)decoder
{
self = [super init]; // super initWithCoder: decoder];
[decoder decodeValueOfObjCType: @encode(id) at: &bytes];
return self;
}
@end