1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/runtime/runtime-utils.h" 6 7 #include "src/arguments.h" 8 #include "src/debug/debug.h" 9 #include "src/isolate-inl.h" 10 11 namespace v8 { 12 namespace internal { 13 14 RUNTIME_FUNCTION(Runtime_IsObserved) { 15 SealHandleScope shs(isolate); 16 DCHECK(args.length() == 1); 17 18 if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value(); 19 CONVERT_ARG_CHECKED(JSReceiver, obj, 0); 20 DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed()); 21 return isolate->heap()->ToBoolean(obj->map()->is_observed()); 22 } 23 24 25 RUNTIME_FUNCTION(Runtime_SetIsObserved) { 26 HandleScope scope(isolate); 27 DCHECK(args.length() == 1); 28 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); 29 RUNTIME_ASSERT(!obj->IsJSGlobalProxy()); 30 if (obj->IsJSProxy()) return isolate->heap()->undefined_value(); 31 RUNTIME_ASSERT(!obj->map()->is_observed()); 32 33 DCHECK(obj->IsJSObject()); 34 JSObject::SetObserved(Handle<JSObject>::cast(obj)); 35 return isolate->heap()->undefined_value(); 36 } 37 38 39 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) { 40 HandleScope scope(isolate); 41 DCHECK(args.length() == 1); 42 CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0); 43 isolate->EnqueueMicrotask(microtask); 44 return isolate->heap()->undefined_value(); 45 } 46 47 48 RUNTIME_FUNCTION(Runtime_RunMicrotasks) { 49 HandleScope scope(isolate); 50 DCHECK(args.length() == 0); 51 isolate->RunMicrotasks(); 52 return isolate->heap()->undefined_value(); 53 } 54 55 56 RUNTIME_FUNCTION(Runtime_DeliverObservationChangeRecords) { 57 HandleScope scope(isolate); 58 DCHECK(args.length() == 2); 59 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callback, 0); 60 CONVERT_ARG_HANDLE_CHECKED(Object, argument, 1); 61 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); 62 // We should send a message on uncaught exception thrown during 63 // Object.observe delivery while not interrupting further delivery, thus 64 // we make a call inside a verbose TryCatch. 65 catcher.SetVerbose(true); 66 Handle<Object> argv[] = {argument}; 67 68 // If we are in step-in mode, flood the handler. 69 isolate->debug()->EnableStepIn(); 70 71 USE(Execution::Call(isolate, callback, isolate->factory()->undefined_value(), 72 arraysize(argv), argv)); 73 if (isolate->has_pending_exception()) { 74 isolate->ReportPendingMessages(); 75 isolate->clear_pending_exception(); 76 isolate->set_external_caught_exception(false); 77 } 78 return isolate->heap()->undefined_value(); 79 } 80 81 82 RUNTIME_FUNCTION(Runtime_GetObservationState) { 83 HandleScope scope(isolate); 84 DCHECK(args.length() == 0); 85 isolate->CountUsage(v8::Isolate::kObjectObserve); 86 return isolate->heap()->observation_state(); 87 } 88 89 90 static bool ContextsHaveSameOrigin(Handle<Context> context1, 91 Handle<Context> context2) { 92 return context1->security_token() == context2->security_token(); 93 } 94 95 96 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) { 97 HandleScope scope(isolate); 98 DCHECK(args.length() == 3); 99 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, observer, 0); 100 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1); 101 CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2); 102 103 while (observer->IsJSBoundFunction()) { 104 observer = handle( 105 Handle<JSBoundFunction>::cast(observer)->bound_target_function()); 106 } 107 if (!observer->IsJSFunction()) return isolate->heap()->false_value(); 108 109 Handle<Context> observer_context( 110 Handle<JSFunction>::cast(observer)->context()->native_context()); 111 Handle<Context> object_context(object->GetCreationContext()); 112 Handle<Context> record_context(record->GetCreationContext()); 113 114 return isolate->heap()->ToBoolean( 115 ContextsHaveSameOrigin(object_context, observer_context) && 116 ContextsHaveSameOrigin(object_context, record_context)); 117 } 118 119 120 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) { 121 HandleScope scope(isolate); 122 DCHECK(args.length() == 1); 123 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 124 125 Handle<Context> creation_context(object->GetCreationContext(), isolate); 126 return isolate->heap()->ToBoolean( 127 ContextsHaveSameOrigin(creation_context, isolate->native_context())); 128 } 129 130 131 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) { 132 HandleScope scope(isolate); 133 DCHECK(args.length() == 1); 134 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 135 136 Handle<Context> context(object->GetCreationContext(), isolate); 137 return context->native_object_observe(); 138 } 139 140 141 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) { 142 HandleScope scope(isolate); 143 DCHECK(args.length() == 1); 144 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 145 146 Handle<Context> context(object->GetCreationContext(), isolate); 147 return context->native_object_get_notifier(); 148 } 149 150 151 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) { 152 HandleScope scope(isolate); 153 DCHECK(args.length() == 1); 154 CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0); 155 156 Handle<Context> context(object_info->GetCreationContext(), isolate); 157 return context->native_object_notifier_perform_change(); 158 } 159 } // namespace internal 160 } // namespace v8 161