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

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: rebase 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
« no previous file with comments | « runtime/vm/object.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698