Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(882)

Unified Diff: runtime/vm/object.cc

Issue 98253009: Refactor VM service IDs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 99bad2b62e7bbfbef94cb75ac01409ab296be38c..8c78a6fdb5fab4d61067b7470c459006f7ed0f78 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1808,6 +1808,32 @@ void Class::AddFunction(const Function& function) const {
}
+intptr_t Class::FindFunctionIndex(const Function& needle) const {
+ Isolate* isolate = Isolate::Current();
+ if (EnsureIsFinalized(isolate) != Error::null()) {
+ return -1;
+ }
+ ReusableHandleScope reused_handles(isolate);
+ Array& funcs = reused_handles.ArrayHandle();
+ funcs ^= functions();
+ ASSERT(!funcs.IsNull());
+ Function& function = reused_handles.FunctionHandle();
+ String& function_name = reused_handles.StringHandle();
+ String& needle_name = String::Handle(isolate);
+ needle_name ^= needle.name();
+ const intptr_t len = funcs.Length();
+ for (intptr_t i = 0; i < len; i++) {
+ function ^= funcs.At(i);
+ function_name ^= function.name();
+ if (function_name.Equals(needle_name)) {
+ return i;
+ }
+ }
+ // No function found.
+ return -1;
+}
+
+
void Class::AddClosureFunction(const Function& function) const {
GrowableObjectArray& closures =
GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
@@ -1848,6 +1874,31 @@ RawFunction* Class::LookupClosureFunction(intptr_t token_pos) const {
return closure.raw();
}
+intptr_t Class::FindClosureIndex(intptr_t token_pos) const {
+ if (raw_ptr()->closure_functions_ == GrowableObjectArray::null()) {
+ return -1;
+ }
+ Isolate* isolate = Isolate::Current();
+ ReusableHandleScope reused_handles(isolate);
+ const GrowableObjectArray& closures =
+ GrowableObjectArray::Handle(isolate, raw_ptr()->closure_functions_);
+ Function& closure = reused_handles.FunctionHandle();
+ intptr_t num_closures = closures.Length();
+ intptr_t best_fit_token_pos = -1;
+ intptr_t best_fit_index = -1;
+ for (intptr_t i = 0; i < num_closures; i++) {
+ closure ^= closures.At(i);
+ ASSERT(!closure.IsNull());
+ if ((closure.token_pos() <= token_pos) &&
+ (token_pos <= closure.end_token_pos()) &&
+ (best_fit_token_pos < closure.token_pos())) {
+ best_fit_index = i;
+ best_fit_token_pos = closure.token_pos();
+ }
+ }
+ return best_fit_index;
+}
+
void Class::set_signature_function(const Function& value) const {
ASSERT(value.IsClosureFunction() || value.IsSignatureFunction());
@@ -2399,6 +2450,32 @@ void Class::SetFields(const Array& value) const {
}
+intptr_t Class::FindFieldIndex(const Field& needle) const {
+ Isolate* isolate = Isolate::Current();
+ if (EnsureIsFinalized(isolate) != Error::null()) {
+ return -1;
+ }
+ ReusableHandleScope reused_handles(isolate);
+ Array& fields_array = reused_handles.ArrayHandle();
+ fields_array ^= fields();
+ ASSERT(!fields_array.IsNull());
+ Field& field = reused_handles.FieldHandle();
+ String& field_name = reused_handles.StringHandle();
+ String& needle_name = String::Handle(isolate);
+ needle_name ^= needle.name();
+ const intptr_t len = fields_array.Length();
+ for (intptr_t i = 0; i < len; i++) {
+ field ^= fields_array.At(i);
+ field_name ^= field.name();
+ if (field_name.Equals(needle_name)) {
+ return i;
+ }
+ }
+ // No field found found.
+ return -1;
+}
+
+
template <class FakeInstance>
RawClass* Class::New(intptr_t index) {
ASSERT(Object::class_class() != Class::null());
@@ -3248,7 +3325,7 @@ void Class::PrintToJSONStream(JSONStream* stream, bool ref) const {
const char* user_visible_class_name =
String::Handle(UserVisibleName()).ToCString();
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddProperty("id", id());
+ jsobj.AddPropertyF("id", "classes/%" Pd "", id());
jsobj.AddProperty("name", internal_class_name);
jsobj.AddProperty("user_name", user_visible_class_name);
if (!ref) {
@@ -5619,11 +5696,26 @@ void Function::PrintToJSONStream(JSONStream* stream, bool ref) const {
const char* internal_function_name = String::Handle(name()).ToCString();
const char* function_name =
String::Handle(QualifiedUserVisibleName()).ToCString();
- ObjectIdRing* ring = Isolate::Current()->object_id_ring();
- intptr_t id = ring->GetIdForObject(raw());
+ Class& cls = Class::Handle(Owner());
+ Error& err = Error::Handle();
+ err ^= cls.EnsureIsFinalized(Isolate::Current());
+ ASSERT(err.IsNull());
+ const Function& func = *this;
+ intptr_t id = cls.FindFunctionIndex(func);
turnidge 2013/12/20 17:44:45 Did you end up trying the isClosure thing?
Cutch 2013/12/20 18:23:46 Yes, it doesn't work.
turnidge 2013/12/20 21:00:44 Can you try IsNonImplicitClosureFunction? Looking
+ bool closure = false;
+ if (id == -1) {
+ closure = true;
+ id = cls.FindClosureIndex(token_pos());
+ }
+ ASSERT(id >= 0);
+ intptr_t cid = cls.id();
JSONObject jsobj(stream);
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddProperty("id", id);
+ if (closure) {
+ jsobj.AddPropertyF("id", "classes/%" Pd "/closures/%" Pd "", cid, id);
+ } else {
+ jsobj.AddPropertyF("id", "classes/%" Pd "/functions/%" Pd "", cid, id);
+ }
jsobj.AddProperty("name", internal_function_name);
jsobj.AddProperty("user_name", function_name);
if (ref) return;
@@ -5952,10 +6044,12 @@ void Field::PrintToJSONStreamWithInstance(JSONStream* stream,
JSONObject jsobj(stream);
const char* internal_field_name = String::Handle(name()).ToCString();
const char* field_name = String::Handle(UserVisibleName()).ToCString();
- ObjectIdRing* ring = Isolate::Current()->object_id_ring();
- intptr_t id = ring->GetIdForObject(raw());
+ Class& cls = Class::Handle(owner());
+ intptr_t id = cls.FindFieldIndex(*this);
+ ASSERT(id >= 0);
+ intptr_t cid = cls.id();
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddProperty("id", id);
+ jsobj.AddPropertyF("id", "classes/%" Pd "/fields/%" Pd "", cid, id);
jsobj.AddProperty("name", internal_field_name);
jsobj.AddProperty("user_name", field_name);
if (is_static()) {
@@ -5965,7 +6059,7 @@ void Field::PrintToJSONStreamWithInstance(JSONStream* stream,
const Object& valueObj = Object::Handle(instance.GetField(*this));
jsobj.AddProperty("value", valueObj);
}
- Class& cls = Class::Handle(owner());
+
jsobj.AddProperty("owner", cls);
AbstractType& declared_type = AbstractType::Handle(type());
cls = declared_type.type_class();
@@ -7119,11 +7213,12 @@ const char* Script::ToCString() const {
void Script::PrintToJSONStream(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
- ObjectIdRing* ring = Isolate::Current()->object_id_ring();
- intptr_t id = ring->GetIdForObject(raw());
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddProperty("id", id);
const String& name = String::Handle(url());
+ ASSERT(!name.IsNull());
+ const String& encoded_url = String::Handle(String::EncodeURI(name));
+ ASSERT(!encoded_url.IsNull());
+ jsobj.AddPropertyF("id", "scripts/%s", encoded_url.ToCString());
jsobj.AddProperty("name", name.ToCString());
jsobj.AddProperty("kind", GetKindAsCString());
if (ref) {
@@ -8193,13 +8288,13 @@ const char* Library::ToCString() const {
void Library::PrintToJSONStream(JSONStream* stream, bool ref) const {
const char* library_name = String::Handle(name()).ToCString();
const char* library_url = String::Handle(url()).ToCString();
- ObjectIdRing* ring = Isolate::Current()->object_id_ring();
- intptr_t id = ring->GetIdForObject(raw());
+ intptr_t id = index();
+ ASSERT(id >= 0);
JSONObject jsobj(stream);
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddProperty("id", id);
+ jsobj.AddPropertyF("id", "libraries/%" Pd "", id);
jsobj.AddProperty("name", library_name);
- jsobj.AddProperty("url", library_url);
+ jsobj.AddProperty("user_name", library_url);
if (ref) return;
{
JSONArray jsarr(&jsobj, "classes");
@@ -9766,16 +9861,28 @@ const char* Code::ToCString() const {
void Code::PrintToJSONStream(JSONStream* stream, bool ref) const {
- ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+ Isolate* isolate = Isolate::Current();
+ ObjectIdRing* ring = isolate->object_id_ring();
intptr_t id = ring->GetIdForObject(raw());
JSONObject jsobj(stream);
+ jsobj.AddProperty("type", JSONType(ref));
+ jsobj.AddPropertyF("id", "objects/%" Pd "", id);
+ ReusableHandleScope reused_handles(isolate);
+ Function& func = reused_handles.FunctionHandle();
+ String& name = reused_handles.StringHandle();
+ func ^= function();
+ ASSERT(!func.IsNull());
+ name ^= func.name();
+ const char* internal_function_name = name.ToCString();
+ jsobj.AddPropertyF("name", "%s%s", is_optimized() ? "*" : "",
+ internal_function_name);
+ name ^= func.QualifiedUserVisibleName();
+ const char* function_name = name.ToCString();
+ jsobj.AddPropertyF("user_name", "%s%s", is_optimized() ? "*" : "",
+ function_name);
if (ref) {
- jsobj.AddProperty("type", "@Code");
- jsobj.AddProperty("id", id);
return;
}
- jsobj.AddProperty("type", "Code");
- jsobj.AddProperty("id", id);
jsobj.AddProperty("is_optimized", is_optimized());
jsobj.AddProperty("is_alive", is_alive());
jsobj.AddProperty("function", Object::Handle(function()));
@@ -11477,7 +11584,7 @@ void Instance::PrintToJSONStream(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
jsobj.AddProperty("type", JSONType(ref));
- jsobj.AddProperty("id", id);
+ jsobj.AddPropertyF("id", "objects/%" Pd "", id);
Class& cls = Class::Handle(this->clazz());
jsobj.AddProperty("class", cls);
@@ -14335,6 +14442,30 @@ RawString* String::EscapeSpecialCharacters(const String& str) {
}
+RawString* String::EncodeURI(const String& str) {
+ if (str.IsOneByteString()) {
+ return OneByteString::EncodeURI(str);
+ }
+ if (str.IsExternalOneByteString()) {
+ return ExternalOneByteString::EncodeURI(str);
+ }
+ UNREACHABLE();
+ return String::null();
+}
+
+
+RawString* String::DecodeURI(const String& str) {
+ if (str.IsOneByteString()) {
+ return OneByteString::DecodeURI(str);
+ }
+ if (str.IsExternalOneByteString()) {
+ return ExternalOneByteString::DecodeURI(str);
+ }
+ UNREACHABLE();
+ return String::null();
+}
+
+
RawString* String::NewFormatted(const char* format, ...) {
va_list args;
va_start(args, format);
@@ -14892,6 +15023,175 @@ RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters(
}
+static bool IsPercent(int32_t c) {
+ return c == '%';
+}
+
+static bool IsURISafeCharacter(int32_t c) {
+ if ((c >= '0') && (c <= '9')) {
+ return true;
+ }
+ if ((c >= 'a') && (c <= 'z')) {
+ return true;
+ }
+ if ((c >= 'A') && (c <= 'Z')) {
+ return true;
+ }
+ return (c == '-') || (c == '_') || (c == '.') || (c == '~');
+}
+
+
+static int32_t GetHexCharacter(int32_t c) {
+ ASSERT(c >= 0);
+ ASSERT(c < 16);
+ const char* hex = "0123456789ABCDEF";
+ return hex[c];
+}
+
+
+static int32_t GetHexValue(int32_t c) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ UNREACHABLE();
+ return 0;
+}
+
+
+static int32_t MergeHexCharacters(int32_t c1, int32_t c2) {
+ return GetHexValue(c1) << 4 | GetHexValue(c2);
+}
+
+
+RawOneByteString* OneByteString::EncodeURI(const String& str) {
turnidge 2013/12/20 17:44:45 Let's talk in person about Encode/Decode.
Cutch 2013/12/20 18:23:46 No need. It's fixed.
+ intptr_t len = str.Length();
+ if (len > 0) {
+ intptr_t num_escapes = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (!IsURISafeCharacter(*CharAddr(str, i))) {
+ num_escapes += 2;
+ }
+ }
+ const String& dststr = String::Handle(
+ OneByteString::New(len + num_escapes, Heap::kNew));
+ intptr_t index = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (!IsURISafeCharacter(*CharAddr(str, i))) {
+ *(CharAddr(dststr, index)) = '%';
+ int32_t ch = *CharAddr(str, i);
+ *(CharAddr(dststr, index + 1)) = GetHexCharacter(ch >> 4);
+ *(CharAddr(dststr, index + 2)) = GetHexCharacter(ch & 0xF);
+ index += 3;
+ } else {
+ *(CharAddr(dststr, index)) = *CharAddr(str, i);
+ index += 1;
+ }
+ }
+ return OneByteString::raw(dststr);
+ }
+ return OneByteString::raw(Symbols::Empty());
+}
+
+
+RawOneByteString* ExternalOneByteString::EncodeURI(const String& str) {
+ intptr_t len = str.Length();
+ if (len > 0) {
+ intptr_t num_escapes = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (!IsURISafeCharacter(*CharAddr(str, i))) {
+ num_escapes += 2;
+ }
+ }
+ const String& dststr = String::Handle(
+ OneByteString::New(len + num_escapes, Heap::kNew));
+ intptr_t index = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (!IsURISafeCharacter(*CharAddr(str, i))) {
+ *(OneByteString::CharAddr(dststr, index)) = '%';
+ int32_t ch = *CharAddr(str, i);
+ *(OneByteString::CharAddr(dststr, index + 1)) =
+ GetHexCharacter(ch >> 4);
+ *(OneByteString::CharAddr(dststr, index + 2)) =
+ GetHexCharacter(ch & 0xF);
+ index += 3;
+ } else {
+ *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i);
+ index += 1;
+ }
+ }
+ return OneByteString::raw(dststr);
+ }
+ return OneByteString::raw(Symbols::Empty());
+}
+
+
+RawOneByteString* OneByteString::DecodeURI(const String& str) {
+ intptr_t len = str.Length();
+ if (len > 0) {
+ intptr_t num_escapes = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (IsPercent(*CharAddr(str, i))) {
+ num_escapes += 2;
+ }
+ }
+ ASSERT(len - num_escapes > 0);
+ const String& dststr = String::Handle(
+ OneByteString::New(len - num_escapes, Heap::kNew));
+ intptr_t index = 0;
+ for (intptr_t i = 0; i < len;) {
+ if (IsPercent(*CharAddr(str, i))) {
+ int32_t ch1 = *CharAddr(str, i + 1);
+ int32_t ch2 = *CharAddr(str, i + 2);
+ int32_t merged = MergeHexCharacters(ch1, ch2);
+ *(CharAddr(dststr, index)) = merged;
+ i += 3;
+ } else {
+ *(CharAddr(dststr, index)) = *CharAddr(str, i);
+ i += 1;
+ }
+ index++;
+ }
+ return OneByteString::raw(dststr);
+ }
+ return OneByteString::raw(Symbols::Empty());
+}
+
+
+RawOneByteString* ExternalOneByteString::DecodeURI(const String& str) {
+ intptr_t len = str.Length();
+ if (len > 0) {
+ intptr_t num_escapes = 0;
+ for (intptr_t i = 0; i < len; i++) {
+ if (IsPercent(*CharAddr(str, i))) {
+ num_escapes += 2;
+ }
+ }
+ ASSERT(len - num_escapes > 0);
+ const String& dststr = String::Handle(
+ OneByteString::New(len - num_escapes, Heap::kNew));
+ intptr_t index = 0;
+ for (intptr_t i = 0; i < len;) {
+ if (IsPercent(*CharAddr(str, i))) {
+ int32_t ch1 = *CharAddr(str, i + 1);
+ int32_t ch2 = *CharAddr(str, i + 2);
+ int32_t merged = MergeHexCharacters(ch1, ch2);
+ *(OneByteString::CharAddr(dststr, index)) = merged;
+ i += 3;
+ } else {
+ *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i);
+ i += 1;
+ }
+ index++;
+ }
+ return OneByteString::raw(dststr);
+ }
+ return OneByteString::raw(Symbols::Empty());
+}
+
+
RawOneByteString* OneByteString::New(intptr_t len,
Heap::Space space) {
ASSERT(Isolate::Current() == Dart::vm_isolate() ||
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | runtime/vm/service.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698