Esempio n. 1
0
//
//	This computes obj_C = obj_Z - obj_A from obj_K
//
unsigned long lengthAfterObjectKey( Ref * obj_K ) {
	//	Keys fall into the following categories: FunctionKey, SimpleKey, Pointer to Keys
	Ref key = *obj_K;
	if ( IsSimpleKey( key ) ) {
		switch ( LayoutOfSimpleKey( key ) ) {
		//switch ( KindOfSimpleKey( key ) ) {
			case RECORD_LAYOUT: {
			//case MAP_KIND:
			//case PAIR_KIND:
			//case RECORD_KIND: {
				assert( LayoutOfSimpleKey( key ) == RECORD_LAYOUT );
				assert( KindOfSimpleKey( key ) == PAIR_KIND || KindOfSimpleKey( key ) == MAP_KIND  || KindOfSimpleKey( key ) == RECORD_KIND );
				return sizeAfterKeyOfRecordLayout( obj_K );
				break;
			}
			case VECTOR_LAYOUT: {
			//case VECTOR_KIND: {
				assert( LayoutOfSimpleKey( key ) == VECTOR_LAYOUT );
				assert( KindOfSimpleKey( key ) == VECTOR_KIND );
				return sizeAfterKeyOfVectorLayout( obj_K );
				break;
			}
			case MIXED_LAYOUT: {
				assert( LayoutOfSimpleKey( key ) == MIXED_LAYOUT );
				return sizeAfterKeyOfMixedLayout( obj_K );
				break;
			}
			case STRING_LAYOUT: {
			//case STRING_KIND: {
				assert( LayoutOfSimpleKey( key ) == STRING_LAYOUT );
				assert( KindOfSimpleKey( key ) == STRING_KIND );
				return sizeAfterKeyOfStringLayout( obj_K );
				break;
			}
			case WRECORD_LAYOUT: {
				assert( LayoutOfSimpleKey( key ) == WRECORD_LAYOUT );
				return sizeAfterKeyOfWRecordLayout( obj_K );
				break;
			}
			default: 
				throw UnreachableError();
		}
	} else if ( IsFunctionKey( key ) ) {
		return sizeAfterKeyOfFn( obj_K );
	} else if ( IsObj( key ) ) {
		return sizeAfterKeyOfInstance( obj_K );
	} else {
		throw Ginger::Mishap( "Cannot take length of this" );
	}
}
Esempio n. 2
0
//
//	This computes obj_K from obj_A. 
//
Ref * findObjectKey( Ref * obj_A ) {
	//	Cases are that 'obj_A' is pointing at
	//		1.	FnLengthKey.
	//		2.	NonKey* Key series
	if ( IsFnLength( *obj_A ) ) {
		//	We are at the start of a function.
		//	It has a fixed offset to the key.
		return obj_A + OFFSET_FROM_FN_LENGTH_TO_KEY;
	} else {
		for ( int n = 0; n < MAX_OFFSET_FROM_START_TO_KEY; n++ ) {
			//
			//	Note that this function is called on objects that have been
			//	forwarded but not yet scanned by the GC. So the test for the
			//	key has to be capable of coping with a forwarded key. This
			//	test is stupider and restricts values in front of the key to
			//	simple values.
			//
			//	A smarter test is 
			//		1. 	Are you a simple key? Job done. A: yes
			//		2.	Are you an object? Define K = *you
			//			2a.	Is *K the keykey? If so job done. A: yes
			//			2b. Is *K forwarded? Define F = *K
			//			2c.	Is *F the keykey? If so A: yes
			//		3. 	Otherwise done A: no
			//	
			/*	I think the code would look like this.
			if ( IsSimpleKey( *obj_A ) ) return obj_A;
			if ( IsObj( *obj_A ) ) {
				if ( *RefToPtr4( *obj_A ) == sysClassKey ) return obj_A;
			}
			if ( IsFwd( *obj_A ) ) {
				Ref K = *FwdToPtr4( *obj_A );
				if ( IsObj( K ) ) {
					if ( *RefToPtr4( K ) == sysClassKey ) return obj_A;
				}
			} 
			*/
			Ref * x = obj_A + n;
			Ref k = *x;
			if ( IsSimpleKey( k ) || IsObj( k ) || IsFwd( k ) ) {
				return x;
			}
		}
		throw UnreachableError();
	}
}
Esempio n. 3
0
Ref * sysVectorAppend( Ref * pc, class MachineClass * vm ) {

	//	Variables here would be unaffected by a GC.
	unsigned long N;
	unsigned long lhs_n;
	unsigned long rhs_n;

	if ( vm->count != 2 ) throw Ginger::Mishap( "Wrong number of arguments in vectorAppend" );

	{
	
		//	May need to GC so leave on the stack.
		Ref rhs = vm->fastPeek();
		Ref lhs = vm->fastPeek( 1 );
		
		if ( !IsObj( lhs ) || !IsObj( rhs ) ) throw Ginger::Mishap( "Invalid arguments in vectorAppend" );
		
		Ref * lhs_K = RefToPtr4( lhs );
		Ref * rhs_K = RefToPtr4( rhs );
		Ref lhs_key = *lhs_K;
		Ref rhs_key = *rhs_K;
		
		if ( lhs_key != rhs_key || !IsSimpleKey( lhs_key ) || KindOfSimpleKey( lhs_key ) != VECTOR_KIND ) throw Ginger::Mishap( "Invalid arguments in vectorAppend" );
	
		lhs_n = sizeAfterKeyOfVectorLayout( lhs_K );
		rhs_n = sizeAfterKeyOfVectorLayout( rhs_K );
		N = lhs_n + rhs_n;
	
	}
	
	XfrClass xfr( vm->heap().preflight( pc, N + 2 ) );

	//	No risk of GC so safe to pop.
	Ref * rhs_K = RefToPtr4( vm->fastPop() );
	Ref * lhs_K = RefToPtr4( vm->fastPop() );

	xfr.xfrRef( ULongToSmall( N ) );
	xfr.setOrigin();
	xfr.xfrRef( *lhs_K );
	xfr.xfrCopy( lhs_K + 1, lhs_n );
	xfr.xfrCopy( rhs_K + 1, rhs_n );

	vm->fastPush( xfr.makeRef() );
	return pc;

}