| 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/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 2725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2736 piece ^= formal_params.At(i); | 2736 piece ^= formal_params.At(i); |
| 2737 src_pieces.Add(piece); | 2737 src_pieces.Add(piece); |
| 2738 } | 2738 } |
| 2739 src_pieces.Add(Symbols::RParenArrow()); | 2739 src_pieces.Add(Symbols::RParenArrow()); |
| 2740 src_pieces.Add(expr); | 2740 src_pieces.Add(expr); |
| 2741 src_pieces.Add(Symbols::Semicolon()); | 2741 src_pieces.Add(Symbols::Semicolon()); |
| 2742 return String::ConcatAll(Array::Handle(Array::MakeArray(src_pieces))); | 2742 return String::ConcatAll(Array::Handle(Array::MakeArray(src_pieces))); |
| 2743 } | 2743 } |
| 2744 | 2744 |
| 2745 | 2745 |
| 2746 static RawPatchClass* MakeTempPatchClass(const Class& cls, | 2746 static RawFunction* EvaluateHelper(const Class& cls, |
| 2747 const String& expr, | 2747 const String& expr, |
| 2748 const Array& formal_params) { | 2748 const Array& param_names, |
| 2749 bool is_static) { |
| 2749 const String& func_src = | 2750 const String& func_src = |
| 2750 String::Handle(BuildClosureSource(formal_params, expr)); | 2751 String::Handle(BuildClosureSource(param_names, expr)); |
| 2751 Script& script = Script::Handle(); | 2752 Script& script = Script::Handle(); |
| 2752 script = Script::New(Symbols::Empty(), func_src, RawScript::kSourceTag); | 2753 script = Script::New(Symbols::Empty(), func_src, RawScript::kSourceTag); |
| 2753 // In order to tokenize the source, we need to get the key to mangle | 2754 // In order to tokenize the source, we need to get the key to mangle |
| 2754 // private names from the library from which the object's class | 2755 // private names from the library from which the class originates. |
| 2755 // originates. | |
| 2756 const Library& lib = Library::Handle(cls.library()); | 2756 const Library& lib = Library::Handle(cls.library()); |
| 2757 ASSERT(!lib.IsNull()); | 2757 ASSERT(!lib.IsNull()); |
| 2758 const String& lib_key = String::Handle(lib.private_key()); | 2758 const String& lib_key = String::Handle(lib.private_key()); |
| 2759 script.Tokenize(lib_key); | 2759 script.Tokenize(lib_key); |
| 2760 | 2760 |
| 2761 const String& src_class_name = String::Handle(Symbols::New(":internal")); | 2761 const Function& func = Function::Handle( |
| 2762 const Class& src_class = Class::Handle( | 2762 Function::NewEvalFunction(cls, script, is_static)); |
| 2763 Class::New(src_class_name, script, Scanner::kNoSourcePos)); | 2763 func.set_result_type(Type::Handle(Type::DynamicType())); |
| 2764 src_class.set_is_finalized(); | 2764 const intptr_t num_implicit_params = is_static ? 0 : 1; |
| 2765 src_class.set_library(lib); | 2765 func.set_num_fixed_parameters(num_implicit_params + param_names.Length()); |
| 2766 return PatchClass::New(cls, src_class); | 2766 func.SetNumOptionalParameters(0, true); |
| 2767 func.SetIsOptimizable(false); |
| 2768 return func.raw(); |
| 2767 } | 2769 } |
| 2768 | 2770 |
| 2769 | 2771 |
| 2770 RawObject* Class::Evaluate(const String& expr, | 2772 RawObject* Class::Evaluate(const String& expr, |
| 2771 const Array& param_names, | 2773 const Array& param_names, |
| 2772 const Array& param_values) const { | 2774 const Array& param_values) const { |
| 2773 const PatchClass& temp_class = | |
| 2774 PatchClass::Handle(MakeTempPatchClass(*this, expr, param_names)); | |
| 2775 const String& eval_func_name = String::Handle(Symbols::New(":eval")); | |
| 2776 const Function& eval_func = | 2775 const Function& eval_func = |
| 2777 Function::Handle(Function::New(eval_func_name, | 2776 Function::Handle(EvaluateHelper(*this, expr, param_names, true)); |
| 2778 RawFunction::kRegularFunction, | |
| 2779 true, // Static. | |
| 2780 false, // Not const. | |
| 2781 false, // Not abstract. | |
| 2782 false, // Not external. | |
| 2783 false, // Not native. | |
| 2784 temp_class, | |
| 2785 0)); | |
| 2786 eval_func.set_result_type(Type::Handle(Type::DynamicType())); | |
| 2787 eval_func.set_num_fixed_parameters(param_names.Length()); | |
| 2788 eval_func.SetNumOptionalParameters(0, true); | |
| 2789 eval_func.SetIsOptimizable(false); | |
| 2790 | |
| 2791 const Object& result = | 2777 const Object& result = |
| 2792 Object::Handle(DartEntry::InvokeFunction(eval_func, param_values)); | 2778 Object::Handle(DartEntry::InvokeFunction(eval_func, param_values)); |
| 2793 return result.raw(); | 2779 return result.raw(); |
| 2794 } | 2780 } |
| 2795 | 2781 |
| 2796 | 2782 |
| 2797 // Ensure that top level parsing of the class has been done. | 2783 // Ensure that top level parsing of the class has been done. |
| 2798 RawError* Class::EnsureIsFinalized(Isolate* isolate) const { | 2784 RawError* Class::EnsureIsFinalized(Isolate* isolate) const { |
| 2799 // Finalized classes have already been parsed. | 2785 // Finalized classes have already been parsed. |
| 2800 if (is_finalized()) { | 2786 if (is_finalized()) { |
| (...skipping 2265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5066 if (IsImplicitStaticClosureFunction()) { | 5052 if (IsImplicitStaticClosureFunction()) { |
| 5067 const Object& obj = Object::Handle(raw_ptr()->data_); | 5053 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5068 ASSERT(!obj.IsNull()); | 5054 ASSERT(!obj.IsNull()); |
| 5069 ClosureData::Cast(obj).set_implicit_static_closure(closure); | 5055 ClosureData::Cast(obj).set_implicit_static_closure(closure); |
| 5070 return; | 5056 return; |
| 5071 } | 5057 } |
| 5072 UNREACHABLE(); | 5058 UNREACHABLE(); |
| 5073 } | 5059 } |
| 5074 | 5060 |
| 5075 | 5061 |
| 5062 RawScript* Function::eval_script() const { |
| 5063 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5064 if (obj.IsScript()) { |
| 5065 return Script::Cast(obj).raw(); |
| 5066 } |
| 5067 return Script::null(); |
| 5068 } |
| 5069 |
| 5070 |
| 5071 void Function::set_eval_script(const Script& script) const { |
| 5072 ASSERT(token_pos() == 0); |
| 5073 ASSERT(raw_ptr()->data_ == Object::null()); |
| 5074 set_data(script); |
| 5075 } |
| 5076 |
| 5077 |
| 5076 RawFunction* Function::extracted_method_closure() const { | 5078 RawFunction* Function::extracted_method_closure() const { |
| 5077 ASSERT(kind() == RawFunction::kMethodExtractor); | 5079 ASSERT(kind() == RawFunction::kMethodExtractor); |
| 5078 const Object& obj = Object::Handle(raw_ptr()->data_); | 5080 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5079 ASSERT(obj.IsFunction()); | 5081 ASSERT(obj.IsFunction()); |
| 5080 return Function::Cast(obj).raw(); | 5082 return Function::Cast(obj).raw(); |
| 5081 } | 5083 } |
| 5082 | 5084 |
| 5083 | 5085 |
| 5084 void Function::set_extracted_method_closure(const Function& value) const { | 5086 void Function::set_extracted_method_closure(const Function& value) const { |
| 5085 ASSERT(kind() == RawFunction::kMethodExtractor); | 5087 ASSERT(kind() == RawFunction::kMethodExtractor); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5142 | 5144 |
| 5143 | 5145 |
| 5144 RawFunction* Function::implicit_closure_function() const { | 5146 RawFunction* Function::implicit_closure_function() const { |
| 5145 if (IsClosureFunction() || | 5147 if (IsClosureFunction() || |
| 5146 IsSignatureFunction() || | 5148 IsSignatureFunction() || |
| 5147 IsStaticInitializerFunction() || | 5149 IsStaticInitializerFunction() || |
| 5148 IsFactory()) { | 5150 IsFactory()) { |
| 5149 return Function::null(); | 5151 return Function::null(); |
| 5150 } | 5152 } |
| 5151 const Object& obj = Object::Handle(raw_ptr()->data_); | 5153 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5152 ASSERT(obj.IsNull() || obj.IsFunction()); | 5154 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction()); |
| 5153 return (obj.IsNull()) ? Function::null() : Function::Cast(obj).raw(); | 5155 return (obj.IsNull() || obj.IsScript()) ? Function::null() |
| 5156 : Function::Cast(obj).raw(); |
| 5154 } | 5157 } |
| 5155 | 5158 |
| 5156 | 5159 |
| 5157 void Function::set_implicit_closure_function(const Function& value) const { | 5160 void Function::set_implicit_closure_function(const Function& value) const { |
| 5158 ASSERT(!IsClosureFunction() && !IsSignatureFunction()); | 5161 ASSERT(!IsClosureFunction() && !IsSignatureFunction()); |
| 5162 ASSERT(raw_ptr()->data_ == Object::null()); |
| 5159 set_data(value); | 5163 set_data(value); |
| 5160 } | 5164 } |
| 5161 | 5165 |
| 5162 | 5166 |
| 5163 RawClass* Function::signature_class() const { | 5167 RawClass* Function::signature_class() const { |
| 5164 if (IsSignatureFunction()) { | 5168 if (IsSignatureFunction()) { |
| 5165 const Object& obj = Object::Handle(raw_ptr()->data_); | 5169 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5166 ASSERT(obj.IsNull() || obj.IsClass()); | 5170 ASSERT(obj.IsNull() || obj.IsClass()); |
| 5167 return (obj.IsNull()) ? Class::null() : Class::Cast(obj).raw(); | 5171 return (obj.IsNull()) ? Class::null() : Class::Cast(obj).raw(); |
| 5168 } | 5172 } |
| (...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6072 Function::New(name, | 6076 Function::New(name, |
| 6073 RawFunction::kClosureFunction, | 6077 RawFunction::kClosureFunction, |
| 6074 /* is_static = */ parent.is_static(), | 6078 /* is_static = */ parent.is_static(), |
| 6075 /* is_const = */ false, | 6079 /* is_const = */ false, |
| 6076 /* is_abstract = */ false, | 6080 /* is_abstract = */ false, |
| 6077 /* is_external = */ false, | 6081 /* is_external = */ false, |
| 6078 parent.is_native(), | 6082 parent.is_native(), |
| 6079 parent_owner, | 6083 parent_owner, |
| 6080 token_pos)); | 6084 token_pos)); |
| 6081 result.set_parent_function(parent); | 6085 result.set_parent_function(parent); |
| 6082 | |
| 6083 return result.raw(); | 6086 return result.raw(); |
| 6084 } | 6087 } |
| 6085 | 6088 |
| 6086 | 6089 |
| 6090 RawFunction* Function::NewEvalFunction(const Class& owner, |
| 6091 const Script& script, |
| 6092 bool is_static) { |
| 6093 const Function& result = Function::Handle( |
| 6094 Function::New(String::Handle(Symbols::New(":Eval")), |
| 6095 RawFunction::kRegularFunction, |
| 6096 is_static, |
| 6097 /* is_const = */ false, |
| 6098 /* is_abstract = */ false, |
| 6099 /* is_external = */ false, |
| 6100 /* is_native = */ false, |
| 6101 owner, |
| 6102 0)); |
| 6103 ASSERT(!script.IsNull()); |
| 6104 result.set_eval_script(script); |
| 6105 return result.raw(); |
| 6106 } |
| 6107 |
| 6087 RawFunction* Function::ImplicitClosureFunction() const { | 6108 RawFunction* Function::ImplicitClosureFunction() const { |
| 6088 // Return the existing implicit closure function if any. | 6109 // Return the existing implicit closure function if any. |
| 6089 if (implicit_closure_function() != Function::null()) { | 6110 if (implicit_closure_function() != Function::null()) { |
| 6090 return implicit_closure_function(); | 6111 return implicit_closure_function(); |
| 6091 } | 6112 } |
| 6092 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); | 6113 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); |
| 6093 // Create closure function. | 6114 // Create closure function. |
| 6094 const String& closure_name = String::Handle(name()); | 6115 const String& closure_name = String::Handle(name()); |
| 6095 const Function& closure_function = Function::Handle( | 6116 const Function& closure_function = Function::Handle( |
| 6096 NewClosureFunction(closure_name, *this, token_pos())); | 6117 NewClosureFunction(closure_name, *this, token_pos())); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6342 const Object& obj = Object::Handle(raw_ptr()->owner_); | 6363 const Object& obj = Object::Handle(raw_ptr()->owner_); |
| 6343 if (obj.IsClass()) { | 6364 if (obj.IsClass()) { |
| 6344 return Class::Cast(obj).raw(); | 6365 return Class::Cast(obj).raw(); |
| 6345 } | 6366 } |
| 6346 ASSERT(obj.IsPatchClass()); | 6367 ASSERT(obj.IsPatchClass()); |
| 6347 return PatchClass::Cast(obj).source_class(); | 6368 return PatchClass::Cast(obj).source_class(); |
| 6348 } | 6369 } |
| 6349 | 6370 |
| 6350 | 6371 |
| 6351 RawScript* Function::script() const { | 6372 RawScript* Function::script() const { |
| 6373 if (token_pos() == 0) { |
| 6374 // Testing for position 0 is an optimization that relies on temporary |
| 6375 // eval functions having token position 0. |
| 6376 const Script& script = Script::Handle(eval_script()); |
| 6377 if (!script.IsNull()) { |
| 6378 return script.raw(); |
| 6379 } |
| 6380 } |
| 6381 if (IsClosureFunction()) { |
| 6382 return Function::Handle(parent_function()).script(); |
| 6383 } |
| 6352 const Object& obj = Object::Handle(raw_ptr()->owner_); | 6384 const Object& obj = Object::Handle(raw_ptr()->owner_); |
| 6353 if (obj.IsClass()) { | 6385 if (obj.IsClass()) { |
| 6354 return Class::Cast(obj).script(); | 6386 return Class::Cast(obj).script(); |
| 6355 } | 6387 } |
| 6356 ASSERT(obj.IsPatchClass()); | 6388 ASSERT(obj.IsPatchClass()); |
| 6357 return PatchClass::Cast(obj).Script(); | 6389 return PatchClass::Cast(obj).Script(); |
| 6358 } | 6390 } |
| 6359 | 6391 |
| 6360 | 6392 |
| 6361 bool Function::HasOptimizedCode() const { | 6393 bool Function::HasOptimizedCode() const { |
| (...skipping 2907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9269 // classes are coming from the VM isolate, and are shared between multiple | 9301 // classes are coming from the VM isolate, and are shared between multiple |
| 9270 // isolates so setting their library pointers would be wrong. | 9302 // isolates so setting their library pointers would be wrong. |
| 9271 const Class& cls = Class::Handle(Object::dynamic_class()); | 9303 const Class& cls = Class::Handle(Object::dynamic_class()); |
| 9272 core_lib.AddObject(cls, String::Handle(cls.Name())); | 9304 core_lib.AddObject(cls, String::Handle(cls.Name())); |
| 9273 } | 9305 } |
| 9274 | 9306 |
| 9275 | 9307 |
| 9276 RawObject* Library::Evaluate(const String& expr, | 9308 RawObject* Library::Evaluate(const String& expr, |
| 9277 const Array& param_names, | 9309 const Array& param_names, |
| 9278 const Array& param_values) const { | 9310 const Array& param_values) const { |
| 9279 // Make a fake top-level class and evaluate the expression | 9311 // Take or make a fake top-level class and evaluate the expression |
| 9280 // as a static function of the class. | 9312 // as a static function of the class. |
| 9281 Script& script = Script::Handle(); | 9313 Class& top_level_class = Class::Handle(); |
| 9282 script = Script::New(Symbols::Empty(), | 9314 Array& top_level_classes = Array::Handle(anonymous_classes()); |
| 9283 Symbols::Empty(), | 9315 if (top_level_classes.Length() > 0) { |
| 9284 RawScript::kSourceTag); | 9316 top_level_class ^= top_level_classes.At(0); |
| 9285 Class& temp_class = | 9317 } else { |
| 9286 Class::Handle(Class::New(Symbols::TopLevel(), script, 0)); | 9318 // A library may have no top-level classes if it has no top-level |
| 9287 temp_class.set_library(*this); | 9319 // variables or methods. |
| 9288 temp_class.set_is_finalized(); | 9320 Script& script = Script::Handle(Script::New(Symbols::Empty(), |
| 9289 return temp_class.Evaluate(expr, param_names, param_values); | 9321 Symbols::Empty(), |
| 9322 RawScript::kSourceTag)); |
| 9323 top_level_class = Class::New(Symbols::TopLevel(), script, 0); |
| 9324 top_level_class.set_is_finalized(); |
| 9325 top_level_class.set_library(*this); |
| 9326 AddAnonymousClass(top_level_class); |
| 9327 } |
| 9328 ASSERT(top_level_class.is_finalized()); |
| 9329 return top_level_class.Evaluate(expr, param_names, param_values); |
| 9290 } | 9330 } |
| 9291 | 9331 |
| 9292 | 9332 |
| 9293 void Library::InitNativeWrappersLibrary(Isolate* isolate) { | 9333 void Library::InitNativeWrappersLibrary(Isolate* isolate) { |
| 9294 static const int kNumNativeWrappersClasses = 4; | 9334 static const int kNumNativeWrappersClasses = 4; |
| 9295 ASSERT(kNumNativeWrappersClasses > 0 && kNumNativeWrappersClasses < 10); | 9335 ASSERT(kNumNativeWrappersClasses > 0 && kNumNativeWrappersClasses < 10); |
| 9296 const String& native_flds_lib_url = Symbols::DartNativeWrappers(); | 9336 const String& native_flds_lib_url = Symbols::DartNativeWrappers(); |
| 9297 const Library& native_flds_lib = Library::Handle( | 9337 const Library& native_flds_lib = Library::Handle( |
| 9298 Library::NewLibraryHelper(native_flds_lib_url, false)); | 9338 Library::NewLibraryHelper(native_flds_lib_url, false)); |
| 9299 const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); | 9339 const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); |
| (...skipping 3452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12752 jsobj.AddProperty("id", ""); | 12792 jsobj.AddProperty("id", ""); |
| 12753 jsobj.AddProperty("kind", JSONType(false)); | 12793 jsobj.AddProperty("kind", JSONType(false)); |
| 12754 jsobj.AddProperty("message", ToErrorCString()); | 12794 jsobj.AddProperty("message", ToErrorCString()); |
| 12755 } | 12795 } |
| 12756 | 12796 |
| 12757 | 12797 |
| 12758 RawObject* Instance::Evaluate(const String& expr, | 12798 RawObject* Instance::Evaluate(const String& expr, |
| 12759 const Array& param_names, | 12799 const Array& param_names, |
| 12760 const Array& param_values) const { | 12800 const Array& param_values) const { |
| 12761 const Class& cls = Class::Handle(clazz()); | 12801 const Class& cls = Class::Handle(clazz()); |
| 12762 const PatchClass& temp_class = PatchClass::Handle( | |
| 12763 MakeTempPatchClass(cls, expr, param_names)); | |
| 12764 const String& eval_func_name = String::Handle(Symbols::New(":eval")); | |
| 12765 const Function& eval_func = | 12802 const Function& eval_func = |
| 12766 Function::Handle(Function::New(eval_func_name, | 12803 Function::Handle(EvaluateHelper(cls, expr, param_names, false)); |
| 12767 RawFunction::kRegularFunction, | |
| 12768 false, // Not static. | |
| 12769 false, // Not const. | |
| 12770 false, // Not abstract. | |
| 12771 false, // Not external. | |
| 12772 false, // Not native. | |
| 12773 temp_class, | |
| 12774 0)); | |
| 12775 eval_func.set_result_type(Type::Handle(Type::DynamicType())); | |
| 12776 eval_func.set_num_fixed_parameters(1 + param_values.Length()); | |
| 12777 eval_func.SetNumOptionalParameters(0, true); | |
| 12778 eval_func.SetIsOptimizable(false); | |
| 12779 | |
| 12780 const Array& args = Array::Handle(Array::New(1 + param_values.Length())); | 12804 const Array& args = Array::Handle(Array::New(1 + param_values.Length())); |
| 12781 Object& param = Object::Handle(); | 12805 Object& param = Object::Handle(); |
| 12782 args.SetAt(0, *this); | 12806 args.SetAt(0, *this); |
| 12783 for (intptr_t i = 0; i < param_values.Length(); i++) { | 12807 for (intptr_t i = 0; i < param_values.Length(); i++) { |
| 12784 param = param_values.At(i); | 12808 param = param_values.At(i); |
| 12785 args.SetAt(i + 1, param); | 12809 args.SetAt(i + 1, param); |
| 12786 } | 12810 } |
| 12787 const Object& result = | 12811 const Object& result = |
| 12788 Object::Handle(DartEntry::InvokeFunction(eval_func, args)); | 12812 Object::Handle(DartEntry::InvokeFunction(eval_func, args)); |
| 12789 return result.raw(); | 12813 return result.raw(); |
| (...skipping 6261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19051 return tag_label.ToCString(); | 19075 return tag_label.ToCString(); |
| 19052 } | 19076 } |
| 19053 | 19077 |
| 19054 | 19078 |
| 19055 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 19079 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 19056 Instance::PrintJSONImpl(stream, ref); | 19080 Instance::PrintJSONImpl(stream, ref); |
| 19057 } | 19081 } |
| 19058 | 19082 |
| 19059 | 19083 |
| 19060 } // namespace dart | 19084 } // namespace dart |
| OLD | NEW |