/ runtime / JSMicrotask.cpp
JSMicrotask.cpp
 1  /*
 2   * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
 3   *
 4   * Redistribution and use in source and binary forms, with or without
 5   * modification, are permitted provided that the following conditions
 6   * are met:
 7   * 1. Redistributions of source code must retain the above copyright
 8   *    notice, this list of conditions and the following disclaimer.
 9   * 2. Redistributions in binary form must reproduce the above copyright
10   *    notice, this list of conditions and the following disclaimer in the
11   *    documentation and/or other materials provided with the distribution.
12   *
13   * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23   * THE POSSIBILITY OF SUCH DAMAGE.
24   */
25  
26  #include "config.h"
27  #include "JSMicrotask.h"
28  
29  #include "CatchScope.h"
30  #include "Debugger.h"
31  #include "JSGlobalObject.h"
32  #include "JSObjectInlines.h"
33  #include "Microtask.h"
34  #include "StrongInlines.h"
35  
36  namespace JSC {
37  
38  class JSMicrotask final : public Microtask {
39  public:
40      static constexpr unsigned maxArguments = 3;
41      JSMicrotask(VM& vm, JSValue job, JSValue argument0, JSValue argument1, JSValue argument2)
42      {
43          m_job.set(vm, job);
44          m_arguments[0].set(vm, argument0);
45          m_arguments[1].set(vm, argument1);
46          m_arguments[2].set(vm, argument2);
47      }
48  
49      JSMicrotask(VM& vm, JSValue job)
50      {
51          m_job.set(vm, job);
52      }
53  
54  private:
55      void run(JSGlobalObject*) final;
56  
57      Strong<Unknown> m_job;
58      Strong<Unknown> m_arguments[maxArguments];
59  };
60  
61  Ref<Microtask> createJSMicrotask(VM& vm, JSValue job)
62  {
63      return adoptRef(*new JSMicrotask(vm, job));
64  }
65  
66  Ref<Microtask> createJSMicrotask(VM& vm, JSValue job, JSValue argument0, JSValue argument1, JSValue argument2)
67  {
68      return adoptRef(*new JSMicrotask(vm, job, argument0, argument1, argument2));
69  }
70  
71  void JSMicrotask::run(JSGlobalObject* globalObject)
72  {
73      VM& vm = globalObject->vm();
74      auto scope = DECLARE_CATCH_SCOPE(vm);
75  
76      auto handlerCallData = getCallData(vm, m_job.get());
77      ASSERT(handlerCallData.type != CallData::Type::None);
78  
79      MarkedArgumentBuffer handlerArguments;
80      for (unsigned index = 0; index < maxArguments; ++index) {
81          JSValue arg = m_arguments[index].get();
82          if (!arg)
83              break;
84          handlerArguments.append(arg);
85      }
86      if (UNLIKELY(handlerArguments.hasOverflowed()))
87          return;
88  
89      if (UNLIKELY(globalObject->hasDebugger()))
90          globalObject->debugger()->willRunMicrotask();
91  
92      profiledCall(globalObject, ProfilingReason::Microtask, m_job.get(), handlerCallData, jsUndefined(), handlerArguments);
93      scope.clearException();
94  
95      if (UNLIKELY(globalObject->hasDebugger()))
96          globalObject->debugger()->didRunMicrotask();
97  }
98  
99  } // namespace JSC