Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 8fe6d6f34104adc2a8a6243d9d17f5fc0e0c51c1..f1b5b3986d5671ea8835c08f08d3e2458b2926d4 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -5583,16 +5583,29 @@ 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()); |
| + return reinterpret_cast<RawFunction*>(Array::Cast(obj).At(1)); |
|
siva
2015/11/12 18:04:11
You can use Function::RawCast(Array::Cast(obj).At(
rmacnak
2015/11/12 23:51:15
RawCast doesn't allow null.
srdjan
2015/11/13 00:15:13
I think reinterpret_cast is quite unsafe. Either h
rmacnak
2015/11/13 01:24:15
Done.
|
| } |
| 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); |
| + } |
| } |
| @@ -5627,7 +5640,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. |
| @@ -5637,6 +5650,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(); |
| @@ -5740,6 +5754,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()); |
| } |
| @@ -5795,6 +5822,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()); |
| @@ -6700,7 +6745,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()); |
| } |
| } |
| } |
| @@ -8863,6 +8908,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; |