OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 ASSERT(args.length() == 1); | 1091 ASSERT(args.length() == 1); |
1092 Object* obj = args[0]; | 1092 Object* obj = args[0]; |
1093 if (!obj->IsJSObject()) return isolate->heap()->null_value(); | 1093 if (!obj->IsJSObject()) return isolate->heap()->null_value(); |
1094 return JSObject::cast(obj)->class_name(); | 1094 return JSObject::cast(obj)->class_name(); |
1095 } | 1095 } |
1096 | 1096 |
1097 | 1097 |
1098 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { | 1098 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { |
1099 NoHandleAllocation ha(isolate); | 1099 NoHandleAllocation ha(isolate); |
1100 ASSERT(args.length() == 1); | 1100 ASSERT(args.length() == 1); |
1101 CONVERT_ARG_CHECKED(JSReceiver, input_obj, 0); | 1101 CONVERT_ARG_CHECKED(Object, obj, 0); |
1102 Object* obj = input_obj; | |
1103 // We don't expect access checks to be needed on JSProxy objects. | 1102 // We don't expect access checks to be needed on JSProxy objects. |
1104 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 1103 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
1105 do { | 1104 do { |
1106 if (obj->IsAccessCheckNeeded() && | 1105 if (obj->IsAccessCheckNeeded() && |
1107 !isolate->MayNamedAccess(JSObject::cast(obj), | 1106 !isolate->MayNamedAccess(JSObject::cast(obj), |
1108 isolate->heap()->proto_string(), | 1107 isolate->heap()->proto_string(), |
1109 v8::ACCESS_GET)) { | 1108 v8::ACCESS_GET)) { |
1110 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); | 1109 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); |
1111 return isolate->heap()->undefined_value(); | 1110 return isolate->heap()->undefined_value(); |
1112 } | 1111 } |
1113 obj = obj->GetPrototype(isolate); | 1112 obj = obj->GetPrototype(isolate); |
1114 } while (obj->IsJSObject() && | 1113 } while (obj->IsJSObject() && |
1115 JSObject::cast(obj)->map()->is_hidden_prototype()); | 1114 JSObject::cast(obj)->map()->is_hidden_prototype()); |
1116 return obj; | 1115 return obj; |
1117 } | 1116 } |
1118 | 1117 |
1119 | 1118 |
| 1119 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, |
| 1120 Object* receiver) { |
| 1121 Object* current = receiver->GetPrototype(isolate); |
| 1122 while (current->IsJSObject() && |
| 1123 JSObject::cast(current)->map()->is_hidden_prototype()) { |
| 1124 current = current->GetPrototype(isolate); |
| 1125 } |
| 1126 return current; |
| 1127 } |
| 1128 |
| 1129 |
1120 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) { | 1130 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) { |
1121 NoHandleAllocation ha(isolate); | 1131 NoHandleAllocation ha(isolate); |
1122 ASSERT(args.length() == 2); | 1132 ASSERT(args.length() == 2); |
1123 CONVERT_ARG_CHECKED(JSReceiver, input_obj, 0); | 1133 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
1124 CONVERT_ARG_CHECKED(Object, prototype, 1); | 1134 CONVERT_ARG_CHECKED(Object, prototype, 1); |
1125 return input_obj->SetPrototype(prototype, true); | 1135 if (FLAG_harmony_observation && obj->map()->is_observed()) { |
| 1136 HandleScope scope(isolate); |
| 1137 Handle<JSObject> receiver(obj); |
| 1138 Handle<Object> value(prototype, isolate); |
| 1139 Handle<Object> old_value( |
| 1140 GetPrototypeSkipHiddenPrototypes(isolate, *receiver), isolate); |
| 1141 |
| 1142 MaybeObject* result = receiver->SetPrototype(*value, true); |
| 1143 Handle<Object> hresult; |
| 1144 if (!result->ToHandle(&hresult, isolate)) return result; |
| 1145 |
| 1146 Handle<Object> new_value( |
| 1147 GetPrototypeSkipHiddenPrototypes(isolate, *receiver), isolate); |
| 1148 if (!new_value->SameValue(*old_value)) { |
| 1149 JSObject::EnqueueChangeRecord(receiver, "prototype", |
| 1150 isolate->factory()->proto_string(), |
| 1151 old_value); |
| 1152 } |
| 1153 return *hresult; |
| 1154 } |
| 1155 return obj->SetPrototype(prototype, true); |
1126 } | 1156 } |
1127 | 1157 |
1128 | 1158 |
1129 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { | 1159 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { |
1130 NoHandleAllocation ha(isolate); | 1160 NoHandleAllocation ha(isolate); |
1131 ASSERT(args.length() == 2); | 1161 ASSERT(args.length() == 2); |
1132 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). | 1162 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
1133 Object* O = args[0]; | 1163 Object* O = args[0]; |
1134 Object* V = args[1]; | 1164 Object* V = args[1]; |
1135 while (true) { | 1165 while (true) { |
(...skipping 3108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4244 | 4274 |
4245 // Special case for callback properties. | 4275 // Special case for callback properties. |
4246 if (result.IsPropertyCallbacks()) { | 4276 if (result.IsPropertyCallbacks()) { |
4247 Object* callback = result.GetCallbackObject(); | 4277 Object* callback = result.GetCallbackObject(); |
4248 // To be compatible with Safari we do not change the value on API objects | 4278 // To be compatible with Safari we do not change the value on API objects |
4249 // in Object.defineProperty(). Firefox disagrees here, and actually changes | 4279 // in Object.defineProperty(). Firefox disagrees here, and actually changes |
4250 // the value. | 4280 // the value. |
4251 if (callback->IsAccessorInfo()) { | 4281 if (callback->IsAccessorInfo()) { |
4252 return isolate->heap()->undefined_value(); | 4282 return isolate->heap()->undefined_value(); |
4253 } | 4283 } |
4254 // TODO(mstarzinger): The __proto__ property should actually be a real | |
4255 // JavaScript accessor instead of a foreign callback. But for now we just | |
4256 // avoid changing the writability and configurability attribute of this | |
4257 // property. | |
4258 Handle<Name> proto_string = isolate->factory()->proto_string(); | |
4259 if (callback->IsForeign() && proto_string->Equals(*name)) { | |
4260 attr = static_cast<PropertyAttributes>(attr & ~(READ_ONLY | DONT_DELETE)); | |
4261 } | |
4262 // Avoid redefining foreign callback as data property, just use the stored | 4284 // Avoid redefining foreign callback as data property, just use the stored |
4263 // setter to update the value instead. | 4285 // setter to update the value instead. |
4264 // TODO(mstarzinger): So far this only works if property attributes don't | 4286 // TODO(mstarzinger): So far this only works if property attributes don't |
4265 // change, this should be fixed once we cleanup the underlying code. | 4287 // change, this should be fixed once we cleanup the underlying code. |
4266 if (callback->IsForeign() && result.GetAttributes() == attr) { | 4288 if (callback->IsForeign() && result.GetAttributes() == attr) { |
4267 return js_object->SetPropertyWithCallback(callback, | 4289 return js_object->SetPropertyWithCallback(callback, |
4268 *name, | 4290 *name, |
4269 *obj_value, | 4291 *obj_value, |
4270 result.holder(), | 4292 result.holder(), |
4271 kStrictMode); | 4293 kStrictMode); |
(...skipping 7888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12160 } | 12182 } |
12161 return JSArray::cast(result)->SetContent(instances); | 12183 return JSArray::cast(result)->SetContent(instances); |
12162 } | 12184 } |
12163 | 12185 |
12164 | 12186 |
12165 // Find the effective prototype object as returned by __proto__. | 12187 // Find the effective prototype object as returned by __proto__. |
12166 // args[0]: the object to find the prototype for. | 12188 // args[0]: the object to find the prototype for. |
12167 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { | 12189 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { |
12168 NoHandleAllocation ha(isolate); | 12190 NoHandleAllocation ha(isolate); |
12169 ASSERT(args.length() == 1); | 12191 ASSERT(args.length() == 1); |
12170 | |
12171 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 12192 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
12172 | 12193 return GetPrototypeSkipHiddenPrototypes(isolate, obj); |
12173 // Use the __proto__ accessor. | |
12174 return Accessors::ObjectPrototype.getter(obj, NULL); | |
12175 } | 12194 } |
12176 | 12195 |
12177 | 12196 |
12178 // Patches script source (should be called upon BeforeCompile event). | 12197 // Patches script source (should be called upon BeforeCompile event). |
12179 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) { | 12198 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) { |
12180 HandleScope scope(isolate); | 12199 HandleScope scope(isolate); |
12181 ASSERT(args.length() == 2); | 12200 ASSERT(args.length() == 2); |
12182 | 12201 |
12183 CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0); | 12202 CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0); |
12184 CONVERT_ARG_HANDLE_CHECKED(String, source, 1); | 12203 CONVERT_ARG_HANDLE_CHECKED(String, source, 1); |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13151 // Handle last resort GC and make sure to allow future allocations | 13170 // Handle last resort GC and make sure to allow future allocations |
13152 // to grow the heap without causing GCs (if possible). | 13171 // to grow the heap without causing GCs (if possible). |
13153 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13172 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13154 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13173 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13155 "Runtime::PerformGC"); | 13174 "Runtime::PerformGC"); |
13156 } | 13175 } |
13157 } | 13176 } |
13158 | 13177 |
13159 | 13178 |
13160 } } // namespace v8::internal | 13179 } } // namespace v8::internal |
OLD | NEW |