/* classConstructor( key )( arg1, ..., argN ) -> instance */ Ref * sysClassConstructor( Ref * pc, MachineClass *vm ) { if ( vm->count != 1 ) throw Ginger::Mishap( "Wrong number of arguments" ); Ref kk = vm->fastPeek(); if ( !IsObj( kk ) || *RefToPtr4( kk ) != sysClassKey ) throw Ginger::Mishap( "Key needed" ); Ref * obj_K = RefToPtr4( kk ); long n = SmallToLong( obj_K[ CLASS_OFFSET_NFIELDS ] ); CodeGen codegen = vm->codegen(); codegen->vmiFUNCTION( makeName( "new", obj_K[ CLASS_OFFSET_TITLE ]), n, 1 ); //vmiCHECK_COUNT( codegen, n ); codegen->vmiSYS_CALL_ARGDAT( sysargdatConstruct, kk, n ); codegen->vmiSYS_RETURN(); vm->fastPeek() = codegen->vmiENDFUNCTION(); return pc; }
/* classAccessor( key, N:Small )( instance ) -> nth_field_of_instance */ Ref * sysClassAccessor( Ref * pc, MachineClass *vm ) { if ( vm->count != 2 ) throw Ginger::Mishap( "Wrong number of arguments" ); Ref N = vm->fastPop(); if ( !IsSmall( N ) ) throw Ginger::Mishap( "Integer index needed" ); Ref kk = vm->fastPeek(); if ( !isKey( kk ) ) throw Ginger::Mishap( "Key needed" ); long nargs = SmallToLong( RefToPtr4( kk )[ CLASS_OFFSET_NFIELDS ] ); long index = SmallToLong( N ); if ( 1 <= index && index <= nargs ) { CodeGen codegen = vm->codegen(); // TODO: Figure out name. codegen->vmiFUNCTION( 1, 1 ); codegen->vmiSYS_CALL_ARGDAT( sysargdatAccess, kk, index ); codegen->vmiSYS_RETURN(); vm->fastPeek() = codegen->vmiENDFUNCTION(); } else { throw Ginger::Mishap( "ToBeDone" ); } return pc; }