/* Sun-$Revision: 23.20 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface class codeSlotsMap: public slotsMap { // abstract class for objects with code public: bool is_method_like() { return true; } oop mirror_names(oop ignored); oop mirror_reflectee(oop r) { Unused(r); return ErrorCodes::vmString_prim_error(REFLECTTYPEERROR); } fint arg_count(); }; class oldMapList; class methodMap: public codeSlotsMap { friend slotsOop create_outerMethod(slotList* slots, ByteCode* b, char* annotation = "", IntBList* stack_deltas = NULL); protected: // instance variables byteVectorOop _codes; stringOop _file; smiOop _line; stringOop _source; objVectorOop _literals; public: byteVectorOop codes() { return _codes; } stringOop file() { return _file; } smiOop line() { return _line; } objVectorOop literals() { return _literals; } stringOop source() { return _source; } void setFile(stringOop f) { Memory->store((oop*)&_file, oop(f)); } void setLine(smiOop l) { Memory->store((oop*)&_line, l); } virtual methodMap* get_lexical_link_map() = 0; protected: void setLiterals(objVectorOop lit) { Memory->store((oop*)&_literals, lit); } void setCodes(byteVectorOop c) { Memory->store((oop*)&_codes, c); } void setSource(stringOop s) { Memory->store((oop*)&_source, s); } // functions to implement local access bytecodes void fix_local_bytecodes_and_links( oldMapList* old_maps, slotsOop outerMethod, IntBList* stack_deltas = NULL); void fix_local_bytecodes_and_links_of_my_blocks( oldMapList* old_maps, slotsOop outerMethod); void fix_local_bytecodes_and_links_in_myself( oldMapList* old_maps, slotsOop outerMethod, IntBList* stack_deltas); public: void GenSendOrLocal( ByteCode* bc, stringOop sel); slotDesc* getLocalSlot( fint lexicalLevel, fint index); public: bool has_code() { return true; } bool hasSubBlocks() { for (oop *p= start_literals(), *end= p + length_literals(); p < end; p++) if ((*p)->is_block_with_code()) return true; return false; } public: u_char* start_codes() { return (u_char*) _codes->bytes(); } fint length_codes() { return _codes->length(); } oop* start_literals() { return literals()->objs(); } fint length_literals() { return literals()->length(); } oop mirror_codes(oop r); oop mirror_literals(oop r); oop mirror_source(oop r); oop mirror_file(oop r); oop mirror_line(oop r); // compiler helper functions bool containsBranch(); bool containsLoop(); bool containsNLR(); IntList* accessedSlots(blockMethodMap *bmm); // Indices of all slots that could be uplevel-accessed by sends // in bmm and subblocks thereof. public: fint beginningOfStatement(fint bci); IntList* expression_stack(fint bci, bool keepArgs, fint startBCI); IntList* expression_stack(fint bci, bool keepArgs) { // this used to be: // if (!keepArgs // && bci+1 < length_codes() // && start_codes()[bci+1] == BuildCode(NO_OPERAND_CODE, POP_CODE)) { // // last send in a statement has empty expression stack // return EMPTY; // } else { // return expression_stack(bci, keepArgs, beginningOfStatement(bci)); // } // but the then-case fails when the bytecodes do not come from source. // So I took it out, which broke Mario's concurrentProgrammingTest // but am pressing on for now. -- dmu return expression_stack(bci, keepArgs, beginningOfStatement(bci)); } IntList* expression_stack_bcis(bool debugMode); IntList* all_blocks(OopList** literals = NULL); IntList* blocks_upto(fint bci, OopList** literals = NULL); public: void branch_targets( bool& got_one, BoolBList** branch_targets, BoolBList** backwards_branch_targets = NULL); int32 debug_size(oop p); fint get_index_at(fint byteCodeIndex); stringOop get_selector_at(fint byteCodeIndex); virtual slotDesc* slots() { return (slotDesc*) (this + 1); } // creation operation friend slotsOop basic_create_method(slotList* slots, ByteCode* b, methodMap &m1, char *annotation, bool isBlock); protected: virtual void set_lexical_links( slotsOop enclosingMethod, slotsOop outerMethod, stringOop src, fint srcOffset, bool isOKToBashLiteralVector); void set_outer_method_link_in_literals( slotsOop outerMethod); public: // programming friend char* check_byteCodes_and_literals( smi& errorIndex, IntBList*& stack_deltas, byteVectorOop codes, objVectorOop literals ); // used by programming prims to set backpointers oop fix_up_method( oop obj, oop old_optimized_method = NULL, bool isOKToBashLiteralVector = false, bool mustAllocate= true, IntBList* stack_deltas = NULL); // printing support void print_string(oop obj, char* buf); void print_oop(oop obj); void print_code(oop obj); virtual void print_source(); void print_byteCode_at(fint byteCodeIndex); bool verify(oop obj); }; class outerMethodMap: public methodMap { public: friend slotsOop create_outerMethod(slotList* slots, ByteCode* b, char* annotation, IntBList* stack_deltas); MethodKind kind() { return OuterMethodType; } mirrorOop mirror_proto() { return Memory->outerMethodMirrorObj; } oop mirror_source_offset(oop r) { Unused(r); return smiOop_zero; } oop mirror_source_length(oop r) { Unused(r); return smiOop_zero; } bool verify(oop obj); methodMap* get_lexical_link_map() { return NULL; } }; class blockMethodMap: public methodMap { friend slotsOop basic_create_method(slotList* slots, ByteCode* b, methodMap &m1, char* annotation, bool isBlock); friend class methodMap; public: // needs to be public for MW smiOop _sourceOffset, _sourceLen; protected: void set_lexical_links( slotsOop enclosingMethod, slotsOop outerMethod, stringOop src, fint srcOffset, bool isOKToBashLiteralVector); slotsOop set_lexical_link( slotsOop block_meth, slotsOop enclosing_meth); public: slotDesc* slots() { return (slotDesc*) (this + 1); } oop mirror_source_offset(oop r) { Unused(r); return _sourceOffset; } oop mirror_source_length(oop r) { Unused(r); return _sourceLen; } friend slotsOop create_blockMethod(slotList* slots, ByteCode* b, char* annotation = "", IntBList* stack_deltas = NULL); friend slotsOop basic_create_method(slotList* slots, ByteCode* b, methodMap* m1, char* annotation, bool isBlock); MethodKind kind() { return BlockMethodType; } mirrorOop mirror_proto() { return Memory->blockMethodMirrorObj; } oop mirror_parent(oop obj); void print_source(); bool verify(oop obj); methodMap* get_lexical_link_map(); slotsOop get_lexical_link(); // compiler helper // return list of indices of slots in parentMap up-level accessed by me IntList* uplevel_accessed_slots(methodMap* parentMap); };