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)); | |
1161 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); | |
1162 | |
1163 // Compute the property attributes. According to ECMA-262, section | |
1164 // 13, page 71, the property must be read-only and | |
1165 // non-deletable. However, neither SpiderMonkey nor KJS creates the | |
1166 // property as read-only, so we don't either. | |
1167 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; | |
1168 | 1160 |
1169 // Traverse the name/value pairs and set the properties. | 1161 // Traverse the name/value pairs and set the properties. |
1170 int length = pairs->length(); | 1162 int length = pairs->length(); |
1171 for (int i = 0; i < length; i += 2) { | 1163 for (int i = 0; i < length; i += 2) { |
1172 HandleScope scope(isolate); | 1164 HandleScope scope(isolate); |
1173 Handle<String> name(String::cast(pairs->get(i))); | 1165 Handle<String> name(String::cast(pairs->get(i))); |
1174 Handle<Object> value(pairs->get(i + 1), isolate); | 1166 Handle<Object> value(pairs->get(i + 1), isolate); |
1175 | 1167 |
1176 // We have to declare a global const property. To capture we only | 1168 // We have to declare a global const property. To capture we only |
1177 // assign to it when evaluating the assignment for "const x = | 1169 // assign to it when evaluating the assignment for "const x = |
1178 // <expr>" the initial value is the hole. | 1170 // <expr>" the initial value is the hole. |
1179 bool is_const_property = value->IsTheHole(); | 1171 bool is_const_property = value->IsTheHole(); |
1180 | 1172 bool is_function_declaration = false; |
1181 if (value->IsUndefined() || is_const_property) { | 1173 if (value->IsUndefined() || is_const_property) { |
1182 // Lookup the property in the global object, and don't set the | 1174 // Lookup the property in the global object, and don't set the |
1183 // value of the variable if the property is already there. | 1175 // value of the variable if the property is already there. |
1184 LookupResult lookup; | 1176 LookupResult lookup; |
1185 global->Lookup(*name, &lookup); | 1177 global->Lookup(*name, &lookup); |
1186 if (lookup.IsProperty()) { | 1178 if (lookup.IsProperty()) { |
1187 // Determine if the property is local by comparing the holder | 1179 // Determine if the property is local by comparing the holder |
1188 // against the global object. The information will be used to | 1180 // against the global object. The information will be used to |
1189 // avoid throwing re-declaration errors when declaring | 1181 // avoid throwing re-declaration errors when declaring |
1190 // variables or constants that exist in the prototype chain. | 1182 // 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)) { | 1211 if (is_local && (is_read_only || is_const_property)) { |
1220 const char* type = (is_read_only) ? "const" : "var"; | 1212 const char* type = (is_read_only) ? "const" : "var"; |
1221 return ThrowRedeclarationError(isolate, type, name); | 1213 return ThrowRedeclarationError(isolate, type, name); |
1222 } | 1214 } |
1223 // The property already exists without conflicting: Go to | 1215 // The property already exists without conflicting: Go to |
1224 // the next declaration. | 1216 // the next declaration. |
1225 continue; | 1217 continue; |
1226 } | 1218 } |
1227 } | 1219 } |
1228 } else { | 1220 } else { |
| 1221 is_function_declaration = true; |
1229 // Copy the function and update its context. Use it as value. | 1222 // Copy the function and update its context. Use it as value. |
1230 Handle<SharedFunctionInfo> shared = | 1223 Handle<SharedFunctionInfo> shared = |
1231 Handle<SharedFunctionInfo>::cast(value); | 1224 Handle<SharedFunctionInfo>::cast(value); |
1232 Handle<JSFunction> function = | 1225 Handle<JSFunction> function = |
1233 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 1226 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
1234 context, | 1227 context, |
1235 TENURED); | 1228 TENURED); |
1236 value = function; | 1229 value = function; |
1237 } | 1230 } |
1238 | 1231 |
1239 LookupResult lookup; | 1232 LookupResult lookup; |
1240 global->LocalLookup(*name, &lookup); | 1233 global->LocalLookup(*name, &lookup); |
1241 | 1234 |
1242 PropertyAttributes attributes = is_const_property | |
1243 ? static_cast<PropertyAttributes>(base | READ_ONLY) | |
1244 : base; | |
1245 | |
1246 // There's a local property that we need to overwrite because | 1235 // There's a local property that we need to overwrite because |
1247 // we're either declaring a function or there's an interceptor | 1236 // we're either declaring a function or there's an interceptor |
1248 // that claims the property is absent. | 1237 // that claims the property is absent. |
1249 // | 1238 // |
1250 // Check for conflicting re-declarations. We cannot have | 1239 // Check for conflicting re-declarations. We cannot have |
1251 // conflicting types in case of intercepted properties because | 1240 // conflicting types in case of intercepted properties because |
1252 // they are absent. | 1241 // they are absent. |
1253 if (lookup.IsProperty() && | 1242 if (lookup.IsProperty() && |
1254 (lookup.type() != INTERCEPTOR) && | 1243 (lookup.type() != INTERCEPTOR) && |
1255 (lookup.IsReadOnly() || is_const_property)) { | 1244 (lookup.IsReadOnly() || is_const_property)) { |
1256 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; | 1245 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; |
1257 return ThrowRedeclarationError(isolate, type, name); | 1246 return ThrowRedeclarationError(isolate, type, name); |
1258 } | 1247 } |
1259 | 1248 |
| 1249 // Compute the property attributes. According to ECMA-262, section |
| 1250 // 13, page 71, the property must be read-only and |
| 1251 // non-deletable. However, neither SpiderMonkey nor KJS creates the |
| 1252 // property as read-only, so we don't either. |
| 1253 int attr = NONE; |
| 1254 if ((flags & kDeclareGlobalsEvalFlag) == 0) { |
| 1255 attr |= DONT_DELETE; |
| 1256 } |
| 1257 bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0; |
| 1258 if (is_const_property || (is_native && is_function_declaration)) { |
| 1259 attr |= READ_ONLY; |
| 1260 } |
| 1261 |
1260 // Safari does not allow the invocation of callback setters for | 1262 // Safari does not allow the invocation of callback setters for |
1261 // function declarations. To mimic this behavior, we do not allow | 1263 // function declarations. To mimic this behavior, we do not allow |
1262 // the invocation of setters for function values. This makes a | 1264 // the invocation of setters for function values. This makes a |
1263 // difference for global functions with the same names as event | 1265 // difference for global functions with the same names as event |
1264 // handlers such as "function onload() {}". Firefox does call the | 1266 // handlers such as "function onload() {}". Firefox does call the |
1265 // onload setter in those case and Safari does not. We follow | 1267 // onload setter in those case and Safari does not. We follow |
1266 // Safari for compatibility. | 1268 // Safari for compatibility. |
1267 if (value->IsJSFunction()) { | 1269 if (value->IsJSFunction()) { |
1268 // Do not change DONT_DELETE to false from true. | 1270 // Do not change DONT_DELETE to false from true. |
1269 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { | 1271 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { |
1270 attributes = static_cast<PropertyAttributes>( | 1272 attr |= lookup.GetAttributes() & DONT_DELETE; |
1271 attributes | (lookup.GetAttributes() & DONT_DELETE)); | |
1272 } | 1273 } |
| 1274 PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); |
| 1275 |
1273 RETURN_IF_EMPTY_HANDLE(isolate, | 1276 RETURN_IF_EMPTY_HANDLE(isolate, |
1274 SetLocalPropertyIgnoreAttributes(global, | 1277 SetLocalPropertyIgnoreAttributes(global, |
1275 name, | 1278 name, |
1276 value, | 1279 value, |
1277 attributes)); | 1280 attributes)); |
1278 } else { | 1281 } else { |
| 1282 StrictModeFlag strict_mode = |
| 1283 ((flags & kDeclareGlobalsStrictModeFlag) != 0) ? kStrictMode |
| 1284 : kNonStrictMode; |
1279 RETURN_IF_EMPTY_HANDLE(isolate, | 1285 RETURN_IF_EMPTY_HANDLE(isolate, |
1280 SetProperty(global, | 1286 SetProperty(global, |
1281 name, | 1287 name, |
1282 value, | 1288 value, |
1283 attributes, | 1289 static_cast<PropertyAttributes>(attr), |
1284 strict_mode)); | 1290 strict_mode)); |
1285 } | 1291 } |
1286 } | 1292 } |
1287 | 1293 |
1288 ASSERT(!isolate->has_pending_exception()); | 1294 ASSERT(!isolate->has_pending_exception()); |
1289 return isolate->heap()->undefined_value(); | 1295 return isolate->heap()->undefined_value(); |
1290 } | 1296 } |
1291 | 1297 |
1292 | 1298 |
1293 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { | 1299 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { |
(...skipping 11693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12987 } else { | 12993 } else { |
12988 // Handle last resort GC and make sure to allow future allocations | 12994 // Handle last resort GC and make sure to allow future allocations |
12989 // to grow the heap without causing GCs (if possible). | 12995 // to grow the heap without causing GCs (if possible). |
12990 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12996 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12991 isolate->heap()->CollectAllGarbage(false); | 12997 isolate->heap()->CollectAllGarbage(false); |
12992 } | 12998 } |
12993 } | 12999 } |
12994 | 13000 |
12995 | 13001 |
12996 } } // namespace v8::internal | 13002 } } // namespace v8::internal |
OLD | NEW |