Home | History | Annotate | Download | only in runtime
      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