Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
| 6 | 6 |
| 7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
| 9 #include "vm/json.h" | |
| 9 #include "vm/message.h" | 10 #include "vm/message.h" |
| 10 #include "vm/port.h" | 11 #include "vm/port.h" |
| 12 #include "vm/resolver.h" | |
| 11 | 13 |
| 12 namespace dart { | 14 namespace dart { |
| 13 | 15 |
| 14 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 16 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| 15 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 17 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 16 return reinterpret_cast<uint8_t*>(new_ptr); | 18 return reinterpret_cast<uint8_t*>(new_ptr); |
| 17 } | 19 } |
| 18 | 20 |
| 19 | 21 |
| 20 DEFINE_NATIVE_ENTRY(Mirrors_send, 3) { | 22 DEFINE_NATIVE_ENTRY(Mirrors_send, 3) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 48 writer.FinalizeBuffer(); | 50 writer.FinalizeBuffer(); |
| 49 | 51 |
| 50 // Post the message. | 52 // Post the message. |
| 51 bool retval = PortMap::PostMessage(new Message( | 53 bool retval = PortMap::PostMessage(new Message( |
| 52 send_port_id, reply_port_id, data, Message::kOOBPriority)); | 54 send_port_id, reply_port_id, data, Message::kOOBPriority)); |
| 53 const Bool& retval_obj = Bool::Handle(Bool::Get(retval)); | 55 const Bool& retval_obj = Bool::Handle(Bool::Get(retval)); |
| 54 arguments->SetReturn(retval_obj); | 56 arguments->SetReturn(retval_obj); |
| 55 } | 57 } |
| 56 | 58 |
| 57 | 59 |
| 58 DEFINE_NATIVE_ENTRY(IsolateMirrorImpl_buildResponse, 1) { | 60 static bool JSONGetLiteral(const char* text, |
| 59 GET_NATIVE_ARGUMENT(Instance, map, arguments->At(0)); | 61 const char* field_name, |
| 60 String& key = String::Handle(); | 62 const char** value_chars, |
| 61 Instance& value = Instance::Handle(); | 63 int* value_len) { |
| 62 Object& result = Object::Handle(); | 64 JSONReader reader(text); |
| 65 reader.Seek(field_name); | |
| 66 if (reader.Type() != JSONReader::kLiteral) { | |
| 67 return false; | |
| 68 } | |
| 69 *value_chars = reader.ValueChars(); | |
| 70 *value_len = reader.ValueLen(); | |
| 71 return true; | |
| 72 } | |
| 63 | 73 |
| 64 key = String::New("debugName"); | 74 |
| 65 value = String::New(isolate->name()); | 75 static bool JSONGetString(const char* text, |
| 66 result = DartLibraryCalls::MapSetAt(map, key, value); | 76 const char* field_name, |
| 67 if (result.IsError()) { | 77 const char** value_chars, |
| 68 // TODO(turnidge): Prevent mirror operations from crashing other isolates? | 78 int* value_len) { |
| 69 Exceptions::PropagateError(result); | 79 JSONReader reader(text); |
| 80 reader.Seek(field_name); | |
| 81 if (reader.Type() != JSONReader::kString) { | |
| 82 return false; | |
| 83 } | |
| 84 *value_chars = reader.ValueChars(); | |
| 85 *value_len = reader.ValueLen(); | |
| 86 return true; | |
| 87 } | |
| 88 | |
| 89 | |
| 90 static bool match(const char* expected, | |
| 91 const char* actual, | |
| 92 int actual_len) { | |
| 93 if (!strncmp(expected, actual, actual_len) == 0) { | |
| 94 return false; | |
| 95 } | |
| 96 return expected[actual_len] == '\0'; | |
| 97 } | |
| 98 | |
| 99 | |
| 100 DEFINE_NATIVE_ENTRY(Mirrors_processResponse, 3) { | |
| 101 GET_NATIVE_ARGUMENT(Instance, port, arguments->At(0)); | |
| 102 GET_NATIVE_ARGUMENT(String, command, arguments->At(1)); | |
| 103 GET_NATIVE_ARGUMENT(String, response, arguments->At(2)); | |
| 104 | |
| 105 const char* json_text = response.ToCString(); | |
| 106 if (command.Equals("isolateMirrorOf")) { | |
| 107 const char* ok; | |
| 108 int ok_len; | |
| 109 const char* debug_name; | |
| 110 int debug_name_len; | |
| 111 if (!JSONGetLiteral(json_text, "ok", &ok, &ok_len) || | |
|
hausner
2012/04/23 21:54:17
If you don't throw away the JSONReader object afte
turnidge
2012/04/23 22:14:19
Instead of IsLiteral I added IsTrue(), IsFalse(),
| |
| 112 !match("true", ok, ok_len) || | |
| 113 !JSONGetString(json_text, "debugName", &debug_name, &debug_name_len)) { | |
| 114 // TODO(turnidge): Use an exception class instead of a String. | |
| 115 Exceptions::Throw(Instance::Handle(String::NewFormatted( | |
| 116 "Error while processing mirror request."))); | |
| 117 UNREACHABLE(); | |
| 118 } | |
| 119 | |
| 120 // Create and return a new instance of _IsolateMirrorImpl. | |
| 121 Library& lib = Library::Handle(Library::MirrorsLibrary()); | |
| 122 const String& public_class_name = | |
| 123 String::Handle(String::NewSymbol("_IsolateMirrorImpl")); | |
| 124 const String& class_name = | |
| 125 String::Handle(lib.PrivateName(public_class_name)); | |
| 126 const String& function_name = | |
| 127 String::Handle(String::NewSymbol("_make")); | |
| 128 const int kNumArgs = 2; | |
| 129 const Array& kNoArgNames = Array::Handle(); | |
| 130 const Function& function = Function::Handle( | |
| 131 Resolver::ResolveStatic(lib, | |
| 132 class_name, | |
| 133 function_name, | |
| 134 kNumArgs, | |
| 135 kNoArgNames, | |
| 136 Resolver::kIsQualified)); | |
| 137 | |
| 138 GrowableArray<const Object*> args(kNumArgs); | |
| 139 args.Add(&port); | |
| 140 const String& debug_name_str = String::Handle( | |
| 141 String::NewFormatted("%.*s", debug_name_len, debug_name)); | |
| 142 args.Add(&debug_name_str); | |
| 143 const Object& result = Object::Handle( | |
| 144 DartEntry::InvokeStatic(function, args, kNoArgNames)); | |
| 145 arguments->SetReturn(result); | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 | |
| 150 void HandleMirrorsMessage(Isolate* isolate, | |
| 151 Dart_Port reply_port, | |
| 152 const Instance& message) { | |
| 153 TextBuffer buffer(64); | |
| 154 if (!message.IsString()) { | |
| 155 buffer.Printf( | |
| 156 "{ \"ok\": false, \"error\": \"Malformed mirrors request\" }"); | |
| 157 } else { | |
| 158 String& json_string = String::Handle(); | |
| 159 json_string ^= message.raw(); | |
| 160 const char* json_text = json_string.ToCString(); | |
| 161 | |
| 162 const char* command; | |
| 163 int command_len; | |
| 164 if (JSONGetString(json_text, "command", &command, &command_len)) { | |
| 165 if (match("isolateMirrorOf", command, command_len)) { | |
| 166 buffer.Printf("{ \"ok\": true, \"debugName\": \"%s\" }", | |
| 167 isolate->name()); | |
| 168 } else { | |
| 169 buffer.Printf( | |
| 170 "{ \"ok\": false, \"error\": \"Command '%.*s' not recognized\" }", | |
| 171 command_len, command); | |
| 172 } | |
| 173 } else { | |
| 174 buffer.Printf( | |
| 175 "{ \"ok\": false, \"error\": \"Field 'command' not found\" }"); | |
| 176 } | |
| 70 } | 177 } |
| 71 | 178 |
| 72 key = String::New("ok"); | 179 Dart_CObject reply; |
| 73 value = Bool::True(); | 180 reply.type = Dart_CObject::kString; |
| 74 result = DartLibraryCalls::MapSetAt(map, key, value); | 181 reply.value.as_string = buffer.buf(); |
| 75 if (result.IsError()) { | 182 if (!Dart_PostCObject(reply_port, &reply)) { |
| 76 Exceptions::PropagateError(result); | 183 OS::PrintErr("Unable to post mirrors reply"); |
| 184 return; | |
| 77 } | 185 } |
| 78 } | 186 } |
| 79 | 187 |
| 80 } // namespace dart | 188 } // namespace dart |
| OLD | NEW |