OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1142 Handle<Object> type_handle = | 1142 Handle<Object> type_handle = |
1143 isolate->factory()->NewStringFromAscii(CStrVector(type)); | 1143 isolate->factory()->NewStringFromAscii(CStrVector(type)); |
1144 Handle<Object> args[2] = { type_handle, name }; | 1144 Handle<Object> args[2] = { type_handle, name }; |
1145 Handle<Object> error = | 1145 Handle<Object> error = |
1146 isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2)); | 1146 isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2)); |
1147 return isolate->Throw(*error); | 1147 return isolate->Throw(*error); |
1148 } | 1148 } |
1149 | 1149 |
1150 | 1150 |
1151 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { | 1151 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { |
1152 ASSERT(args.length() == 4); | 1152 ASSERT(args.length() == 3); |
1153 HandleScope scope(isolate); | 1153 HandleScope scope(isolate); |
1154 Handle<GlobalObject> global = Handle<GlobalObject>( | 1154 Handle<GlobalObject> global = Handle<GlobalObject>( |
1155 isolate->context()->global()); | 1155 isolate->context()->global()); |
1156 | 1156 |
1157 Handle<Context> context = args.at<Context>(0); | 1157 Handle<Context> context = args.at<Context>(0); |
1158 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); | 1158 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); |
1159 bool is_eval = args.smi_at(2) == 1; | 1159 CONVERT_SMI_ARG_CHECKED(flags, 2); |
1160 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); | 1160 bool is_eval = (flags & kDeclareGlobalsEvalFlag) != 0; |
Kevin Millikin (Chromium)
2011/09/01 07:58:24
These flags and 'base' below are declared a away f
Lasse Reichstein
2011/09/01 09:26:58
Done.
| |
1161 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); | 1161 StrictModeFlag strict_mode = |
1162 ((flags & kDeclareGlobalsStrictModeFlag) != 0) ? kStrictMode | |
1163 : kNonStrictMode; | |
1164 bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0; | |
1162 | 1165 |
1163 // Compute the property attributes. According to ECMA-262, section | 1166 // Compute the property attributes. According to ECMA-262, section |
1164 // 13, page 71, the property must be read-only and | 1167 // 13, page 71, the property must be read-only and |
1165 // non-deletable. However, neither SpiderMonkey nor KJS creates the | 1168 // non-deletable. However, neither SpiderMonkey nor KJS creates the |
1166 // property as read-only, so we don't either. | 1169 // property as read-only, so we don't either. |
1167 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; | 1170 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; |
1168 | 1171 |
1169 // Traverse the name/value pairs and set the properties. | 1172 // Traverse the name/value pairs and set the properties. |
1170 int length = pairs->length(); | 1173 int length = pairs->length(); |
1171 for (int i = 0; i < length; i += 2) { | 1174 for (int i = 0; i < length; i += 2) { |
1172 HandleScope scope(isolate); | 1175 HandleScope scope(isolate); |
1173 Handle<String> name(String::cast(pairs->get(i))); | 1176 Handle<String> name(String::cast(pairs->get(i))); |
1174 Handle<Object> value(pairs->get(i + 1), isolate); | 1177 Handle<Object> value(pairs->get(i + 1), isolate); |
1175 | 1178 |
1176 // We have to declare a global const property. To capture we only | 1179 // We have to declare a global const property. To capture we only |
1177 // assign to it when evaluating the assignment for "const x = | 1180 // assign to it when evaluating the assignment for "const x = |
1178 // <expr>" the initial value is the hole. | 1181 // <expr>" the initial value is the hole. |
1179 bool is_const_property = value->IsTheHole(); | 1182 bool is_const_property = value->IsTheHole(); |
1180 | 1183 bool is_function_declaration = false; |
1181 if (value->IsUndefined() || is_const_property) { | 1184 if (value->IsUndefined() || is_const_property) { |
1182 // Lookup the property in the global object, and don't set the | 1185 // Lookup the property in the global object, and don't set the |
1183 // value of the variable if the property is already there. | 1186 // value of the variable if the property is already there. |
1184 LookupResult lookup; | 1187 LookupResult lookup; |
1185 global->Lookup(*name, &lookup); | 1188 global->Lookup(*name, &lookup); |
1186 if (lookup.IsProperty()) { | 1189 if (lookup.IsProperty()) { |
1187 // Determine if the property is local by comparing the holder | 1190 // Determine if the property is local by comparing the holder |
1188 // against the global object. The information will be used to | 1191 // against the global object. The information will be used to |
1189 // avoid throwing re-declaration errors when declaring | 1192 // avoid throwing re-declaration errors when declaring |
1190 // variables or constants that exist in the prototype chain. | 1193 // variables or constants that exist in the prototype chain. |
(...skipping 28 matching lines...) Expand all Loading... | |
1219 if (is_local && (is_read_only || is_const_property)) { | 1222 if (is_local && (is_read_only || is_const_property)) { |
1220 const char* type = (is_read_only) ? "const" : "var"; | 1223 const char* type = (is_read_only) ? "const" : "var"; |
1221 return ThrowRedeclarationError(isolate, type, name); | 1224 return ThrowRedeclarationError(isolate, type, name); |
1222 } | 1225 } |
1223 // The property already exists without conflicting: Go to | 1226 // The property already exists without conflicting: Go to |
1224 // the next declaration. | 1227 // the next declaration. |
1225 continue; | 1228 continue; |
1226 } | 1229 } |
1227 } | 1230 } |
1228 } else { | 1231 } else { |
1232 is_function_declaration = true; | |
1229 // Copy the function and update its context. Use it as value. | 1233 // Copy the function and update its context. Use it as value. |
1230 Handle<SharedFunctionInfo> shared = | 1234 Handle<SharedFunctionInfo> shared = |
1231 Handle<SharedFunctionInfo>::cast(value); | 1235 Handle<SharedFunctionInfo>::cast(value); |
1232 Handle<JSFunction> function = | 1236 Handle<JSFunction> function = |
1233 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 1237 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
1234 context, | 1238 context, |
1235 TENURED); | 1239 TENURED); |
1236 value = function; | 1240 value = function; |
1237 } | 1241 } |
1238 | 1242 |
1239 LookupResult lookup; | 1243 LookupResult lookup; |
1240 global->LocalLookup(*name, &lookup); | 1244 global->LocalLookup(*name, &lookup); |
1241 | 1245 |
1242 PropertyAttributes attributes = is_const_property | 1246 PropertyAttributes attributes = |
Kevin Millikin (Chromium)
2011/09/01 07:58:24
Here, you could just get rid of base and have the
Lasse Reichstein
2011/09/01 09:26:58
Good idea. Done!
| |
1247 (is_const_property || (is_native && is_function_declaration)) | |
1243 ? static_cast<PropertyAttributes>(base | READ_ONLY) | 1248 ? static_cast<PropertyAttributes>(base | READ_ONLY) |
1244 : base; | 1249 : base; |
1245 | 1250 |
1246 // There's a local property that we need to overwrite because | 1251 // There's a local property that we need to overwrite because |
1247 // we're either declaring a function or there's an interceptor | 1252 // we're either declaring a function or there's an interceptor |
1248 // that claims the property is absent. | 1253 // that claims the property is absent. |
1249 // | 1254 // |
1250 // Check for conflicting re-declarations. We cannot have | 1255 // Check for conflicting re-declarations. We cannot have |
1251 // conflicting types in case of intercepted properties because | 1256 // conflicting types in case of intercepted properties because |
1252 // they are absent. | 1257 // they are absent. |
1253 if (lookup.IsProperty() && | 1258 if (lookup.IsProperty() && |
1254 (lookup.type() != INTERCEPTOR) && | 1259 (lookup.type() != INTERCEPTOR) && |
1255 (lookup.IsReadOnly() || is_const_property)) { | 1260 (lookup.IsReadOnly() || is_const_property)) { |
1256 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; | 1261 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; |
1257 return ThrowRedeclarationError(isolate, type, name); | 1262 return ThrowRedeclarationError(isolate, type, name); |
1258 } | 1263 } |
1259 | 1264 |
1260 // Safari does not allow the invocation of callback setters for | 1265 // Safari does not allow the invocation of callback setters for |
1261 // function declarations. To mimic this behavior, we do not allow | 1266 // function declarations. To mimic this behavior, we do not allow |
1262 // the invocation of setters for function values. This makes a | 1267 // the invocation of setters for function values. This makes a |
1263 // difference for global functions with the same names as event | 1268 // difference for global functions with the same names as event |
1264 // handlers such as "function onload() {}". Firefox does call the | 1269 // handlers such as "function onload() {}". Firefox does call the |
1265 // onload setter in those case and Safari does not. We follow | 1270 // onload setter in those case and Safari does not. We follow |
1266 // Safari for compatibility. | 1271 // Safari for compatibility. |
1267 if (value->IsJSFunction()) { | 1272 if (value->IsJSFunction()) { |
1268 // Do not change DONT_DELETE to false from true. | 1273 // Do not change DONT_DELETE to false from true. |
1269 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { | 1274 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { |
1270 attributes = static_cast<PropertyAttributes>( | 1275 attributes = static_cast<PropertyAttributes>( |
Kevin Millikin (Chromium)
2011/09/01 07:58:24
Here
attr |= (lookup.GetAttributes() & DONT_DELET
Lasse Reichstein
2011/09/01 09:26:58
Done.
| |
1271 attributes | (lookup.GetAttributes() & DONT_DELETE)); | 1276 attributes | (lookup.GetAttributes() & DONT_DELETE)); |
1272 } | 1277 } |
1273 RETURN_IF_EMPTY_HANDLE(isolate, | 1278 RETURN_IF_EMPTY_HANDLE(isolate, |
Kevin Millikin (Chromium)
2011/09/01 07:58:24
Here:
SetLocalPropertyIgnoreAttributes(global,
Lasse Reichstein
2011/09/01 09:26:58
Done.
| |
1274 SetLocalPropertyIgnoreAttributes(global, | 1279 SetLocalPropertyIgnoreAttributes(global, |
1275 name, | 1280 name, |
1276 value, | 1281 value, |
1277 attributes)); | 1282 attributes)); |
1278 } else { | 1283 } else { |
1279 RETURN_IF_EMPTY_HANDLE(isolate, | 1284 RETURN_IF_EMPTY_HANDLE(isolate, |
1280 SetProperty(global, | 1285 SetProperty(global, |
1281 name, | 1286 name, |
1282 value, | 1287 value, |
1283 attributes, | 1288 attributes, |
(...skipping 11665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12949 } else { | 12954 } else { |
12950 // Handle last resort GC and make sure to allow future allocations | 12955 // Handle last resort GC and make sure to allow future allocations |
12951 // to grow the heap without causing GCs (if possible). | 12956 // to grow the heap without causing GCs (if possible). |
12952 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12957 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12953 isolate->heap()->CollectAllGarbage(false); | 12958 isolate->heap()->CollectAllGarbage(false); |
12954 } | 12959 } |
12955 } | 12960 } |
12956 | 12961 |
12957 | 12962 |
12958 } } // namespace v8::internal | 12963 } } // namespace v8::internal |
OLD | NEW |