1/*
2 * Copyright (C) 2016 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. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "JSGlobalObject.h"
29
30#include "ArrayConstructor.h"
31#include "ArrayPrototype.h"
32#include "JSFunction.h"
33#include "LinkTimeConstant.h"
34#include "ObjectPrototype.h"
35
36namespace JSC {
37
38ALWAYS_INLINE bool JSGlobalObject::objectPrototypeIsSane()
39{
40 return !hasIndexedProperties(m_objectPrototype->indexingType())
41 && m_objectPrototype->getPrototypeDirect(vm()).isNull();
42}
43
44ALWAYS_INLINE bool JSGlobalObject::arrayPrototypeChainIsSane()
45{
46 return !hasIndexedProperties(m_arrayPrototype->indexingType())
47 && m_arrayPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
48 && objectPrototypeIsSane();
49}
50
51ALWAYS_INLINE bool JSGlobalObject::stringPrototypeChainIsSane()
52{
53 return !hasIndexedProperties(m_stringPrototype->indexingType())
54 && m_stringPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
55 && objectPrototypeIsSane();
56}
57
58ALWAYS_INLINE bool JSGlobalObject::isArrayPrototypeIteratorProtocolFastAndNonObservable()
59{
60 // We're fast if we don't have any indexed properties on the prototype.
61 // We're non-observable if the iteration protocol hasn't changed.
62 //
63 // Note: it only makes sense to call this from the main thread. If you're
64 // trying to prove this behavior on the compiler thread, you'll want to
65 // carefully set up watchpoints to have correct ordering while JS code is
66 // executing concurrently.
67
68 return arrayIteratorProtocolWatchpointSet().isStillValid() && !isHavingABadTime() && arrayPrototypeChainIsSane();
69}
70
71// We're non-observable if the iteration protocol hasn't changed.
72//
73// Note: it only makes sense to call this from the main thread. If you're
74// trying to prove this behavior on the compiler thread, you'll want to
75// carefully set up watchpoints to have correct ordering while JS code is
76// executing concurrently.
77ALWAYS_INLINE bool JSGlobalObject::isMapPrototypeIteratorProtocolFastAndNonObservable()
78{
79 return mapIteratorProtocolWatchpointSet().isStillValid();
80}
81
82ALWAYS_INLINE bool JSGlobalObject::isSetPrototypeIteratorProtocolFastAndNonObservable()
83{
84 return setIteratorProtocolWatchpointSet().isStillValid();
85}
86
87ALWAYS_INLINE bool JSGlobalObject::isStringPrototypeIteratorProtocolFastAndNonObservable()
88{
89 return stringIteratorProtocolWatchpointSet().isStillValid();
90}
91
92ALWAYS_INLINE bool JSGlobalObject::isMapPrototypeSetFastAndNonObservable()
93{
94 return mapSetWatchpointSet().isStillValid();
95}
96
97ALWAYS_INLINE bool JSGlobalObject::isSetPrototypeAddFastAndNonObservable()
98{
99 return setAddWatchpointSet().isStillValid();
100}
101
102ALWAYS_INLINE Structure* JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation(JSGlobalObject* globalObject, IndexingType indexingType, JSValue newTarget) const
103{
104 return InternalFunction::createSubclassStructure(globalObject, globalObject->arrayConstructor(), newTarget, arrayStructureForIndexingTypeDuringAllocation(indexingType));
105}
106
107inline JSFunction* JSGlobalObject::throwTypeErrorFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::throwTypeErrorFunction)); }
108inline JSFunction* JSGlobalObject::newPromiseCapabilityFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::newPromiseCapability)); }
109inline JSFunction* JSGlobalObject::resolvePromiseFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::resolvePromise)); }
110inline JSFunction* JSGlobalObject::rejectPromiseFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::rejectPromise)); }
111inline JSFunction* JSGlobalObject::promiseProtoThenFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::defaultPromiseThen)); }
112inline JSFunction* JSGlobalObject::regExpProtoExecFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::regExpBuiltinExec)); }
113inline GetterSetter* JSGlobalObject::regExpProtoGlobalGetter() const { return bitwise_cast<GetterSetter*>(linkTimeConstant(LinkTimeConstant::regExpProtoGlobalGetter)); }
114inline GetterSetter* JSGlobalObject::regExpProtoUnicodeGetter() const { return bitwise_cast<GetterSetter*>(linkTimeConstant(LinkTimeConstant::regExpProtoUnicodeGetter)); }
115
116ALWAYS_INLINE VM& getVM(JSGlobalObject* globalObject)
117{
118 return globalObject->vm();
119}
120
121} // namespace JSC
122