Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 17032) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -6884,46 +6884,67 @@ |
| intptr_t ExceptionHandlers::Length() const { |
| - return Smi::Value(raw_ptr()->length_); |
| + return raw_ptr()->length_; |
| } |
| -void ExceptionHandlers::SetLength(intptr_t value) const { |
| - // This is only safe because we create a new Smi, which does not cause |
| - // heap allocation. |
| - raw_ptr()->length_ = Smi::New(value); |
| +void ExceptionHandlers::SetHandlerInfo(intptr_t index, |
| + intptr_t try_index, |
| + intptr_t outer_try_index, |
| + intptr_t handler_pc) const { |
| + ASSERT(index < Length()); |
|
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length())
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length())
hausner
2013/01/15 22:44:52
Done.
|
| + RawExceptionHandlers::HandlerInfo* info = &raw_ptr()->data_[index]; |
| + info->try_index = try_index; |
| + info->outer_try_index = outer_try_index; |
| + info->handler_pc = handler_pc; |
| } |
| +void ExceptionHandlers::GetHandlerInfo( |
| + intptr_t index, |
| + RawExceptionHandlers::HandlerInfo* info) const { |
| + ASSERT(index < Length()); |
|
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length())
hausner
2013/01/15 22:44:52
Done.
|
| + RawExceptionHandlers::HandlerInfo* data = &raw_ptr()->data_[index]; |
|
siva
2013/01/15 22:04:12
ASSERT(info != NULL);
hausner
2013/01/15 22:44:52
Done.
|
| + info->try_index = data->try_index; |
| + info->outer_try_index = data->outer_try_index; |
| + info->handler_pc = data->handler_pc; |
| +} |
| + |
| intptr_t ExceptionHandlers::TryIndex(intptr_t index) const { |
| - return *(EntryAddr(index, kTryIndexEntry)); |
| + ASSERT(index < Length()); |
|
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length())
hausner
2013/01/15 22:44:52
Done.
|
| + return raw_ptr()->data_[index].try_index; |
| } |
| -void ExceptionHandlers::SetTryIndex(intptr_t index, intptr_t value) const { |
| - *(EntryAddr(index, kTryIndexEntry)) = value; |
| +intptr_t ExceptionHandlers::HandlerPC(intptr_t index) const { |
| + ASSERT(index < Length()); |
|
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length());
hausner
2013/01/15 22:44:52
Done.
|
| + return raw_ptr()->data_[index].handler_pc; |
| } |
| -intptr_t ExceptionHandlers::HandlerPC(intptr_t index) const { |
| - return *(EntryAddr(index, kHandlerPcEntry)); |
| +void ExceptionHandlers::SetHandledTypes(intptr_t index, |
| + const Array& handled_types) const { |
|
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length());
hausner
2013/01/15 22:44:52
Done.
|
| + const Array& handled_types_data = |
| + Array::Handle(raw_ptr()->handled_types_data_); |
| + handled_types_data.SetAt(index, handled_types); |
| } |
| -void ExceptionHandlers::SetHandlerPC(intptr_t index, |
| - intptr_t value) const { |
| - *(EntryAddr(index, kHandlerPcEntry)) = value; |
| +RawArray* ExceptionHandlers::GetHandledTypes(intptr_t index) const { |
|
siva
2013/01/15 22:04:12
ASSERT(index >= 0 && index < Length());
hausner
2013/01/15 22:44:52
Done.
|
| + Array& array = Array::Handle(raw_ptr()->handled_types_data_); |
| + array ^= array.At(index); |
| + return array.raw(); |
| } |
| +void ExceptionHandlers::set_handled_types_data(const Array& value) const { |
| + StorePointer(&raw_ptr()->handled_types_data_, value.raw()); |
| +} |
| + |
| + |
| RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) { |
| ASSERT(Object::exception_handlers_class() != Class::null()); |
|
siva
2013/01/15 22:04:12
You should probably still retain the check as an A
hausner
2013/01/15 22:44:52
Done, but to be an effective security check it has
|
| - if (num_handlers < 0 || num_handlers > kMaxElements) { |
| - // This should be caught before we reach here. |
| - FATAL1("Fatal error in ExceptionHandlers::New: " |
| - "invalid num_handlers %"Pd"\n", |
| - num_handlers); |
| - } |
| + const Array& handled_types_data = Array::Handle(Array::New(num_handlers)); |
| ExceptionHandlers& result = ExceptionHandlers::Handle(); |
| { |
| uword size = ExceptionHandlers::InstanceSize(num_handlers); |
| @@ -6932,7 +6953,8 @@ |
| Heap::kOld); |
| NoGCScope no_gc; |
| result ^= raw; |
| - result.SetLength(num_handlers); |
| + result.raw_ptr()->length_ = num_handlers; |
| + result.set_handled_types_data(handled_types_data); |
|
siva
2013/01/15 22:04:12
Pull the result.set_handled_types_data code outsid
hausner
2013/01/15 22:44:52
Done.
|
| } |
| return result.raw(); |
| } |
| @@ -6942,22 +6964,50 @@ |
| if (Length() == 0) { |
| return "No exception handlers\n"; |
| } |
| + Array& handled_types = Array::Handle(); |
| + Type& type = Type::Handle(); |
| + RawExceptionHandlers::HandlerInfo info; |
| // First compute the buffer size required. |
| - const char* kFormat = "%"Pd" => %#"Px"\n"; |
| + const char* kFormat = "%"Pd" => %#"Px" (%"Pd" types) (outer %"Pd")\n"; |
| + const char* kFormat2 = " %d. %s\n"; |
| intptr_t len = 1; // Trailing '\0'. |
| for (intptr_t i = 0; i < Length(); i++) { |
| - len += OS::SNPrint(NULL, 0, kFormat, TryIndex(i), HandlerPC(i)); |
| + GetHandlerInfo(i, &info); |
| + handled_types = GetHandledTypes(i); |
| + ASSERT(!handled_types.IsNull()); |
| + intptr_t num_types = handled_types.Length(); |
| + len += OS::SNPrint(NULL, 0, kFormat, |
| + info.try_index, |
| + info.handler_pc, |
| + num_types, |
| + info.outer_try_index); |
| + for (int k = 0; k < num_types; k++) { |
| + type ^= handled_types.At(k); |
| + ASSERT(!type.IsNull()); |
| + len += OS::SNPrint(NULL, 0, kFormat2, k, type.ToCString()); |
| + } |
| } |
| // Allocate the buffer. |
| char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); |
| // Layout the fields in the buffer. |
| - intptr_t index = 0; |
| + intptr_t num_chars = 0; |
| for (intptr_t i = 0; i < Length(); i++) { |
| - index += OS::SNPrint((buffer + index), |
| - (len - index), |
| - kFormat, |
| - TryIndex(i), |
| - HandlerPC(i)); |
| + GetHandlerInfo(i, &info); |
| + handled_types = GetHandledTypes(i); |
| + intptr_t num_types = handled_types.Length(); |
| + num_chars += OS::SNPrint((buffer + num_chars), |
| + (len - num_chars), |
| + kFormat, |
| + info.try_index, |
| + info.handler_pc, |
| + num_types, |
| + info.outer_try_index); |
| + for (int k = 0; k < num_types; k++) { |
| + type ^= handled_types.At(k); |
| + num_chars += OS::SNPrint((buffer + num_chars), |
| + (len - num_chars), |
| + kFormat2, k, type.ToCString()); |
| + } |
| } |
| return buffer; |
| } |