/* Sun-$Revision: 23.2 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface // interpret but keep track of the stack // assumes that method has already been "fixed" with // pushes and pops after uncond branches. class stacking_interpreter : public abstract_interpreter { protected: virtual bool check_for_pop(oop n) { assert_smi(n, "must be smiOop"); if ( get_stack_depth() < smiOop(n)->value()) { set_error_msg("stack underflow"); return false; } return true; } virtual bool check_and_pop(fint n = 1) { if ( !check(::check_for_pop, as_smiOop(n)) ) return false; pop(n); return true; } // override/copy the next few methods to implement the stack: // Also, since C++ forbids virtuals in constructors, // you must override constructors to initialize the stack. public: stacking_interpreter(oop meth) : abstract_interpreter(meth) { } stacking_interpreter(methodMap *m) : abstract_interpreter(m) { } stacking_interpreter(byteVectorOop codes, objVectorOop literals) : abstract_interpreter(codes, literals) { } protected: virtual void push() = 0; virtual void* pop(fint n = 1) = 0; virtual fint get_stack_depth() = 0; void do_read_write_local_code(bool isW) { if (isW) check_and_pop(); push(); } void do_branch_code(int32 , oop target_oop = badOop ) { if ( target_oop != badOop ) check_and_pop(); } void do_BRANCH_INDEXED_CODE() { check_and_pop(); } void do_POP_CODE() { check_and_pop(); } void do_SELF_CODE() { push(); } // override do_literal_code not do_LITERAL_CODE // because need the checking of the argument for the checker void do_literal_code(oop) { push(); } void do_send_code(bool isSelfImplicit, stringOop selector); }; class stack_depth_interpreter : public stacking_interpreter { private: fint stack_depth; public: stack_depth_interpreter(oop meth) : stacking_interpreter(meth) { stack_depth= 0; } stack_depth_interpreter(methodMap *m) : stacking_interpreter(m) { stack_depth= 0; } stack_depth_interpreter(byteVectorOop codes, objVectorOop literals) : stacking_interpreter(codes, literals) { stack_depth= 0; } protected: void init_stack() { stack_depth = 0; } void push() { ++stack_depth; } void* pop(fint n = 1) { stack_depth -= n; return NULL; } fint get_stack_depth() { return stack_depth; } void set_stack_depth(fint d) { stack_depth = d; } };