| 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 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 } | 872 } |
| 873 } | 873 } |
| 874 | 874 |
| 875 | 875 |
| 876 enum MayAccessDecision { | 876 enum MayAccessDecision { |
| 877 YES, NO, UNKNOWN | 877 YES, NO, UNKNOWN |
| 878 }; | 878 }; |
| 879 | 879 |
| 880 | 880 |
| 881 static MayAccessDecision MayAccessPreCheck(Isolate* isolate, | 881 static MayAccessDecision MayAccessPreCheck(Isolate* isolate, |
| 882 JSObject* receiver, | 882 JSObject* receiver) { |
| 883 v8::AccessType type) { | |
| 884 // During bootstrapping, callback functions are not enabled yet. | 883 // During bootstrapping, callback functions are not enabled yet. |
| 885 if (isolate->bootstrapper()->IsActive()) return YES; | 884 if (isolate->bootstrapper()->IsActive()) return YES; |
| 886 | 885 |
| 887 if (receiver->IsJSGlobalProxy()) { | 886 if (receiver->IsJSGlobalProxy()) { |
| 888 Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context(); | 887 Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context(); |
| 889 if (!receiver_context->IsContext()) return NO; | 888 if (!receiver_context->IsContext()) return NO; |
| 890 | 889 |
| 891 // Get the native context of current top context. | 890 // Get the native context of current top context. |
| 892 // avoid using Isolate::native_context() because it uses Handle. | 891 // avoid using Isolate::native_context() because it uses Handle. |
| 893 Context* native_context = | 892 Context* native_context = |
| (...skipping 17 matching lines...) Expand all Loading... |
| 911 AssertNoAllocation no_gc; | 910 AssertNoAllocation no_gc; |
| 912 | 911 |
| 913 // Skip checks for hidden properties access. Note, we do not | 912 // Skip checks for hidden properties access. Note, we do not |
| 914 // require existence of a context in this case. | 913 // require existence of a context in this case. |
| 915 if (key == heap_.hidden_symbol()) return true; | 914 if (key == heap_.hidden_symbol()) return true; |
| 916 | 915 |
| 917 // Check for compatibility between the security tokens in the | 916 // Check for compatibility between the security tokens in the |
| 918 // current lexical context and the accessed object. | 917 // current lexical context and the accessed object. |
| 919 ASSERT(context()); | 918 ASSERT(context()); |
| 920 | 919 |
| 921 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); | 920 MayAccessDecision decision = MayAccessPreCheck(this, receiver); |
| 922 if (decision != UNKNOWN) return decision == YES; | 921 if (decision != UNKNOWN) return decision == YES; |
| 923 | 922 |
| 924 // Get named access check callback | 923 // Get named access check callback |
| 925 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); | 924 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
| 926 if (!constructor->shared()->IsApiFunction()) return false; | 925 if (!constructor->shared()->IsApiFunction()) return false; |
| 927 | 926 |
| 928 Object* data_obj = | 927 Object* data_obj = |
| 929 constructor->shared()->get_api_func_data()->access_check_info(); | 928 constructor->shared()->get_api_func_data()->access_check_info(); |
| 930 if (data_obj == heap_.undefined_value()) return false; | 929 if (data_obj == heap_.undefined_value()) return false; |
| 931 | 930 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 954 | 953 |
| 955 | 954 |
| 956 bool Isolate::MayIndexedAccess(JSObject* receiver, | 955 bool Isolate::MayIndexedAccess(JSObject* receiver, |
| 957 uint32_t index, | 956 uint32_t index, |
| 958 v8::AccessType type) { | 957 v8::AccessType type) { |
| 959 ASSERT(receiver->IsAccessCheckNeeded()); | 958 ASSERT(receiver->IsAccessCheckNeeded()); |
| 960 // Check for compatibility between the security tokens in the | 959 // Check for compatibility between the security tokens in the |
| 961 // current lexical context and the accessed object. | 960 // current lexical context and the accessed object. |
| 962 ASSERT(context()); | 961 ASSERT(context()); |
| 963 | 962 |
| 964 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); | 963 MayAccessDecision decision = MayAccessPreCheck(this, receiver); |
| 965 if (decision != UNKNOWN) return decision == YES; | 964 if (decision != UNKNOWN) return decision == YES; |
| 966 | 965 |
| 967 // Get indexed access check callback | 966 // Get indexed access check callback |
| 968 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); | 967 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
| 969 if (!constructor->shared()->IsApiFunction()) return false; | 968 if (!constructor->shared()->IsApiFunction()) return false; |
| 970 | 969 |
| 971 Object* data_obj = | 970 Object* data_obj = |
| 972 constructor->shared()->get_api_func_data()->access_check_info(); | 971 constructor->shared()->get_api_func_data()->access_check_info(); |
| 973 if (data_obj == heap_.undefined_value()) return false; | 972 if (data_obj == heap_.undefined_value()) return false; |
| 974 | 973 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 988 VMState state(this, EXTERNAL); | 987 VMState state(this, EXTERNAL); |
| 989 result = callback(v8::Utils::ToLocal(receiver_handle), | 988 result = callback(v8::Utils::ToLocal(receiver_handle), |
| 990 index, | 989 index, |
| 991 type, | 990 type, |
| 992 v8::Utils::ToLocal(data)); | 991 v8::Utils::ToLocal(data)); |
| 993 } | 992 } |
| 994 return result; | 993 return result; |
| 995 } | 994 } |
| 996 | 995 |
| 997 | 996 |
| 997 bool Isolate::MayObserveAccess(JSObject* receiver) { |
| 998 ASSERT(receiver->IsAccessCheckNeeded()); |
| 999 // Check for compatibility between the security tokens in the |
| 1000 // current lexical context and the accessed object. |
| 1001 ASSERT(context()); |
| 1002 |
| 1003 MayAccessDecision decision = MayAccessPreCheck(this, receiver); |
| 1004 if (decision != UNKNOWN) return decision == YES; |
| 1005 |
| 1006 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
| 1007 if (!constructor->shared()->IsApiFunction()) return false; |
| 1008 |
| 1009 Object* data_obj = |
| 1010 constructor->shared()->get_api_func_data()->access_check_info(); |
| 1011 if (data_obj == heap_.undefined_value()) return false; |
| 1012 |
| 1013 Object* fun_obj = AccessCheckInfo::cast(data_obj)->observe_callback(); |
| 1014 v8::ObserveSecurityCallback callback = |
| 1015 v8::ToCData<v8::ObserveSecurityCallback>(fun_obj); |
| 1016 |
| 1017 if (!callback) return false; |
| 1018 |
| 1019 HandleScope scope(this); |
| 1020 Handle<JSObject> receiver_handle(receiver, this); |
| 1021 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); |
| 1022 bool result = false; |
| 1023 { |
| 1024 // Leaving JavaScript. |
| 1025 VMState state(this, EXTERNAL); |
| 1026 result = callback(v8::Utils::ToLocal(receiver_handle), |
| 1027 v8::Utils::ToLocal(data)); |
| 1028 } |
| 1029 return result; |
| 1030 } |
| 1031 |
| 1032 |
| 998 const char* const Isolate::kStackOverflowMessage = | 1033 const char* const Isolate::kStackOverflowMessage = |
| 999 "Uncaught RangeError: Maximum call stack size exceeded"; | 1034 "Uncaught RangeError: Maximum call stack size exceeded"; |
| 1000 | 1035 |
| 1001 | 1036 |
| 1002 Failure* Isolate::StackOverflow() { | 1037 Failure* Isolate::StackOverflow() { |
| 1003 HandleScope scope; | 1038 HandleScope scope; |
| 1004 // At this point we cannot create an Error object using its javascript | 1039 // At this point we cannot create an Error object using its javascript |
| 1005 // constructor. Instead, we copy the pre-constructed boilerplate and | 1040 // constructor. Instead, we copy the pre-constructed boilerplate and |
| 1006 // attach the stack trace as a hidden property. | 1041 // attach the stack trace as a hidden property. |
| 1007 Handle<String> key = factory()->stack_overflow_symbol(); | 1042 Handle<String> key = factory()->stack_overflow_symbol(); |
| (...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2210 | 2245 |
| 2211 #ifdef DEBUG | 2246 #ifdef DEBUG |
| 2212 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 2247 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
| 2213 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 2248 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
| 2214 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 2249 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
| 2215 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 2250 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
| 2216 #undef ISOLATE_FIELD_OFFSET | 2251 #undef ISOLATE_FIELD_OFFSET |
| 2217 #endif | 2252 #endif |
| 2218 | 2253 |
| 2219 } } // namespace v8::internal | 2254 } } // namespace v8::internal |
| OLD | NEW |