| 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 |