Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 5bc255d57599371c608528313db9d6c9586d2f7e..731c76771682b58b5a3801af298cd88e3dd9f434 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -5572,16 +5572,31 @@ RawFunction* Function::implicit_closure_function() const { |
return Function::null(); |
} |
const Object& obj = Object::Handle(raw_ptr()->data_); |
- ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction()); |
- return (obj.IsNull() || obj.IsScript()) ? Function::null() |
- : Function::Cast(obj).raw(); |
+ ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray()); |
+ if (obj.IsNull() || obj.IsScript()) { |
+ return Function::null(); |
+ } |
+ if (obj.IsFunction()) { |
+ return Function::Cast(obj).raw(); |
+ } |
+ ASSERT(is_native()); |
+ ASSERT(obj.IsArray()); |
+ const Object& res = Object::Handle(Array::Cast(obj).At(1)); |
+ return res.IsNull() ? Function::null() : Function::Cast(res).raw(); |
} |
void Function::set_implicit_closure_function(const Function& value) const { |
ASSERT(!IsClosureFunction() && !IsSignatureFunction()); |
- ASSERT(raw_ptr()->data_ == Object::null()); |
- set_data(value); |
+ if (is_native()) { |
+ const Object& obj = Object::Handle(raw_ptr()->data_); |
+ ASSERT(obj.IsArray()); |
+ ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); |
+ Array::Cast(obj).SetAt(1, value); |
+ } else { |
+ ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); |
+ set_data(value); |
+ } |
} |
@@ -5616,7 +5631,7 @@ void Function::set_signature_class(const Class& value) const { |
bool Function::IsRedirectingFactory() const { |
- if (!IsFactory() || (raw_ptr()->data_ == Object::null())) { |
+ if (!IsFactory() || !is_redirecting()) { |
return false; |
} |
ASSERT(!IsClosureFunction()); // A factory cannot also be a closure. |
@@ -5626,6 +5641,7 @@ bool Function::IsRedirectingFactory() const { |
RawType* Function::RedirectionType() const { |
ASSERT(IsRedirectingFactory()); |
+ ASSERT(!is_native()); |
const Object& obj = Object::Handle(raw_ptr()->data_); |
ASSERT(!obj.IsNull()); |
return RedirectionData::Cast(obj).type(); |
@@ -5729,6 +5745,19 @@ void Function::SetRedirectionTarget(const Function& target) const { |
} |
+// This field is heavily overloaded: |
+// eval function: Script expression source |
+// signature function: Class signature class |
+// method extractor: Function extracted closure function |
+// noSuchMethod dispatcher: Array arguments descriptor |
+// invoke-field dispatcher: Array arguments descriptor |
+// redirecting constructor: RedirectionData |
+// closure function: ClosureData |
+// irregexp function: Array[0] = JSRegExp |
+// Array[1] = Smi string specialization cid |
+// native function: Array[0] = String native name |
+// Array[1] = Function implicit closure function |
+// regular function: Function for implicit closure function |
void Function::set_data(const Object& value) const { |
StorePointer(&raw_ptr()->data_, value.raw()); |
} |
@@ -5784,6 +5813,24 @@ void Function::SetRegExpData(const JSRegExp& regexp, |
} |
+RawString* Function::native_name() const { |
+ ASSERT(is_native()); |
+ const Object& obj = Object::Handle(raw_ptr()->data_); |
+ ASSERT(obj.IsArray()); |
+ return String::RawCast(Array::Cast(obj).At(0)); |
+} |
+ |
+ |
+void Function::set_native_name(const String& value) const { |
+ ASSERT(is_native()); |
+ ASSERT(raw_ptr()->data_ == Object::null()); |
+ const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); |
+ pair.SetAt(0, value); |
+ // pair[1] will be the implicit closure function if needed. |
+ set_data(pair); |
+} |
+ |
+ |
void Function::set_result_type(const AbstractType& value) const { |
ASSERT(!value.IsNull()); |
StorePointer(&raw_ptr()->result_type_, value.raw()); |
@@ -6689,7 +6736,7 @@ void Function::DropUncompiledImplicitClosureFunction() const { |
if (implicit_closure_function() != Function::null()) { |
const Function& func = Function::Handle(implicit_closure_function()); |
if (!func.HasCode()) { |
- set_data(Object::null_object()); |
+ set_implicit_closure_function(Function::Handle()); |
} |
} |
} |
@@ -8710,6 +8757,10 @@ RawString* Script::Source() const { |
RawString* Script::GenerateSource() const { |
const TokenStream& token_stream = TokenStream::Handle(tokens()); |
+ if (token_stream.IsNull()) { |
+ ASSERT(Dart::IsRunningPrecompiledCode()); |
+ return String::null(); |
+ } |
return token_stream.GenerateSource(); |
} |
@@ -8873,6 +8924,17 @@ void Script::GetTokenLocation(intptr_t token_pos, |
intptr_t* token_len) const { |
ASSERT(line != NULL); |
const TokenStream& tkns = TokenStream::Handle(tokens()); |
+ if (tkns.IsNull()) { |
+ ASSERT(Dart::IsRunningPrecompiledCode()); |
+ *line = -1; |
+ if (column != NULL) { |
+ *column = -1; |
+ } |
+ if (token_len != NULL) { |
+ *token_len = 1; |
+ } |
+ return; |
+ } |
if (column == NULL) { |
TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens); |
intptr_t cur_line = line_offset() + 1; |
@@ -9115,10 +9177,12 @@ void Script::PrintJSONImpl(JSONStream* stream, bool ref) const { |
const String& source = String::Handle(Source()); |
jsobj.AddProperty("lineOffset", line_offset()); |
jsobj.AddProperty("columnOffset", col_offset()); |
- jsobj.AddPropertyStr("source", source); |
+ if (!source.IsNull()) { |
+ jsobj.AddPropertyStr("source", source); |
+ } |
// Print the line number table |
- { |
+ if (!source.IsNull()) { |
JSONArray tokenPosTable(&jsobj, "tokenPosTable"); |
const GrowableObjectArray& lineNumberArray = |