| 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 2079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2090 Token::kSET, | 2090 Token::kSET, |
| 2091 arguments, | 2091 arguments, |
| 2092 Array::ZoneHandle(), | 2092 Array::ZoneHandle(), |
| 2093 2)); // Checked argument count. | 2093 2)); // Checked argument count. |
| 2094 ReturnDefinition(BuildLoadExprTemp()); | 2094 ReturnDefinition(BuildLoadExprTemp()); |
| 2095 } | 2095 } |
| 2096 | 2096 |
| 2097 | 2097 |
| 2098 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 2098 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 2099 const String& getter_name = | 2099 const String& getter_name = |
| 2100 String::Handle(Field::GetterName(node->field_name())); | 2100 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 2101 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2101 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2102 new ZoneGrowableArray<PushArgumentInstr*>(); | 2102 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2103 Function& getter_function = Function::ZoneHandle(); | 2103 Function& getter_function = Function::ZoneHandle(); |
| 2104 if (node->is_super_getter()) { | 2104 if (node->is_super_getter()) { |
| 2105 // Statically resolved instance getter, i.e. "super getter". | 2105 // Statically resolved instance getter, i.e. "super getter". |
| 2106 getter_function = | |
| 2107 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | |
| 2108 ASSERT(!getter_function.IsNull()); | |
| 2109 ASSERT(node->receiver() != NULL); | 2106 ASSERT(node->receiver() != NULL); |
| 2110 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth()); | 2107 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 2111 node->receiver()->Visit(&receiver_value); | 2108 if (getter_function.IsNull()) { |
| 2112 Append(receiver_value); | 2109 // Resolve and call noSuchMethod. |
| 2113 arguments->Add(PushArgument(receiver_value.value())); | 2110 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2111 arguments->Add(node->receiver()); |
| 2112 StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(), |
| 2113 node->receiver(), |
| 2114 getter_name, |
| 2115 arguments); |
| 2116 ReturnDefinition(call); |
| 2117 return; |
| 2118 } else { |
| 2119 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth()); |
| 2120 node->receiver()->Visit(&receiver_value); |
| 2121 Append(receiver_value); |
| 2122 arguments->Add(PushArgument(receiver_value.value())); |
| 2123 } |
| 2114 } else { | 2124 } else { |
| 2115 getter_function = node->cls().LookupStaticFunction(getter_name); | 2125 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 2116 if (getter_function.IsNull()) { | 2126 if (getter_function.IsNull()) { |
| 2117 // When the parser encounters a reference to a static field materialized | 2127 // When the parser encounters a reference to a static field materialized |
| 2118 // only by a static setter, but no corresponding static getter, it creates | 2128 // only by a static setter, but no corresponding static getter, it creates |
| 2119 // a StaticGetterNode ast node referring to the non-existing static getter | 2129 // a StaticGetterNode ast node referring to the non-existing static getter |
| 2120 // for the case this field reference appears in a left hand side | 2130 // for the case this field reference appears in a left hand side |
| 2121 // expression (the parser has not distinguished between left and right | 2131 // expression (the parser has not distinguished between left and right |
| 2122 // hand side yet at this stage). If the parser establishes later that the | 2132 // hand side yet at this stage). If the parser establishes later that the |
| 2123 // field access is part of a left hand side expression, the | 2133 // field access is part of a left hand side expression, the |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2153 getter_function, | 2163 getter_function, |
| 2154 Array::ZoneHandle(), // No names. | 2164 Array::ZoneHandle(), // No names. |
| 2155 arguments); | 2165 arguments); |
| 2156 ReturnDefinition(call); | 2166 ReturnDefinition(call); |
| 2157 } | 2167 } |
| 2158 | 2168 |
| 2159 | 2169 |
| 2160 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 2170 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 2161 bool result_is_needed) { | 2171 bool result_is_needed) { |
| 2162 const String& setter_name = | 2172 const String& setter_name = |
| 2163 String::Handle(Field::SetterName(node->field_name())); | 2173 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 2174 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2175 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2164 // A super setter is an instance setter whose setter function is | 2176 // A super setter is an instance setter whose setter function is |
| 2165 // resolved at compile time (in the caller instance getter's super class). | 2177 // resolved at compile time (in the caller instance getter's super class). |
| 2166 // Unlike a static getter, a super getter has a receiver parameter. | 2178 // Unlike a static getter, a super getter has a receiver parameter. |
| 2167 const bool is_super_setter = (node->receiver() != NULL); | 2179 const bool is_super_setter = (node->receiver() != NULL); |
| 2168 const Function& setter_function = | 2180 Function& setter_function = |
| 2169 Function::ZoneHandle(is_super_setter | 2181 Function::ZoneHandle(is_super_setter |
| 2170 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 2182 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2171 : node->cls().LookupStaticFunction(setter_name)); | 2183 : node->cls().LookupStaticFunction(setter_name)); |
| 2172 ASSERT(!setter_function.IsNull()); | 2184 StaticCallInstr* call; |
| 2185 if (setter_function.IsNull()) { |
| 2186 if (is_super_setter) { |
| 2187 ASSERT(node->receiver() != NULL); |
| 2188 // Resolve and call noSuchMethod. |
| 2189 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2190 arguments->Add(node->receiver()); |
| 2191 arguments->Add(node->value()); |
| 2192 call = BuildStaticNoSuchMethodCall(node->cls(), |
| 2193 node->receiver(), |
| 2194 setter_name, |
| 2195 arguments); |
| 2196 } else { |
| 2197 // Throw a NoSuchMethodError. |
| 2198 // Location argument. |
| 2199 Value* call_pos = Bind( |
| 2200 new ConstantInstr(Smi::ZoneHandle(Smi::New(node->token_pos())))); |
| 2201 arguments->Add(PushArgument(call_pos)); |
| 2202 // Function name argument. |
| 2203 const String& method_name = String::ZoneHandle(Symbols::New(setter_name)); |
| 2204 Value* method_name_value = Bind(new ConstantInstr(method_name)); |
| 2205 arguments->Add(PushArgument(method_name_value)); |
| 2206 const String& cls_name = String::Handle(Symbols::NoSuchMethodError()); |
| 2207 const String& func_name = String::Handle(Symbols::ThrowNew()); |
| 2208 const Class& cls = Class::Handle( |
| 2209 Library::Handle(Library::CoreLibrary()).LookupClass(cls_name)); |
| 2210 ASSERT(!cls.IsNull()); |
| 2211 setter_function = Resolver::ResolveStatic(cls, |
| 2212 func_name, |
| 2213 arguments->length(), |
| 2214 Array::ZoneHandle(), |
| 2215 Resolver::kIsQualified); |
| 2216 ASSERT(!setter_function.IsNull()); |
| 2217 call = new StaticCallInstr(node->token_pos(), |
| 2218 setter_function, |
| 2219 Array::ZoneHandle(), // No names. |
| 2220 arguments); |
| 2221 } |
| 2222 } else { |
| 2223 if (is_super_setter) { |
| 2224 // Add receiver of instance getter. |
| 2225 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 2226 node->receiver()->Visit(&for_receiver); |
| 2227 Append(for_receiver); |
| 2228 arguments->Add(PushArgument(for_receiver.value())); |
| 2229 } |
| 2230 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2231 node->value()->Visit(&for_value); |
| 2232 Append(for_value); |
| 2233 Value* value = NULL; |
| 2234 if (result_is_needed) { |
| 2235 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2236 } else { |
| 2237 value = for_value.value(); |
| 2238 } |
| 2239 arguments->Add(PushArgument(value)); |
| 2173 | 2240 |
| 2174 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2241 call = new StaticCallInstr(node->token_pos(), |
| 2175 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2242 setter_function, |
| 2176 if (is_super_setter) { | 2243 Array::ZoneHandle(), // No names. |
| 2177 // Add receiver of instance getter. | 2244 arguments); |
| 2178 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | |
| 2179 node->receiver()->Visit(&for_receiver); | |
| 2180 Append(for_receiver); | |
| 2181 arguments->Add(PushArgument(for_receiver.value())); | |
| 2182 } | 2245 } |
| 2183 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | |
| 2184 node->value()->Visit(&for_value); | |
| 2185 Append(for_value); | |
| 2186 Value* value = NULL; | |
| 2187 if (result_is_needed) { | |
| 2188 value = Bind(BuildStoreExprTemp(for_value.value())); | |
| 2189 } else { | |
| 2190 value = for_value.value(); | |
| 2191 } | |
| 2192 arguments->Add(PushArgument(value)); | |
| 2193 | |
| 2194 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | |
| 2195 setter_function, | |
| 2196 Array::ZoneHandle(), // No names. | |
| 2197 arguments); | |
| 2198 if (result_is_needed) { | 2246 if (result_is_needed) { |
| 2199 Do(call); | 2247 Do(call); |
| 2200 ReturnDefinition(BuildLoadExprTemp()); | 2248 ReturnDefinition(BuildLoadExprTemp()); |
| 2201 } else { | 2249 } else { |
| 2202 ReturnDefinition(call); | 2250 ReturnDefinition(call); |
| 2203 } | 2251 } |
| 2204 } | 2252 } |
| 2205 | 2253 |
| 2206 | 2254 |
| 2207 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 2255 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 Function* super_function = NULL; | 2418 Function* super_function = NULL; |
| 2371 if (node->IsSuperLoad()) { | 2419 if (node->IsSuperLoad()) { |
| 2372 // Resolve the load indexed operator in the super class. | 2420 // Resolve the load indexed operator in the super class. |
| 2373 super_function = &Function::ZoneHandle( | 2421 super_function = &Function::ZoneHandle( |
| 2374 Resolver::ResolveDynamicAnyArgs(node->super_class(), | 2422 Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 2375 Symbols::IndexTokenHandle())); | 2423 Symbols::IndexTokenHandle())); |
| 2376 if (super_function->IsNull()) { | 2424 if (super_function->IsNull()) { |
| 2377 // Could not resolve super operator. Generate call noSuchMethod() of the | 2425 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 2378 // super class instead. | 2426 // super class instead. |
| 2379 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2427 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2428 arguments->Add(node->array()); |
| 2380 arguments->Add(node->index_expr()); | 2429 arguments->Add(node->index_expr()); |
| 2381 StaticCallInstr* call = | 2430 StaticCallInstr* call = |
| 2382 BuildStaticNoSuchMethodCall(node->super_class(), | 2431 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2383 node->array(), | 2432 node->array(), |
| 2384 Symbols::IndexTokenHandle(), | 2433 Symbols::IndexTokenHandle(), |
| 2385 arguments); | 2434 arguments); |
| 2386 ReturnDefinition(call); | 2435 ReturnDefinition(call); |
| 2387 return; | 2436 return; |
| 2388 } | 2437 } |
| 2389 } | 2438 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2434 // super class instead. | 2483 // super class instead. |
| 2435 if (result_is_needed) { | 2484 if (result_is_needed) { |
| 2436 // Even though noSuchMethod most likely does not return, | 2485 // Even though noSuchMethod most likely does not return, |
| 2437 // we save the stored value if the result is needed. | 2486 // we save the stored value if the result is needed. |
| 2438 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 2487 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2439 node->value()->Visit(&for_value); | 2488 node->value()->Visit(&for_value); |
| 2440 Append(for_value); | 2489 Append(for_value); |
| 2441 Bind(BuildStoreExprTemp(for_value.value())); | 2490 Bind(BuildStoreExprTemp(for_value.value())); |
| 2442 } | 2491 } |
| 2443 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2492 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2493 arguments->Add(node->array()); |
| 2444 arguments->Add(node->index_expr()); | 2494 arguments->Add(node->index_expr()); |
| 2445 arguments->Add(node->value()); | 2495 arguments->Add(node->value()); |
| 2446 StaticCallInstr* call = | 2496 StaticCallInstr* call = |
| 2447 BuildStaticNoSuchMethodCall(node->super_class(), | 2497 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2448 node->array(), | 2498 node->array(), |
| 2449 Symbols::AssignIndexTokenHandle(), | 2499 Symbols::AssignIndexTokenHandle(), |
| 2450 arguments); | 2500 arguments); |
| 2451 if (result_is_needed) { | 2501 if (result_is_needed) { |
| 2452 Do(call); | 2502 Do(call); |
| 2453 return BuildLoadExprTemp(); | 2503 return BuildLoadExprTemp(); |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2960 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3010 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2961 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3011 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2962 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3012 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2963 const Error& error = Error::Handle( | 3013 const Error& error = Error::Handle( |
| 2964 LanguageError::New(String::Handle(String::New(chars)))); | 3014 LanguageError::New(String::Handle(String::New(chars)))); |
| 2965 Isolate::Current()->long_jump_base()->Jump(1, error); | 3015 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2966 } | 3016 } |
| 2967 | 3017 |
| 2968 | 3018 |
| 2969 } // namespace dart | 3019 } // namespace dart |
| OLD | NEW |