Index: runtime/vm/service.cc |
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc |
index 80607bba42fa084766dd68c0098570c562463657..087e47e5199862243e51f0268d63bcf0648c7c43 100644 |
--- a/runtime/vm/service.cc |
+++ b/runtime/vm/service.cc |
@@ -14,6 +14,7 @@ |
#include "vm/dart_api_state.h" |
#include "vm/dart_entry.h" |
#include "vm/debugger.h" |
+#include "vm/dev_fs.h" |
#include "vm/isolate.h" |
#include "vm/lockers.h" |
#include "vm/message.h" |
@@ -413,6 +414,10 @@ class MethodParameter { |
return true; |
} |
+ virtual bool ValidateObject(const Object& value) const { |
+ return true; |
+ } |
+ |
const char* name() const { |
return name_; |
} |
@@ -427,12 +432,42 @@ class MethodParameter { |
PrintInvalidParamError(js, name); |
} |
+ virtual void PrintErrorObject(const char* name, |
+ const Object& value, |
+ JSONStream* js) const { |
+ PrintInvalidParamError(js, name); |
+ } |
+ |
private: |
const char* name_; |
bool required_; |
}; |
+class DartStringParameter : public MethodParameter { |
+ public: |
+ DartStringParameter(const char* name, bool required) |
+ : MethodParameter(name, required) { |
+ } |
+ |
+ virtual bool ValidateObject(const Object& value) const { |
+ return value.IsString(); |
+ } |
+}; |
+ |
+ |
+class DartListParameter : public MethodParameter { |
+ public: |
+ DartListParameter(const char* name, bool required) |
+ : MethodParameter(name, required) { |
+ } |
+ |
+ virtual bool ValidateObject(const Object& value) const { |
+ return value.IsArray() || value.IsGrowableObjectArray(); |
+ } |
+}; |
+ |
+ |
class NoSuchParameter : public MethodParameter { |
public: |
explicit NoSuchParameter(const char* name) |
@@ -442,6 +477,10 @@ class NoSuchParameter : public MethodParameter { |
virtual bool Validate(const char* value) const { |
return (value == NULL); |
} |
+ |
+ virtual bool ValidateObject(const Object& value) const { |
+ return value.IsNull(); |
+ } |
}; |
@@ -737,19 +776,38 @@ static bool ValidateParameters(const MethodParameter* const* parameters, |
if (parameters == NULL) { |
return true; |
} |
- for (intptr_t i = 0; parameters[i] != NULL; i++) { |
- const MethodParameter* parameter = parameters[i]; |
- const char* name = parameter->name(); |
- const bool required = parameter->required(); |
- const char* value = js->LookupParam(name); |
- const bool has_parameter = (value != NULL); |
- if (required && !has_parameter) { |
- PrintMissingParamError(js, name); |
- return false; |
+ if (js->NumObjectParameters() > 0) { |
+ Object& value = Object::Handle(); |
+ for (intptr_t i = 0; parameters[i] != NULL; i++) { |
+ const MethodParameter* parameter = parameters[i]; |
+ const char* name = parameter->name(); |
+ const bool required = parameter->required(); |
+ value = js->LookupObjectParam(name); |
+ const bool has_parameter = !value.IsNull(); |
+ if (required && !has_parameter) { |
+ PrintMissingParamError(js, name); |
+ return false; |
+ } |
+ if (has_parameter && !parameter->ValidateObject(value)) { |
+ parameter->PrintErrorObject(name, value, js); |
+ return false; |
+ } |
} |
- if (has_parameter && !parameter->Validate(value)) { |
- parameter->PrintError(name, value, js); |
- return false; |
+ } else { |
+ for (intptr_t i = 0; parameters[i] != NULL; i++) { |
+ const MethodParameter* parameter = parameters[i]; |
+ const char* name = parameter->name(); |
+ const bool required = parameter->required(); |
+ const char* value = js->LookupParam(name); |
+ const bool has_parameter = (value != NULL); |
+ if (required && !has_parameter) { |
+ PrintMissingParamError(js, name); |
+ return false; |
+ } |
+ if (has_parameter && !parameter->Validate(value)) { |
+ parameter->PrintError(name, value, js); |
+ return false; |
+ } |
} |
} |
return true; |
@@ -775,7 +833,9 @@ void Service::PostError(const String& method_name, |
} |
-void Service::InvokeMethod(Isolate* I, const Array& msg) { |
+void Service::InvokeMethod(Isolate* I, |
+ const Array& msg, |
+ bool parameters_are_dart_objects) { |
Thread* T = Thread::Current(); |
ASSERT(I == T->isolate()); |
ASSERT(I != NULL); |
@@ -809,7 +869,11 @@ void Service::InvokeMethod(Isolate* I, const Array& msg) { |
JSONStream js; |
js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), |
- seq, method_name, param_keys, param_values); |
+ seq, |
+ method_name, |
+ param_keys, |
+ param_values, |
+ parameters_are_dart_objects); |
// RPC came in with a custom service id zone. |
const char* id_zone_param = js.LookupParam("_idZone"); |
@@ -889,6 +953,12 @@ void Service::HandleRootMessage(const Array& msg_instance) { |
} |
+void Service::HandleObjectRootMessage(const Array& msg_instance) { |
+ Isolate* isolate = Isolate::Current(); |
+ InvokeMethod(isolate, msg_instance, true); |
+} |
+ |
+ |
void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { |
ASSERT(isolate != NULL); |
InvokeMethod(isolate, msg); |
@@ -3883,6 +3953,7 @@ static bool SetName(Thread* thread, JSONStream* js) { |
static const MethodParameter* set_vm_name_params[] = { |
+ NO_ISOLATE_PARAMETER, |
new MethodParameter("name", true), |
NULL, |
}; |
@@ -3932,6 +4003,127 @@ static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) { |
} |
+static const MethodParameter* create_dev_fs_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ new DartStringParameter("fsName", true), |
+ NULL, |
+}; |
+ |
+ |
+static bool CreateDevFS(Thread* thread, JSONStream* js) { |
+ const String& fs_name = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fsName"))); |
+ DevFS::CreateFileSystem(js, fs_name); |
+ return true; |
+} |
+ |
+ |
+static const MethodParameter* delete_dev_fs_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ new DartStringParameter("fsName", true), |
+ NULL, |
+}; |
+ |
+ |
+static bool DeleteDevFS(Thread* thread, JSONStream* js) { |
+ const String& fs_name = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fsName"))); |
+ DevFS::DeleteFileSystem(js, fs_name); |
+ return true; |
+} |
+ |
+ |
+static const MethodParameter* list_dev_fs_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ NULL, |
+}; |
+ |
+ |
+static bool ListDevFS(Thread* thread, JSONStream* js) { |
+ DevFS::ListFileSystems(js); |
+ return true; |
+} |
+ |
+ |
+static const MethodParameter* write_dev_fs_file_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ new DartStringParameter("fsName", true), |
+ new DartStringParameter("path", true), |
+ new DartStringParameter("fileContents", true), |
+ NULL, |
+}; |
+ |
+ |
+static bool WriteDevFSFile(Thread* thread, JSONStream* js) { |
+ const String& fs_name = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fsName"))); |
+ const String& path = |
+ String::Handle(String::RawCast(js->LookupObjectParam("path"))); |
+ const String& file_contents = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fileContents"))); |
+ DevFS::WriteFile(js, fs_name, path, file_contents); |
+ return true; |
+} |
+ |
+ |
+static const MethodParameter* write_dev_fs_files_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ new DartStringParameter("fsName", true), |
+ new DartListParameter("files", true), |
+ NULL, |
+}; |
+ |
+ |
+static bool WriteDevFSFiles(Thread* thread, JSONStream* js) { |
+ const String& fs_name = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fsName"))); |
+ Array& files = Array::Handle(); |
+ const Object& files_param = Object::Handle(js->LookupObjectParam("files")); |
+ if (files_param.IsArray()) { |
+ files ^= files_param.raw(); |
+ } else { |
+ ASSERT(files_param.IsGrowableObjectArray()); |
+ files ^= GrowableObjectArray::Cast(files_param).data(); |
+ } |
+ ASSERT(!files.IsNull()); |
+ DevFS::WriteFiles(js, fs_name, files); |
+ return true; |
+} |
+ |
+ |
+static const MethodParameter* read_dev_fs_file_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ new DartStringParameter("fsName", true), |
+ new DartStringParameter("path", true), |
+ NULL, |
+}; |
+ |
+ |
+static bool ReadDevFSFile(Thread* thread, JSONStream* js) { |
+ const String& fs_name = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fsName"))); |
+ const String& path = |
+ String::Handle(String::RawCast(js->LookupObjectParam("path"))); |
+ DevFS::ReadFile(js, fs_name, path); |
+ return true; |
+} |
+ |
+ |
+static const MethodParameter* list_dev_fs_files_params[] = { |
+ NO_ISOLATE_PARAMETER, |
+ new DartStringParameter("fsName", true), |
+ NULL, |
+}; |
+ |
+ |
+static bool ListDevFSFiles(Thread* thread, JSONStream* js) { |
+ const String& fs_name = |
+ String::Handle(String::RawCast(js->LookupObjectParam("fsName"))); |
+ DevFS::ListFiles(js, fs_name); |
+ return true; |
+} |
+ |
+ |
static const ServiceMethodDescriptor service_methods_[] = { |
{ "_dumpIdZone", DumpIdZone, NULL }, |
{ "_echo", Echo, |
@@ -4044,6 +4236,20 @@ static const ServiceMethodDescriptor service_methods_[] = { |
set_vm_name_params }, |
{ "_setVMTimelineFlags", SetVMTimelineFlags, |
set_vm_timeline_flags_params }, |
+ { "_createDevFS", CreateDevFS, |
+ create_dev_fs_params }, |
+ { "_deleteDevFS", DeleteDevFS, |
+ delete_dev_fs_params }, |
+ { "_listDevFS", ListDevFS, |
+ list_dev_fs_params }, |
+ { "_writeDevFSFile", WriteDevFSFile, |
+ write_dev_fs_file_params }, |
+ { "_writeDevFSFiles", WriteDevFSFiles, |
+ write_dev_fs_files_params }, |
+ { "_readDevFSFile", ReadDevFSFile, |
+ read_dev_fs_file_params }, |
+ { "_listDevFSFiles", ListDevFSFiles, |
+ list_dev_fs_files_params }, |
}; |