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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 821f6c20f96bd2a2071ca72ac69b68b0f2e4d62b..ae69e387227804d7ed6b4f19565fcfbb769397b4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2743,51 +2743,37 @@ static RawString* BuildClosureSource(const Array& formal_params,
}
-static RawPatchClass* MakeTempPatchClass(const Class& cls,
- const String& expr,
- const Array& formal_params) {
+static RawFunction* EvaluateHelper(const Class& cls,
+ const String& expr,
+ const Array& param_names,
+ bool is_static) {
const String& func_src =
- String::Handle(BuildClosureSource(formal_params, expr));
+ String::Handle(BuildClosureSource(param_names, expr));
Script& script = Script::Handle();
script = Script::New(Symbols::Empty(), func_src, RawScript::kSourceTag);
// In order to tokenize the source, we need to get the key to mangle
- // private names from the library from which the object's class
- // originates.
+ // private names from the library from which the class originates.
const Library& lib = Library::Handle(cls.library());
ASSERT(!lib.IsNull());
const String& lib_key = String::Handle(lib.private_key());
script.Tokenize(lib_key);
- const String& src_class_name = String::Handle(Symbols::New(":internal"));
- const Class& src_class = Class::Handle(
- Class::New(src_class_name, script, Scanner::kNoSourcePos));
- src_class.set_is_finalized();
- src_class.set_library(lib);
- return PatchClass::New(cls, src_class);
+ const Function& func = Function::Handle(
+ Function::NewEvalFunction(cls, script, is_static));
+ func.set_result_type(Type::Handle(Type::DynamicType()));
+ const intptr_t num_implicit_params = is_static ? 0 : 1;
+ func.set_num_fixed_parameters(num_implicit_params + param_names.Length());
+ func.SetNumOptionalParameters(0, true);
+ func.SetIsOptimizable(false);
+ return func.raw();
}
RawObject* Class::Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const {
- const PatchClass& temp_class =
- PatchClass::Handle(MakeTempPatchClass(*this, expr, param_names));
- const String& eval_func_name = String::Handle(Symbols::New(":eval"));
const Function& eval_func =
- Function::Handle(Function::New(eval_func_name,
- RawFunction::kRegularFunction,
- true, // Static.
- false, // Not const.
- false, // Not abstract.
- false, // Not external.
- false, // Not native.
- temp_class,
- 0));
- eval_func.set_result_type(Type::Handle(Type::DynamicType()));
- eval_func.set_num_fixed_parameters(param_names.Length());
- eval_func.SetNumOptionalParameters(0, true);
- eval_func.SetIsOptimizable(false);
-
+ Function::Handle(EvaluateHelper(*this, expr, param_names, true));
const Object& result =
Object::Handle(DartEntry::InvokeFunction(eval_func, param_values));
return result.raw();
@@ -5073,6 +5059,22 @@ void Function::set_implicit_static_closure(const Instance& closure) const {
}
+RawScript* Function::eval_script() const {
+ const Object& obj = Object::Handle(raw_ptr()->data_);
+ if (obj.IsScript()) {
+ return Script::Cast(obj).raw();
+ }
+ return Script::null();
+}
+
+
+void Function::set_eval_script(const Script& script) const {
+ ASSERT(token_pos() == 0);
+ ASSERT(raw_ptr()->data_ == Object::null());
+ set_data(script);
+}
+
+
RawFunction* Function::extracted_method_closure() const {
ASSERT(kind() == RawFunction::kMethodExtractor);
const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -5149,13 +5151,15 @@ RawFunction* Function::implicit_closure_function() const {
return Function::null();
}
const Object& obj = Object::Handle(raw_ptr()->data_);
- ASSERT(obj.IsNull() || obj.IsFunction());
- return (obj.IsNull()) ? Function::null() : Function::Cast(obj).raw();
+ ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction());
+ return (obj.IsNull() || obj.IsScript()) ? Function::null()
+ : Function::Cast(obj).raw();
}
void Function::set_implicit_closure_function(const Function& value) const {
ASSERT(!IsClosureFunction() && !IsSignatureFunction());
+ ASSERT(raw_ptr()->data_ == Object::null());
set_data(value);
}
@@ -6079,11 +6083,28 @@ RawFunction* Function::NewClosureFunction(const String& name,
parent_owner,
token_pos));
result.set_parent_function(parent);
-
return result.raw();
}
+RawFunction* Function::NewEvalFunction(const Class& owner,
+ const Script& script,
+ bool is_static) {
+ const Function& result = Function::Handle(
+ Function::New(String::Handle(Symbols::New(":Eval")),
+ RawFunction::kRegularFunction,
+ is_static,
+ /* is_const = */ false,
+ /* is_abstract = */ false,
+ /* is_external = */ false,
+ /* is_native = */ false,
+ owner,
+ 0));
+ ASSERT(!script.IsNull());
+ result.set_eval_script(script);
+ return result.raw();
+}
+
RawFunction* Function::ImplicitClosureFunction() const {
// Return the existing implicit closure function if any.
if (implicit_closure_function() != Function::null()) {
@@ -6349,6 +6370,17 @@ RawClass* Function::origin() const {
RawScript* Function::script() const {
+ if (token_pos() == 0) {
+ // Testing for position 0 is an optimization that relies on temporary
+ // eval functions having token position 0.
+ const Script& script = Script::Handle(eval_script());
+ if (!script.IsNull()) {
+ return script.raw();
+ }
+ }
+ if (IsClosureFunction()) {
+ return Function::Handle(parent_function()).script();
+ }
const Object& obj = Object::Handle(raw_ptr()->owner_);
if (obj.IsClass()) {
return Class::Cast(obj).script();
@@ -9276,17 +9308,25 @@ void Library::InitCoreLibrary(Isolate* isolate) {
RawObject* Library::Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const {
- // Make a fake top-level class and evaluate the expression
+ // Take or make a fake top-level class and evaluate the expression
// as a static function of the class.
- Script& script = Script::Handle();
- script = Script::New(Symbols::Empty(),
- Symbols::Empty(),
- RawScript::kSourceTag);
- Class& temp_class =
- Class::Handle(Class::New(Symbols::TopLevel(), script, 0));
- temp_class.set_library(*this);
- temp_class.set_is_finalized();
- return temp_class.Evaluate(expr, param_names, param_values);
+ Class& top_level_class = Class::Handle();
+ Array& top_level_classes = Array::Handle(anonymous_classes());
+ if (top_level_classes.Length() > 0) {
+ top_level_class ^= top_level_classes.At(0);
+ } else {
+ // A library may have no top-level classes if it has no top-level
+ // variables or methods.
+ Script& script = Script::Handle(Script::New(Symbols::Empty(),
+ Symbols::Empty(),
+ RawScript::kSourceTag));
+ top_level_class = Class::New(Symbols::TopLevel(), script, 0);
+ top_level_class.set_is_finalized();
+ top_level_class.set_library(*this);
+ AddAnonymousClass(top_level_class);
+ }
+ ASSERT(top_level_class.is_finalized());
+ return top_level_class.Evaluate(expr, param_names, param_values);
}
@@ -12759,24 +12799,8 @@ RawObject* Instance::Evaluate(const String& expr,
const Array& param_names,
const Array& param_values) const {
const Class& cls = Class::Handle(clazz());
- const PatchClass& temp_class = PatchClass::Handle(
- MakeTempPatchClass(cls, expr, param_names));
- const String& eval_func_name = String::Handle(Symbols::New(":eval"));
const Function& eval_func =
- Function::Handle(Function::New(eval_func_name,
- RawFunction::kRegularFunction,
- false, // Not static.
- false, // Not const.
- false, // Not abstract.
- false, // Not external.
- false, // Not native.
- temp_class,
- 0));
- eval_func.set_result_type(Type::Handle(Type::DynamicType()));
- eval_func.set_num_fixed_parameters(1 + param_values.Length());
- eval_func.SetNumOptionalParameters(0, true);
- eval_func.SetIsOptimizable(false);
-
+ Function::Handle(EvaluateHelper(cls, expr, param_names, false));
const Array& args = Array::Handle(Array::New(1 + param_values.Length()));
Object& param = Object::Handle();
args.SetAt(0, *this);
« 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