blob: d9b8c14cd31847b503928195b4c4596cda8079bf [file] [log] [blame]
// 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);
// Propagate an error to the entry frame, skipping over Dart frames.
static void PropagateToEntry(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,
kIntegerDivisionByZeroException,
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_