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

Unified Diff: runtime/vm/parser.cc

Issue 8234016: Inline allocation of implicit closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 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.cc ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 355)
+++ runtime/vm/parser.cc (working copy)
@@ -580,7 +580,7 @@
// The instantiator may be required at run time for generic type checks or
// allocation of generic types.
if (parser.current_class().IsParameterized() &&
- (!parser.current_function().IsInStaticScope() ||
+ (!parser.current_function().is_static() ||
parser.current_function().IsInFactoryScope())) {
// In the case of a local function, only set the instantiator if the
// receiver was captured.
@@ -843,7 +843,7 @@
// signature with the type parameters of the enclosing class, if any.
// TODO(regis): Revisit if this is not the right thing to do.
const bool is_static =
- current_function().IsNull() || current_function().IsInStaticScope();
+ current_function().IsNull() || current_function().is_static();
const Function& signature_function = Function::Handle(
Function::New(*parameter.name,
RawFunction::kSignatureFunction,
@@ -1073,19 +1073,13 @@
AstNode* receiver) {
Function& implicit_closure_function =
Function::ZoneHandle(func.ImplicitClosureFunction());
- ASSERT(!implicit_closure_function.IsNull());
- ASSERT(implicit_closure_function.is_static()); // TODO(regis): For now.
- AstNode* node;
if (receiver == NULL) {
- ASSERT(func.is_static());
- node = new StaticImplicitClosureNode(token_pos, implicit_closure_function);
+ return new ImplicitStaticClosureNode(token_pos, implicit_closure_function);
} else {
- ASSERT(!func.is_static());
- node = new ImplicitClosureNode(token_pos,
- implicit_closure_function,
- receiver);
+ return new ImplicitInstanceClosureNode(token_pos,
+ implicit_closure_function,
+ receiver);
}
- return node;
}
@@ -1417,10 +1411,14 @@
OpenFunctionBlock(func);
ParamList params;
+ // Static functions do not have a receiver, except constructors, which are
+ // passed the allocated but uninitialized instance to construct.
+ // An instance closure may capture and access the receiver, but via the
+ // context and not via the first formal parameter.
// The first parameter of a factory is the TypeArguments vector of the type
// of the instance to be allocated. We name this hidden parameter 'this'.
- const bool has_receiver =
- !func.is_static() || func.IsConstructor() || func.IsFactory();
+ const bool has_receiver = !func.IsClosureFunction() &&
+ (!func.is_static() || func.IsConstructor() || func.IsFactory());
const bool are_implicitly_final = func.is_const() && func.IsConstructor();
const bool allow_explicit_default_values = true;
ASSERT(CurrentToken() == Token::kLPAREN);
@@ -1540,7 +1538,7 @@
// The instantiator may be required at run time for generic type checks or
// allocation of generic types.
if (current_class().IsParameterized() &&
- (!current_function().IsInStaticScope() ||
+ (!current_function().is_static() ||
current_function().IsInFactoryScope())) {
// Make sure that the receiver of the enclosing instance function
// (or implicit first parameter of an enclosing factory) is marked as
@@ -3150,7 +3148,7 @@
// A nested function may access 'this', referring to the receiver of the
// outermost enclosing function.
// We should not be loading the receiver from a static scope.
- ASSERT(!current_function().IsInStaticScope() ||
+ ASSERT(!current_function().is_static() ||
current_function().IsInFactoryScope());
const bool kTestOnly = false;
LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly);
@@ -5381,7 +5379,7 @@
} else if (primary->primary().IsString()) {
// Primary is an unresolved name.
String& name = String::CheckedZoneHandle(primary->primary().raw());
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg(primary->token_index(),
"identifier '%s' is not declared in this scope",
name.ToCString());
@@ -5409,7 +5407,7 @@
selector = ParseStaticCall(cls, func_name, primary_pos);
} else {
// Dynamic function call on implicit "this" parameter.
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg(primary_pos,
"Cannot access instance method '%s' "
"from static function",
@@ -5420,7 +5418,7 @@
} else if (primary->primary().IsString()) {
// Primary is an unresolved name.
String& name = String::CheckedZoneHandle(primary->primary().raw());
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg(primary->token_index(),
"identifier '%s' is not declared in this scope",
name.ToCString());
@@ -5454,7 +5452,7 @@
// If we are compiling an instance method, convert this into
// a runtime lookup for a field (which may be defined in a
// subclass.)
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg(primary->token_index(),
"identifier '%s' is not declared in this scope",
ident.ToCString());
@@ -5476,7 +5474,7 @@
NULL);
} else {
// Instance function access.
- if (current_function().IsInStaticScope() ||
+ if (current_function().is_static() ||
current_function().IsInFactoryScope()) {
ErrorMsg(primary->token_index(),
"illegal use of method '%s'",
@@ -5603,7 +5601,7 @@
const String& field_name) {
// Fields are not accessible from a static function, except from a
// constructor, which is considered as non-static by the compiler.
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg(field_pos,
"cannot access instance field '%s' from a static function",
field_name.ToCString());
@@ -5621,7 +5619,7 @@
current_member_->has_static &&
!current_member_->has_factory) ||
(!current_function().IsNull() &&
- current_function().IsInStaticScope() &&
+ current_function().is_static() &&
!current_function().IsInFactoryScope())) {
ErrorMsg(type_parameter_pos,
"cannot refer to type parameter '%s' from a static function",
@@ -5928,7 +5926,7 @@
// method, this is an error. In an instance method, we convert
// the unresolved name to an instance field access, since a
// subclass might define a field with this name.
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope",
ident.ToCString());
} else {
@@ -6651,7 +6649,7 @@
CurrentToken() == Token::kLBRACE) {
primary = ParseCompoundLiteral();
} else if (CurrentToken() == Token::kSUPER) {
- if (current_function().IsInStaticScope()) {
+ if (current_function().is_static()) {
ErrorMsg("cannot access superclass from static method");
} else if (current_function().IsLocalFunction()) {
ErrorMsg("cannot access superclass from local function");
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698