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

Side by Side Diff: runtime/vm/object.cc

Issue 379353003: Implement Evaluate without creating new classes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 if (IsEvalFunction()) {
5064 const Object& obj = Object::Handle(raw_ptr()->data_);
5065 ASSERT(!obj.IsNull());
5066 return Script::Cast(obj).raw();
5067 }
5068 return Script::null();
5069 }
5070
5071
5072 void Function::set_eval_script(const Script& script) const {
5073 if (IsEvalFunction()) {
5074 ASSERT(!script.IsNull());
5075 set_data(script);
5076 return;
5077 }
5078 UNREACHABLE();
5079 }
5080
5081
5076 RawFunction* Function::extracted_method_closure() const { 5082 RawFunction* Function::extracted_method_closure() const {
5077 ASSERT(kind() == RawFunction::kMethodExtractor); 5083 ASSERT(kind() == RawFunction::kMethodExtractor);
5078 const Object& obj = Object::Handle(raw_ptr()->data_); 5084 const Object& obj = Object::Handle(raw_ptr()->data_);
5079 ASSERT(obj.IsFunction()); 5085 ASSERT(obj.IsFunction());
5080 return Function::Cast(obj).raw(); 5086 return Function::Cast(obj).raw();
5081 } 5087 }
5082 5088
5083 5089
5084 void Function::set_extracted_method_closure(const Function& value) const { 5090 void Function::set_extracted_method_closure(const Function& value) const {
5085 ASSERT(kind() == RawFunction::kMethodExtractor); 5091 ASSERT(kind() == RawFunction::kMethodExtractor);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5138 return; 5144 return;
5139 } 5145 }
5140 UNREACHABLE(); 5146 UNREACHABLE();
5141 } 5147 }
5142 5148
5143 5149
5144 RawFunction* Function::implicit_closure_function() const { 5150 RawFunction* Function::implicit_closure_function() const {
5145 if (IsClosureFunction() || 5151 if (IsClosureFunction() ||
5146 IsSignatureFunction() || 5152 IsSignatureFunction() ||
5147 IsStaticInitializerFunction() || 5153 IsStaticInitializerFunction() ||
5148 IsFactory()) { 5154 IsFactory() ||
5155 IsEvalFunction()) {
5149 return Function::null(); 5156 return Function::null();
5150 } 5157 }
5151 const Object& obj = Object::Handle(raw_ptr()->data_); 5158 const Object& obj = Object::Handle(raw_ptr()->data_);
5152 ASSERT(obj.IsNull() || obj.IsFunction()); 5159 ASSERT(obj.IsNull() || obj.IsFunction());
5153 return (obj.IsNull()) ? Function::null() : Function::Cast(obj).raw(); 5160 return (obj.IsNull()) ? Function::null() : Function::Cast(obj).raw();
5154 } 5161 }
5155 5162
5156 5163
5157 void Function::set_implicit_closure_function(const Function& value) const { 5164 void Function::set_implicit_closure_function(const Function& value) const {
5158 ASSERT(!IsClosureFunction() && !IsSignatureFunction()); 5165 ASSERT(!IsClosureFunction() && !IsSignatureFunction() && !IsEvalFunction());
5159 set_data(value); 5166 set_data(value);
5160 } 5167 }
5161 5168
5162 5169
5163 RawClass* Function::signature_class() const { 5170 RawClass* Function::signature_class() const {
5164 if (IsSignatureFunction()) { 5171 if (IsSignatureFunction()) {
5165 const Object& obj = Object::Handle(raw_ptr()->data_); 5172 const Object& obj = Object::Handle(raw_ptr()->data_);
5166 ASSERT(obj.IsNull() || obj.IsClass()); 5173 ASSERT(obj.IsNull() || obj.IsClass());
5167 return (obj.IsNull()) ? Class::null() : Class::Cast(obj).raw(); 5174 return (obj.IsNull()) ? Class::null() : Class::Cast(obj).raw();
5168 } 5175 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
5241 break; 5248 break;
5242 case RawFunction::kMethodExtractor: 5249 case RawFunction::kMethodExtractor:
5243 return "kMethodExtractor"; 5250 return "kMethodExtractor";
5244 break; 5251 break;
5245 case RawFunction::kNoSuchMethodDispatcher: 5252 case RawFunction::kNoSuchMethodDispatcher:
5246 return "kNoSuchMethodDispatcher"; 5253 return "kNoSuchMethodDispatcher";
5247 break; 5254 break;
5248 case RawFunction::kInvokeFieldDispatcher: 5255 case RawFunction::kInvokeFieldDispatcher:
5249 return "kInvokeFieldDispatcher"; 5256 return "kInvokeFieldDispatcher";
5250 break; 5257 break;
5258 case RawFunction::kEvalFunction:
5259 return "kEvalFunction";
5260 break;
5251 default: 5261 default:
5252 UNREACHABLE(); 5262 UNREACHABLE();
5253 return NULL; 5263 return NULL;
5254 } 5264 }
5255 } 5265 }
5256 5266
5257 5267
5258 void Function::SetRedirectionType(const Type& type) const { 5268 void Function::SetRedirectionType(const Type& type) const {
5259 ASSERT(IsFactory()); 5269 ASSERT(IsFactory());
5260 Object& obj = Object::Handle(raw_ptr()->data_); 5270 Object& obj = Object::Handle(raw_ptr()->data_);
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
6072 Function::New(name, 6082 Function::New(name,
6073 RawFunction::kClosureFunction, 6083 RawFunction::kClosureFunction,
6074 /* is_static = */ parent.is_static(), 6084 /* is_static = */ parent.is_static(),
6075 /* is_const = */ false, 6085 /* is_const = */ false,
6076 /* is_abstract = */ false, 6086 /* is_abstract = */ false,
6077 /* is_external = */ false, 6087 /* is_external = */ false,
6078 parent.is_native(), 6088 parent.is_native(),
6079 parent_owner, 6089 parent_owner,
6080 token_pos)); 6090 token_pos));
6081 result.set_parent_function(parent); 6091 result.set_parent_function(parent);
6082
6083 return result.raw(); 6092 return result.raw();
6084 } 6093 }
6085 6094
6086 6095
6096 RawFunction* Function::NewEvalFunction(const Class& owner,
6097 const Script& script,
6098 bool is_static) {
6099 ASSERT(!owner.IsNull());
6100 ASSERT(!script.IsNull());
6101 const Function& result = Function::Handle(
6102 Function::New(String::Handle(Symbols::New(":Eval")),
6103 RawFunction::kEvalFunction,
6104 is_static,
6105 /* is_const = */ false,
6106 /* is_abstract = */ false,
6107 /* is_external = */ false,
6108 /* is_native = */ false,
6109 owner,
6110 0));
6111 result.set_eval_script(script);
6112 return result.raw();
6113 }
6114
6087 RawFunction* Function::ImplicitClosureFunction() const { 6115 RawFunction* Function::ImplicitClosureFunction() const {
6088 // Return the existing implicit closure function if any. 6116 // Return the existing implicit closure function if any.
6089 if (implicit_closure_function() != Function::null()) { 6117 if (implicit_closure_function() != Function::null()) {
6090 return implicit_closure_function(); 6118 return implicit_closure_function();
6091 } 6119 }
6092 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); 6120 ASSERT(!IsSignatureFunction() && !IsClosureFunction());
6093 // Create closure function. 6121 // Create closure function.
6094 const String& closure_name = String::Handle(name()); 6122 const String& closure_name = String::Handle(name());
6095 const Function& closure_function = Function::Handle( 6123 const Function& closure_function = Function::Handle(
6096 NewClosureFunction(closure_name, *this, token_pos())); 6124 NewClosureFunction(closure_name, *this, token_pos()));
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
6341 RawClass* Function::origin() const { 6369 RawClass* Function::origin() const {
6342 const Object& obj = Object::Handle(raw_ptr()->owner_); 6370 const Object& obj = Object::Handle(raw_ptr()->owner_);
6343 if (obj.IsClass()) { 6371 if (obj.IsClass()) {
6344 return Class::Cast(obj).raw(); 6372 return Class::Cast(obj).raw();
6345 } 6373 }
6346 ASSERT(obj.IsPatchClass()); 6374 ASSERT(obj.IsPatchClass());
6347 return PatchClass::Cast(obj).source_class(); 6375 return PatchClass::Cast(obj).source_class();
6348 } 6376 }
6349 6377
6350 6378
6351 RawScript* Function::script() const { 6379 RawScript* Function::script() const {
hausner 2014/07/10 20:12:34 I think it should be possible to do the trick of s
6380 if (IsEvalFunction()) {
6381 return eval_script();
6382 }
6383 if (IsClosureFunction()) {
6384 return Function::Handle(parent_function()).script();
6385 }
6352 const Object& obj = Object::Handle(raw_ptr()->owner_); 6386 const Object& obj = Object::Handle(raw_ptr()->owner_);
6353 if (obj.IsClass()) { 6387 if (obj.IsClass()) {
6354 return Class::Cast(obj).script(); 6388 return Class::Cast(obj).script();
6355 } 6389 }
6356 ASSERT(obj.IsPatchClass()); 6390 ASSERT(obj.IsPatchClass());
6357 return PatchClass::Cast(obj).Script(); 6391 return PatchClass::Cast(obj).Script();
6358 } 6392 }
6359 6393
6360 6394
6361 bool Function::HasOptimizedCode() const { 6395 bool Function::HasOptimizedCode() const {
(...skipping 2907 matching lines...) Expand 10 before | Expand all | Expand 10 after
9269 // classes are coming from the VM isolate, and are shared between multiple 9303 // classes are coming from the VM isolate, and are shared between multiple
9270 // isolates so setting their library pointers would be wrong. 9304 // isolates so setting their library pointers would be wrong.
9271 const Class& cls = Class::Handle(Object::dynamic_class()); 9305 const Class& cls = Class::Handle(Object::dynamic_class());
9272 core_lib.AddObject(cls, String::Handle(cls.Name())); 9306 core_lib.AddObject(cls, String::Handle(cls.Name()));
9273 } 9307 }
9274 9308
9275 9309
9276 RawObject* Library::Evaluate(const String& expr, 9310 RawObject* Library::Evaluate(const String& expr,
9277 const Array& param_names, 9311 const Array& param_names,
9278 const Array& param_values) const { 9312 const Array& param_values) const {
9279 // Make a fake top-level class and evaluate the expression 9313 // Take a fake top-level class and evaluate the expression
9280 // as a static function of the class. 9314 // as a static function of the class.
9281 Script& script = Script::Handle(); 9315 Class& top_level_class = Class::Handle();
9282 script = Script::New(Symbols::Empty(), 9316 Array& top_level_classes = Array::Handle(anonymous_classes());
9283 Symbols::Empty(), 9317 top_level_class ^= top_level_classes.At(0);
hausner 2014/07/10 20:12:34 I'm not sure this array is guaranteed to have entr
rmacnak 2014/07/10 22:26:21 That can happen. Now creating and remembering a cl
9284 RawScript::kSourceTag); 9318 return top_level_class.Evaluate(expr, param_names, param_values);
9285 Class& temp_class =
9286 Class::Handle(Class::New(Symbols::TopLevel(), script, 0));
9287 temp_class.set_library(*this);
9288 temp_class.set_is_finalized();
9289 return temp_class.Evaluate(expr, param_names, param_values);
9290 } 9319 }
9291 9320
9292 9321
9293 void Library::InitNativeWrappersLibrary(Isolate* isolate) { 9322 void Library::InitNativeWrappersLibrary(Isolate* isolate) {
9294 static const int kNumNativeWrappersClasses = 4; 9323 static const int kNumNativeWrappersClasses = 4;
9295 ASSERT(kNumNativeWrappersClasses > 0 && kNumNativeWrappersClasses < 10); 9324 ASSERT(kNumNativeWrappersClasses > 0 && kNumNativeWrappersClasses < 10);
9296 const String& native_flds_lib_url = Symbols::DartNativeWrappers(); 9325 const String& native_flds_lib_url = Symbols::DartNativeWrappers();
9297 const Library& native_flds_lib = Library::Handle( 9326 const Library& native_flds_lib = Library::Handle(
9298 Library::NewLibraryHelper(native_flds_lib_url, false)); 9327 Library::NewLibraryHelper(native_flds_lib_url, false));
9299 const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); 9328 const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName();
(...skipping 3455 matching lines...) Expand 10 before | Expand all | Expand 10 after
12755 jsobj.AddProperty("id", ""); 12784 jsobj.AddProperty("id", "");
12756 jsobj.AddProperty("kind", JSONType(false)); 12785 jsobj.AddProperty("kind", JSONType(false));
12757 jsobj.AddProperty("message", ToErrorCString()); 12786 jsobj.AddProperty("message", ToErrorCString());
12758 } 12787 }
12759 12788
12760 12789
12761 RawObject* Instance::Evaluate(const String& expr, 12790 RawObject* Instance::Evaluate(const String& expr,
12762 const Array& param_names, 12791 const Array& param_names,
12763 const Array& param_values) const { 12792 const Array& param_values) const {
12764 const Class& cls = Class::Handle(clazz()); 12793 const Class& cls = Class::Handle(clazz());
12765 const PatchClass& temp_class = PatchClass::Handle(
12766 MakeTempPatchClass(cls, expr, param_names));
12767 const String& eval_func_name = String::Handle(Symbols::New(":eval"));
12768 const Function& eval_func = 12794 const Function& eval_func =
12769 Function::Handle(Function::New(eval_func_name, 12795 Function::Handle(EvaluateHelper(cls, expr, param_names, false));
12770 RawFunction::kRegularFunction,
12771 false, // Not static.
12772 false, // Not const.
12773 false, // Not abstract.
12774 false, // Not external.
12775 false, // Not native.
12776 temp_class,
12777 0));
12778 eval_func.set_result_type(Type::Handle(Type::DynamicType()));
12779 eval_func.set_num_fixed_parameters(1 + param_values.Length());
12780 eval_func.SetNumOptionalParameters(0, true);
12781 eval_func.SetIsOptimizable(false);
12782
12783 const Array& args = Array::Handle(Array::New(1 + param_values.Length())); 12796 const Array& args = Array::Handle(Array::New(1 + param_values.Length()));
12784 Object& param = Object::Handle(); 12797 Object& param = Object::Handle();
12785 args.SetAt(0, *this); 12798 args.SetAt(0, *this);
12786 for (intptr_t i = 0; i < param_values.Length(); i++) { 12799 for (intptr_t i = 0; i < param_values.Length(); i++) {
12787 param = param_values.At(i); 12800 param = param_values.At(i);
12788 args.SetAt(i + 1, param); 12801 args.SetAt(i + 1, param);
12789 } 12802 }
12790 const Object& result = 12803 const Object& result =
12791 Object::Handle(DartEntry::InvokeFunction(eval_func, args)); 12804 Object::Handle(DartEntry::InvokeFunction(eval_func, args));
12792 return result.raw(); 12805 return result.raw();
(...skipping 6261 matching lines...) Expand 10 before | Expand all | Expand 10 after
19054 return tag_label.ToCString(); 19067 return tag_label.ToCString();
19055 } 19068 }
19056 19069
19057 19070
19058 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 19071 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
19059 Instance::PrintJSONImpl(stream, ref); 19072 Instance::PrintJSONImpl(stream, ref);
19060 } 19073 }
19061 19074
19062 19075
19063 } // namespace dart 19076 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698