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

Side by Side Diff: src/runtime.cc

Issue 7736018: Make functions on the built-in object non-writable. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments. Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698