OLD | NEW |
1 // Copyright (c) 2014, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dartino project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 #ifdef DARTINO_ENABLE_DEBUGGING | 5 #ifdef DARTINO_ENABLE_DEBUGGING |
6 | 6 |
7 #include "src/vm/session.h" | 7 #include "src/vm/session.h" |
8 | 8 |
9 #include "src/shared/bytecodes.h" | 9 #include "src/shared/bytecodes.h" |
10 #include "src/shared/connection.h" | 10 #include "src/shared/connection.h" |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 buffer.WriteInt64(ClassMessage(Class::cast(value))); | 1030 buffer.WriteInt64(ClassMessage(Class::cast(value))); |
1031 connection_->Send(Connection::kClass, buffer); | 1031 connection_->Send(Connection::kClass, buffer); |
1032 } else if (value->IsTwoByteString()) { | 1032 } else if (value->IsTwoByteString()) { |
1033 // TODO(ager): We should send the character data as 16-bit values | 1033 // TODO(ager): We should send the character data as 16-bit values |
1034 // instead of 32-bit values. | 1034 // instead of 32-bit values. |
1035 TwoByteString* str = TwoByteString::cast(value); | 1035 TwoByteString* str = TwoByteString::cast(value); |
1036 for (int i = 0; i < str->length(); i++) { | 1036 for (int i = 0; i < str->length(); i++) { |
1037 buffer.WriteInt(str->get_code_unit(i)); | 1037 buffer.WriteInt(str->get_code_unit(i)); |
1038 } | 1038 } |
1039 connection_->Send(Connection::kString, buffer); | 1039 connection_->Send(Connection::kString, buffer); |
| 1040 } else if (value->IsArray()) { |
| 1041 Array* array = Array::cast(value); |
| 1042 buffer.WriteInt(array->length()); |
| 1043 connection_->Send(Connection::kArray, buffer); |
1040 } else { | 1044 } else { |
| 1045 ASSERT(value->IsInstance()); |
1041 buffer.WriteInt64(ClassMessage(HeapObject::cast(value)->get_class())); | 1046 buffer.WriteInt64(ClassMessage(HeapObject::cast(value)->get_class())); |
1042 connection_->Send(Connection::kInstance, buffer); | 1047 connection_->Send(Connection::kInstance, buffer); |
1043 } | 1048 } |
1044 } | 1049 } |
1045 | 1050 |
1046 void Session::SendInstanceStructure(Instance* instance) { | 1051 void Session::SendInstanceStructure(Instance* instance) { |
1047 WriteBuffer buffer; | 1052 WriteBuffer buffer; |
1048 Class* klass = instance->get_class(); | 1053 Class* klass = instance->get_class(); |
1049 buffer.WriteInt64(ClassMessage(klass)); | 1054 buffer.WriteInt64(ClassMessage(klass)); |
1050 int fields = klass->NumberOfInstanceFields(); | 1055 int fields = klass->NumberOfInstanceFields(); |
1051 buffer.WriteInt(fields); | 1056 buffer.WriteInt(fields); |
1052 connection_->Send(Connection::kInstanceStructure, buffer); | 1057 connection_->Send(Connection::kInstanceStructure, buffer); |
1053 for (int i = 0; i < fields; i++) { | 1058 for (int i = 0; i < fields; i++) { |
1054 SendDartValue(instance->GetInstanceField(i)); | 1059 SendDartValue(instance->GetInstanceField(i)); |
1055 } | 1060 } |
1056 } | 1061 } |
1057 | 1062 |
| 1063 void Session::SendArrayStructure(Array* array) { |
| 1064 int length = array->length(); |
| 1065 WriteBuffer buffer; |
| 1066 buffer.WriteInt(length); |
| 1067 connection_->Send(Connection::kArrayStructure, buffer); |
| 1068 for (int i = 0; i < length; i++) { |
| 1069 SendDartValue(array->get(i)); |
| 1070 } |
| 1071 } |
| 1072 |
| 1073 void Session::SendStructure(Object* object) { |
| 1074 if (object->IsArray()) { |
| 1075 SendArrayStructure(Array::cast(object)); |
| 1076 } else if (object->IsInstance()) { |
| 1077 SendInstanceStructure(Instance::cast(object)); |
| 1078 } else { |
| 1079 SendDartValue(object); |
| 1080 } |
| 1081 } |
| 1082 |
1058 void Session::SendProgramInfo(ClassOffsetsType* class_offsets, | 1083 void Session::SendProgramInfo(ClassOffsetsType* class_offsets, |
1059 FunctionOffsetsType* function_offsets) { | 1084 FunctionOffsetsType* function_offsets) { |
1060 ASSERT(maps_[class_map_id_] != NULL); | 1085 ASSERT(maps_[class_map_id_] != NULL); |
1061 ASSERT(maps_[method_map_id_] != NULL); | 1086 ASSERT(maps_[method_map_id_] != NULL); |
1062 | 1087 |
1063 WriteBuffer buffer; | 1088 WriteBuffer buffer; |
1064 | 1089 |
1065 // Write the hashtag for the program. | 1090 // Write the hashtag for the program. |
1066 buffer.WriteInt(program()->snapshot_hash()); | 1091 buffer.WriteInt(program()->snapshot_hash()); |
1067 | 1092 |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 case Connection::kProcessFiberBacktraceRequest: { | 1362 case Connection::kProcessFiberBacktraceRequest: { |
1338 int64 fiber_id = connection()->ReadInt64(); | 1363 int64 fiber_id = connection()->ReadInt64(); |
1339 Stack* stack = Stack::cast(session()->MapLookupById( | 1364 Stack* stack = Stack::cast(session()->MapLookupById( |
1340 session()->fibers_map_id_, fiber_id)); | 1365 session()->fibers_map_id_, fiber_id)); |
1341 session()->SendStackTrace(stack); | 1366 session()->SendStackTrace(stack); |
1342 break; | 1367 break; |
1343 } | 1368 } |
1344 | 1369 |
1345 case Connection::kProcessUncaughtExceptionRequest: { | 1370 case Connection::kProcessUncaughtExceptionRequest: { |
1346 Object* exception = process()->exception(); | 1371 Object* exception = process()->exception(); |
1347 if (exception->IsInstance()) { | 1372 session()->SendStructure(exception); |
1348 session()->SendInstanceStructure(Instance::cast(exception)); | |
1349 } else { | |
1350 session()->SendDartValue(exception); | |
1351 } | |
1352 break; | 1373 break; |
1353 } | 1374 } |
1354 | 1375 |
1355 case Connection::kProcessInstance: | 1376 case Connection::kProcessInstance: |
1356 case Connection::kProcessInstanceStructure: { | 1377 case Connection::kProcessInstanceStructure: { |
1357 int frame_index = connection()->ReadInt(); | 1378 int frame_index = connection()->ReadInt(); |
1358 int slot = connection()->ReadInt(); | 1379 int slot = connection()->ReadInt(); |
1359 int fieldAccessCount = connection()->ReadInt(); | 1380 int fieldAccessCount = connection()->ReadInt(); |
1360 Stack* stack = process()->stack(); | 1381 Stack* stack = process()->stack(); |
1361 Frame frame(stack); | 1382 Frame frame(stack); |
1362 for (int i = 0; i <= frame_index; i++) frame.MovePrevious(); | 1383 for (int i = 0; i <= frame_index; i++) frame.MovePrevious(); |
1363 word index = frame.FirstLocalIndex() - slot; | 1384 word index = frame.FirstLocalIndex() - slot; |
1364 if (index < frame.LastLocalIndex()) FATAL("Illegal slot offset"); | 1385 if (index < frame.LastLocalIndex()) { |
| 1386 session()->SendError(Connection::kInvalidInstanceAccess); |
| 1387 break; |
| 1388 } |
1365 Object* object = stack->get(index); | 1389 Object* object = stack->get(index); |
1366 for (int i = 0; i < fieldAccessCount; i++) { | 1390 for (int i = 0; i < fieldAccessCount; i++) { |
1367 if (!object->IsInstance()) { | 1391 if (object->IsArray()) { |
| 1392 Array* array = Array::cast(object); |
| 1393 int index = connection()->ReadInt(); |
| 1394 if (index < 0 || index >= array->length()) { |
| 1395 session()->SendError(Connection::kInvalidInstanceAccess); |
| 1396 break; |
| 1397 } |
| 1398 object = array->get(index); |
| 1399 } else if (object->IsInstance()) { |
| 1400 Instance* instance = Instance::cast(object); |
| 1401 Class* klass = instance->get_class(); |
| 1402 int fieldAccess = connection()->ReadInt(); |
| 1403 if (fieldAccess < 0 || |
| 1404 fieldAccess >= klass->NumberOfInstanceFields()) { |
| 1405 session()->SendError(Connection::kInvalidInstanceAccess); |
| 1406 break; |
| 1407 } |
| 1408 object = instance->GetInstanceField(fieldAccess); |
| 1409 } else { |
1368 session()->SendError(Connection::kInvalidInstanceAccess); | 1410 session()->SendError(Connection::kInvalidInstanceAccess); |
| 1411 break; |
1369 } | 1412 } |
1370 Instance* instance = Instance::cast(object); | |
1371 Class* klass = instance->get_class(); | |
1372 int fieldAccess = connection()->ReadInt(); | |
1373 if (fieldAccess < 0 || fieldAccess >= klass->NumberOfInstanceFields()) { | |
1374 session()->SendError(Connection::kInvalidInstanceAccess); | |
1375 } | |
1376 object = instance->GetInstanceField(fieldAccess); | |
1377 } | 1413 } |
1378 if (opcode == Connection::kProcessInstanceStructure && | 1414 if (opcode == Connection::kProcessInstanceStructure) { |
1379 object->IsInstance()) { | 1415 session()->SendStructure(object); |
1380 session()->SendInstanceStructure(Instance::cast(object)); | |
1381 } else { | 1416 } else { |
1382 session()->SendDartValue(object); | 1417 session()->SendDartValue(object); |
1383 } | 1418 } |
1384 break; | 1419 break; |
1385 } | 1420 } |
1386 | 1421 |
1387 case Connection::kProcessRestartFrame: { | 1422 case Connection::kProcessRestartFrame: { |
1388 int frame_index = connection()->ReadInt(); | 1423 int frame_index = connection()->ReadInt(); |
1389 RestartFrame(frame_index); | 1424 RestartFrame(frame_index); |
1390 process()->set_exception(program()->null_object()); | 1425 process()->set_exception(program()->null_object()); |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 if (program()->was_loaded_from_snapshot()) { | 2287 if (program()->was_loaded_from_snapshot()) { |
2253 return program()->OffsetOf(HeapObject::cast(klass)); | 2288 return program()->OffsetOf(HeapObject::cast(klass)); |
2254 } else { | 2289 } else { |
2255 return MapLookupByObject(class_map_id_, klass); | 2290 return MapLookupByObject(class_map_id_, klass); |
2256 } | 2291 } |
2257 } | 2292 } |
2258 | 2293 |
2259 } // namespace dartino | 2294 } // namespace dartino |
2260 | 2295 |
2261 #endif // DARTINO_ENABLE_DEBUGGING | 2296 #endif // DARTINO_ENABLE_DEBUGGING |
OLD | NEW |