// // 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" ); } }
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; }
bool isExternalObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == EXTERNAL_KIND; }
bool isAtomicWRecordObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == ATOMIC_WRECORD_KIND; }
bool isWRecordObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == WRECORD_KIND; }
bool isMapObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == MAP_KIND; }
bool isPairObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == PAIR_KIND; }
bool isMixedObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == MIXED_KIND; }
bool isVectorObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == VECTOR_KIND; }
bool isStringObject() const { return IsSimple( *this->obj_K ) && KindOfSimpleKey( *this->obj_K ) == STRING_KIND; }