예제 #1
0
// Unpacks one or more frames into user-supplied buffers.
// Updates the end index, and returns the number of unpacked frames.
// Always start with the existing vfst.method and bci.
// Do not call vfst.next to advance over the last returned value.
// In other words, do not leave any stale data in the vfst.
//
// Parameters:
//   mode             Restrict which frames to be decoded.
//   JavaFrameStream  stream of javaVFrames
//   max_nframes      Maximum number of frames to be filled.
//   start_index      Start index to the user-supplied buffers.
//   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
//                    frames array is a Class<?>[] array when only getting caller
//                    reference, and a StackFrameInfo[] array (or derivative)
//                    otherwise. It should never be null.
//   end_index        End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream,
                              int max_nframes, int start_index,
                              objArrayHandle  frames_array,
                              int& end_index, TRAPS) {
  if (TraceStackWalk) {
    tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
                  max_nframes, start_index, frames_array->length());
  }
  assert(max_nframes > 0, "invalid max_nframes");
  assert(start_index + max_nframes <= frames_array->length(), "oob");

  int frames_decoded = 0;
  for (; !stream.at_end(); stream.next()) {
    Method* method = stream.method();
    int bci = stream.bci();

    if (method == NULL) continue;
    if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
      if (method->is_hidden()) {
        if (TraceStackWalk) {
          tty->print("  hidden method: "); method->print_short_name();
          tty->print("\n");
        }
        continue;
      }
    }

    int index = end_index++;
    if (TraceStackWalk) {
      tty->print("  %d: frame method: ", index); method->print_short_name();
      tty->print_cr(" bci=%d", bci);
    }

    // fill in StackFrameInfo and initialize MemberName
    if (live_frame_info(mode)) {
      assert (use_frames_array(mode), "Bad mode for get live frame");
      Handle stackFrame(frames_array->obj_at(index));
      fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0);
    } else if (need_method_info(mode)) {
      assert (use_frames_array(mode), "Bad mode for get stack frame");
      Handle stackFrame(frames_array->obj_at(index));
      fill_stackframe(stackFrame, method, bci);
    } else {
      assert (use_frames_array(mode) == false, "Bad mode for get caller class");
      frames_array->obj_at_put(index, method->method_holder()->java_mirror());
    }
    if (++frames_decoded >= max_nframes)  break;
  }
  return frames_decoded;
}
예제 #2
0
// Fill in the StackFrameInfo at the given index in frames_array
void JavaFrameStream::fill_frame(int index, objArrayHandle  frames_array,
                                 const methodHandle& method, TRAPS) {
    if (_need_method_info) {
        Handle stackFrame(THREAD, frames_array->obj_at(index));
        fill_stackframe(stackFrame, method);
    } else {
        frames_array->obj_at_put(index, method->method_holder()->java_mirror());
    }
}
예제 #3
0
// Fill in the LiveStackFrameInfo at the given index in frames_array
void LiveFrameStream::fill_frame(int index, objArrayHandle  frames_array,
                                 const methodHandle& method, TRAPS) {
    Handle stackFrame(THREAD, frames_array->obj_at(index));
    fill_live_stackframe(stackFrame, method, CHECK);
}
예제 #4
0
int16 Expression::parseExpr(byte stopToken, byte *type) {
	Stack stack;
	StackFrame stackFrame(stack);
	byte operation;
	int16 brackStart;
	uint32 varBase;

	while (true) {
		getVarBase(varBase);

		stackFrame.push();

		operation = _vm->_game->_script->readByte();
		if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) {

			loadValue(operation, varBase, stackFrame);

			if ((stackFrame.pos > 0) && ((stackFrame.opers[-1] == OP_NEG) || (stackFrame.opers[-1] == OP_NOT))) {
				stackFrame.pop();

				if (*stackFrame.opers == OP_NEG) {
					*stackFrame.opers = OP_LOAD_IMM_INT16;
					stackFrame.values[0] = -stackFrame.values[1];
				} else
					*stackFrame.opers = (stackFrame.opers[1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE;
			}

			if (stackFrame.pos <= 0)
				continue;

			simpleArithmetic1(stackFrame);

			continue;
		} // (op >= OP_ARRAY_INT8) && (op <= OP_FUNC)

		if ((operation == stopToken) || (operation == OP_OR) ||
				(operation == OP_AND) || (operation == OP_END_EXPR)) {
			while (stackFrame.pos >= 2) {
				if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) &&
						((operation == OP_END_EXPR) || (operation == stopToken))) {
					stackFrame.opers[-2] = stackFrame.opers[-1];
					if ((stackFrame.opers[-2] == OP_LOAD_IMM_INT16) || (stackFrame.opers[-2] == OP_LOAD_IMM_STR))
						stackFrame.values[-2] = stackFrame.values[-1];

					stackFrame.pop();

					simpleArithmetic2(stackFrame);

					if (operation != stopToken)
						break;
				}	// if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) && ...)

				for (brackStart = (stackFrame.pos - 2); (brackStart > 0) &&
				    (stack.opers[brackStart] < OP_OR) && (stack.opers[brackStart] != OP_BEGIN_EXPR);
						brackStart--)
					;

				if ((stack.opers[brackStart] >= OP_OR) || (stack.opers[brackStart] == OP_BEGIN_EXPR))
					brackStart++;

				if (complexArithmetic(stack, stackFrame, brackStart))
					break;

			}	// while (stackFrame.pos >= 2)

			if ((operation == OP_OR) || (operation == OP_AND)) {
				if (stackFrame.opers[-1] == OP_LOAD_IMM_INT16) {
					if (stackFrame.values[-1] != 0)
						stackFrame.opers[-1] = GOB_TRUE;
					else
						stackFrame.opers[-1] = GOB_FALSE;
				}

				if (((operation == OP_OR) && (stackFrame.opers[-1] == GOB_TRUE)) ||
				    ((operation == OP_AND) && (stackFrame.opers[-1] == GOB_FALSE))) {
					if ((stackFrame.pos > 1) && (stackFrame.opers[-2] == OP_BEGIN_EXPR)) {
						skipExpr(OP_END_EXPR);
						stackFrame.opers[-2] = stackFrame.opers[-1];
						stackFrame.pop(2);
					} else {
						skipExpr(stopToken);
					}
					operation = _vm->_game->_script->peekByte(-1);
					if ((stackFrame.pos > 0) && (stackFrame.opers[-1] == OP_NOT)) {
						if (stackFrame.opers[0] == GOB_FALSE)
							stackFrame.opers[-1] = GOB_TRUE;
						else
							stackFrame.opers[-1] = GOB_FALSE;

						stackFrame.pop();
					}
				} else
					stackFrame.opers[0] = operation;
			} else
				stackFrame.pop();

			if (operation != stopToken)
				continue;

			getResult(stack.opers[0], stack.values[0], type);

			return 0;
		}		// (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR)

		if ((operation < OP_NEG) || (operation > OP_NOT)) {
			if ((operation < OP_LESS) || (operation > OP_NEQ))
				continue;

			if (stackFrame.pos > 2) {
				if (stackFrame.opers[-2] == OP_ADD) {
					if (stackFrame.opers[-3] == OP_LOAD_IMM_INT16) {
						stackFrame.values[-3] += stackFrame.values[-1];
					} else if (stackFrame.opers[-3] == OP_LOAD_IMM_STR) {
						if ((char *)decodePtr(stackFrame.values[-3]) != _resultStr) {
							strcpy(_resultStr, (char *)decodePtr(stackFrame.values[-3]));
							stackFrame.values[-3] = encodePtr((byte *)_resultStr, kResStr);
						}
						strcat(_resultStr, (char *)decodePtr(stackFrame.values[-1]));
					}
					stackFrame.pop(2);

				} else if (stackFrame.opers[-2] == OP_SUB) {
					stackFrame.values[-3] -= stackFrame.values[-1];
					stackFrame.pop(2);
				} else if (stackFrame.opers[-2] == OP_BITOR) {
					stackFrame.values[-3] |= stackFrame.values[-1];
					stackFrame.pop(2);
				}
			}
		}
		*stackFrame.opers = operation;
	}
}