mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
170aa90158
Use that to sync variables to predefined stack slots inside of exception handler, not before each MayThrow() instruction. In JIT mode we can avoid storing extra metadata by using deopt info instead. Introduce caching of metadata and exception handler based on PC. R=fschneider@google.com, vegorov@google.com Review-Url: https://codereview.chromium.org/2734323003 .
166 lines
4.7 KiB
C++
166 lines
4.7 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_EXCEPTIONS_H_
|
|
#define RUNTIME_VM_EXCEPTIONS_H_
|
|
|
|
#include "vm/allocation.h"
|
|
#include "vm/token_position.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declarations.
|
|
class AbstractType;
|
|
class Array;
|
|
class DartFrameIterator;
|
|
class Error;
|
|
class LanguageError;
|
|
class Instance;
|
|
class Integer;
|
|
class RawInstance;
|
|
class RawObject;
|
|
class RawScript;
|
|
class RawStackTrace;
|
|
class String;
|
|
class Thread;
|
|
|
|
class Exceptions : AllStatic {
|
|
public:
|
|
static void Throw(Thread* thread, const Instance& exception);
|
|
static void ReThrow(Thread* thread,
|
|
const Instance& exception,
|
|
const Instance& stacktrace);
|
|
static void PropagateError(const Error& error);
|
|
|
|
// Helpers to create and throw errors.
|
|
static RawStackTrace* CurrentStackTrace();
|
|
static RawScript* GetCallerScript(DartFrameIterator* iterator);
|
|
static RawInstance* NewInstance(const char* class_name);
|
|
static void CreateAndThrowTypeError(TokenPosition location,
|
|
const AbstractType& src_type,
|
|
const AbstractType& dst_type,
|
|
const String& dst_name,
|
|
const String& bound_error_msg);
|
|
|
|
enum ExceptionType {
|
|
kNone,
|
|
kRange,
|
|
kRangeMsg,
|
|
kArgument,
|
|
kArgumentValue,
|
|
kNoSuchMethod,
|
|
kFormat,
|
|
kUnsupported,
|
|
kStackOverflow,
|
|
kOutOfMemory,
|
|
kNullThrown,
|
|
kIsolateSpawn,
|
|
kAssertion,
|
|
kCast,
|
|
kType,
|
|
kFallThrough,
|
|
kAbstractClassInstantiation,
|
|
kCyclicInitializationError,
|
|
kCompileTimeError,
|
|
};
|
|
|
|
static void ThrowByType(ExceptionType type, const Array& arguments);
|
|
// Uses the preallocated out of memory exception to avoid calling
|
|
// into Dart code or allocating any code.
|
|
static void ThrowOOM();
|
|
static void ThrowStackOverflow();
|
|
static void ThrowArgumentError(const Instance& arg);
|
|
static void ThrowRangeError(const char* argument_name,
|
|
const Integer& argument_value,
|
|
intptr_t expected_from,
|
|
intptr_t expected_to);
|
|
static void ThrowRangeErrorMsg(const char* msg);
|
|
static void ThrowCompileTimeError(const LanguageError& error);
|
|
|
|
// Returns a RawInstance if the exception is successfully created,
|
|
// otherwise returns a RawError.
|
|
static RawObject* Create(ExceptionType type, const Array& arguments);
|
|
|
|
static void JumpToFrame(Thread* thread,
|
|
uword program_counter,
|
|
uword stack_pointer,
|
|
uword frame_pointer,
|
|
bool clear_deopt_at_target);
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(Exceptions);
|
|
};
|
|
|
|
// The index into the ExceptionHandlers table corresponds to
|
|
// the try_index of the handler.
|
|
struct ExceptionHandlerInfo {
|
|
uint32_t handler_pc_offset; // PC offset value of handler.
|
|
int16_t outer_try_index; // Try block index of enclosing try block.
|
|
int8_t needs_stacktrace; // True if a stacktrace is needed.
|
|
int8_t has_catch_all; // Catches all exceptions.
|
|
int8_t is_generated; // True if this is a generated handler.
|
|
};
|
|
|
|
|
|
class CatchEntryState {
|
|
public:
|
|
enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 };
|
|
|
|
CatchEntryState() : data_(NULL), ref_count_(NULL) {}
|
|
explicit CatchEntryState(intptr_t* data)
|
|
: data_(data), ref_count_(new intptr_t(1)) {}
|
|
|
|
CatchEntryState(const CatchEntryState& state) { Copy(state); }
|
|
|
|
~CatchEntryState() { Destroy(); }
|
|
|
|
CatchEntryState& operator=(const CatchEntryState& state) {
|
|
Destroy();
|
|
Copy(state);
|
|
return *this;
|
|
}
|
|
|
|
bool Empty() { return ref_count_ == NULL; }
|
|
|
|
intptr_t Pairs() { return data_[0]; }
|
|
|
|
intptr_t Src(intptr_t i) { return data_[1 + 2 * i]; }
|
|
|
|
intptr_t Dest(intptr_t i) {
|
|
return data_[2 + 2 * i] >> kCatchEntryStateDestShift;
|
|
}
|
|
|
|
bool isMove(intptr_t i) { return data_[2 + 2 * i] & kCatchEntryStateIsMove; }
|
|
|
|
private:
|
|
void Destroy() {
|
|
if (ref_count_ != NULL) {
|
|
(*ref_count_)--;
|
|
if (*ref_count_ == 0) {
|
|
delete ref_count_;
|
|
delete[] data_;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Copy(const CatchEntryState& state) {
|
|
data_ = state.data_;
|
|
ref_count_ = state.ref_count_;
|
|
if (ref_count_ != NULL) {
|
|
(*ref_count_)++;
|
|
}
|
|
}
|
|
|
|
// data_ has the following format:
|
|
// 0 - number of pairs in this state
|
|
// 1-2 - 1st encoded src,dest pair
|
|
// 3-4 - 2nd pair
|
|
// ....
|
|
intptr_t* data_;
|
|
intptr_t* ref_count_;
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_EXCEPTIONS_H_
|