OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast.h" | 5 #include "src/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 #include "src/builtins.h" | 8 #include "src/builtins.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/contexts.h" | 10 #include "src/contexts.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 bool Expression::IsUndefinedLiteral(Isolate* isolate) const { | 51 bool Expression::IsUndefinedLiteral(Isolate* isolate) const { |
52 const VariableProxy* var_proxy = AsVariableProxy(); | 52 const VariableProxy* var_proxy = AsVariableProxy(); |
53 if (var_proxy == NULL) return false; | 53 if (var_proxy == NULL) return false; |
54 Variable* var = var_proxy->var(); | 54 Variable* var = var_proxy->var(); |
55 // The global identifier "undefined" is immutable. Everything | 55 // The global identifier "undefined" is immutable. Everything |
56 // else could be reassigned. | 56 // else could be reassigned. |
57 return var != NULL && var->location() == Variable::UNALLOCATED && | 57 return var != NULL && var->location() == Variable::UNALLOCATED && |
58 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); | 58 String::Equals(var_proxy->name(), |
| 59 isolate->factory()->undefined_string()); |
59 } | 60 } |
60 | 61 |
61 | 62 |
62 VariableProxy::VariableProxy(Zone* zone, Variable* var, int position) | 63 VariableProxy::VariableProxy(Zone* zone, Variable* var, int position) |
63 : Expression(zone, position), | 64 : Expression(zone, position), |
64 name_(var->raw_name()), | 65 name_(var->name()), |
65 var_(NULL), // Will be set by the call to BindTo. | 66 var_(NULL), // Will be set by the call to BindTo. |
66 is_this_(var->is_this()), | 67 is_this_(var->is_this()), |
67 is_trivial_(false), | 68 is_trivial_(false), |
68 is_lvalue_(false), | 69 is_lvalue_(false), |
69 interface_(var->interface()) { | 70 interface_(var->interface()) { |
70 BindTo(var); | 71 BindTo(var); |
71 } | 72 } |
72 | 73 |
73 | 74 |
74 VariableProxy::VariableProxy(Zone* zone, | 75 VariableProxy::VariableProxy(Zone* zone, |
75 const AstString* name, | 76 Handle<String> name, |
76 bool is_this, | 77 bool is_this, |
77 Interface* interface, | 78 Interface* interface, |
78 int position) | 79 int position) |
79 : Expression(zone, position), | 80 : Expression(zone, position), |
80 name_(name), | 81 name_(name), |
81 var_(NULL), | 82 var_(NULL), |
82 is_this_(is_this), | 83 is_this_(is_this), |
83 is_trivial_(false), | 84 is_trivial_(false), |
84 is_lvalue_(false), | 85 is_lvalue_(false), |
85 interface_(interface) { | 86 interface_(interface) { |
| 87 // Names must be canonicalized for fast equality checks. |
| 88 ASSERT(name->IsInternalizedString()); |
86 } | 89 } |
87 | 90 |
88 | 91 |
89 void VariableProxy::BindTo(Variable* var) { | 92 void VariableProxy::BindTo(Variable* var) { |
90 ASSERT(var_ == NULL); // must be bound only once | 93 ASSERT(var_ == NULL); // must be bound only once |
91 ASSERT(var != NULL); // must bind | 94 ASSERT(var != NULL); // must bind |
92 ASSERT(!FLAG_harmony_modules || interface_->IsUnified(var->interface())); | 95 ASSERT(!FLAG_harmony_modules || interface_->IsUnified(var->interface())); |
93 ASSERT((is_this() && var->is_this()) || name_ == var->raw_name()); | 96 ASSERT((is_this() && var->is_this()) || name_.is_identical_to(var->name())); |
94 // Ideally CONST-ness should match. However, this is very hard to achieve | 97 // Ideally CONST-ness should match. However, this is very hard to achieve |
95 // because we don't know the exact semantics of conflicting (const and | 98 // because we don't know the exact semantics of conflicting (const and |
96 // non-const) multiple variable declarations, const vars introduced via | 99 // non-const) multiple variable declarations, const vars introduced via |
97 // eval() etc. Const-ness and variable declarations are a complete mess | 100 // eval() etc. Const-ness and variable declarations are a complete mess |
98 // in JS. Sigh... | 101 // in JS. Sigh... |
99 var_ = var; | 102 var_ = var; |
100 var->set_is_used(true); | 103 var->set_is_used(true); |
101 } | 104 } |
102 | 105 |
103 | 106 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 173 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
171 if (shared->start_position() == start_position()) { | 174 if (shared->start_position() == start_position()) { |
172 shared_info_ = Handle<SharedFunctionInfo>(shared); | 175 shared_info_ = Handle<SharedFunctionInfo>(shared); |
173 break; | 176 break; |
174 } | 177 } |
175 } | 178 } |
176 } | 179 } |
177 } | 180 } |
178 | 181 |
179 | 182 |
180 ObjectLiteralProperty::ObjectLiteralProperty(Zone* zone, | 183 ObjectLiteralProperty::ObjectLiteralProperty( |
181 AstValueFactory* ast_value_factory, | 184 Zone* zone, Literal* key, Expression* value) { |
182 Literal* key, Expression* value) { | |
183 emit_store_ = true; | 185 emit_store_ = true; |
184 key_ = key; | 186 key_ = key; |
185 value_ = value; | 187 value_ = value; |
186 if (key->raw_value()->EqualsString(ast_value_factory->proto_string())) { | 188 Handle<Object> k = key->value(); |
| 189 if (k->IsInternalizedString() && |
| 190 String::Equals(Handle<String>::cast(k), |
| 191 zone->isolate()->factory()->proto_string())) { |
187 kind_ = PROTOTYPE; | 192 kind_ = PROTOTYPE; |
188 } else if (value_->AsMaterializedLiteral() != NULL) { | 193 } else if (value_->AsMaterializedLiteral() != NULL) { |
189 kind_ = MATERIALIZED_LITERAL; | 194 kind_ = MATERIALIZED_LITERAL; |
190 } else if (value_->IsLiteral()) { | 195 } else if (value_->IsLiteral()) { |
191 kind_ = CONSTANT; | 196 kind_ = CONSTANT; |
192 } else { | 197 } else { |
193 kind_ = COMPUTED; | 198 kind_ = COMPUTED; |
194 } | 199 } |
195 } | 200 } |
196 | 201 |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 DONT_CACHE_NODE(ModuleLiteral) | 1115 DONT_CACHE_NODE(ModuleLiteral) |
1111 | 1116 |
1112 | 1117 |
1113 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { | 1118 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { |
1114 increase_node_count(); | 1119 increase_node_count(); |
1115 if (node->is_jsruntime()) { | 1120 if (node->is_jsruntime()) { |
1116 // Don't try to inline JS runtime calls because we don't (currently) even | 1121 // Don't try to inline JS runtime calls because we don't (currently) even |
1117 // optimize them. | 1122 // optimize them. |
1118 add_flag(kDontInline); | 1123 add_flag(kDontInline); |
1119 } else if (node->function()->intrinsic_type == Runtime::INLINE && | 1124 } else if (node->function()->intrinsic_type == Runtime::INLINE && |
1120 (node->raw_name()->IsOneByteEqualTo("_ArgumentsLength") || | 1125 (node->name()->IsOneByteEqualTo( |
1121 node->raw_name()->IsOneByteEqualTo("_Arguments"))) { | 1126 STATIC_ASCII_VECTOR("_ArgumentsLength")) || |
| 1127 node->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_Arguments")))) { |
1122 // Don't inline the %_ArgumentsLength or %_Arguments because their | 1128 // Don't inline the %_ArgumentsLength or %_Arguments because their |
1123 // implementation will not work. There is no stack frame to get them | 1129 // implementation will not work. There is no stack frame to get them |
1124 // from. | 1130 // from. |
1125 add_flag(kDontInline); | 1131 add_flag(kDontInline); |
1126 } | 1132 } |
1127 } | 1133 } |
1128 | 1134 |
1129 #undef REGULAR_NODE | 1135 #undef REGULAR_NODE |
1130 #undef DONT_OPTIMIZE_NODE | 1136 #undef DONT_OPTIMIZE_NODE |
1131 #undef DONT_SELFOPTIMIZE_NODE | 1137 #undef DONT_SELFOPTIMIZE_NODE |
1132 #undef DONT_CACHE_NODE | 1138 #undef DONT_CACHE_NODE |
1133 | 1139 |
1134 | 1140 |
1135 Handle<String> Literal::ToString() { | 1141 Handle<String> Literal::ToString() { |
1136 if (value_->IsString()) return value_->AsString()->string(); | 1142 if (value_->IsString()) return Handle<String>::cast(value_); |
1137 ASSERT(value_->IsNumber()); | 1143 ASSERT(value_->IsNumber()); |
1138 char arr[100]; | 1144 char arr[100]; |
1139 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 1145 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
1140 const char* str; | 1146 const char* str; |
1141 if (value()->IsSmi()) { | 1147 if (value_->IsSmi()) { |
1142 // Optimization only, the heap number case would subsume this. | 1148 // Optimization only, the heap number case would subsume this. |
1143 SNPrintF(buffer, "%d", Smi::cast(*value())->value()); | 1149 SNPrintF(buffer, "%d", Smi::cast(*value_)->value()); |
1144 str = arr; | 1150 str = arr; |
1145 } else { | 1151 } else { |
1146 str = DoubleToCString(value()->Number(), buffer); | 1152 str = DoubleToCString(value_->Number(), buffer); |
1147 } | 1153 } |
1148 return isolate_->factory()->NewStringFromAsciiChecked(str); | 1154 return isolate_->factory()->NewStringFromAsciiChecked(str); |
1149 } | 1155 } |
1150 | 1156 |
1151 | 1157 |
1152 } } // namespace v8::internal | 1158 } } // namespace v8::internal |
OLD | NEW |