1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/*
2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  This library is free software; you can redistribute it and/or
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  modify it under the terms of the GNU Library General Public
7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  License as published by the Free Software Foundation; either
8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  This library is distributed in the hope that it will be useful,
11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  Library General Public License for more details.
14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  You should have received a copy of the GNU Library General Public License
16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  along with this library; see the file COPYING.LIB.  If not, write to
17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  Boston, MA 02110-1301, USA.
19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */
21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef Operations_h
23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define Operations_h
24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "ExceptionHelpers.h"
268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Interpreter.h"
27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "JSString.h"
282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "JSValueInlineMethods.h"
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace JSC {
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSValue jsTypeStringForValue(CallFrame*, JSValue);
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool jsIsObjectType(JSValue);
355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool jsIsFunctionType(JSValue);
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    {
39692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length1 = s1->length();
40692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length1)
4133fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return s2;
42692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length2 = s2->length();
43692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length2)
4433fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return s1;
45692e5dbf12901edacf14812a6fae25462920af42Steve Block        if ((length1 + length2) < length1)
46692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
4733fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
48f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned fiberCount = s1->fiberCount() + s2->fiberCount();
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        JSGlobalData* globalData = &exec->globalData();
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
51692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount <= JSString::s_maxInternalRopeLength)
52692e5dbf12901edacf14812a6fae25462920af42Steve Block            return new (globalData) JSString(globalData, fiberCount, s1, s2);
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
54692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
55692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return throwOutOfMemoryError(exec);
57692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s1);
58692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s2);
59692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
6233fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
6333fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    {
64f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length1 = u1.length();
65692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length1)
66692e5dbf12901edacf14812a6fae25462920af42Steve Block            return s2;
67692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length2 = s2->length();
68692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length2)
69692e5dbf12901edacf14812a6fae25462920af42Steve Block            return jsString(exec, u1);
70692e5dbf12901edacf14812a6fae25462920af42Steve Block        if ((length1 + length2) < length1)
71692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
72692e5dbf12901edacf14812a6fae25462920af42Steve Block
73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned fiberCount = 1 + s2->fiberCount();
7433fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block        JSGlobalData* globalData = &exec->globalData();
7533fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
76692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount <= JSString::s_maxInternalRopeLength)
77692e5dbf12901edacf14812a6fae25462920af42Steve Block            return new (globalData) JSString(globalData, fiberCount, u1, s2);
7833fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
79692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
80692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
8133fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return throwOutOfMemoryError(exec);
82692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(u1);
83692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s2);
84692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
8533fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    }
8633fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
8733fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
8833fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    {
89692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length1 = s1->length();
90692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length1)
91692e5dbf12901edacf14812a6fae25462920af42Steve Block            return jsString(exec, u2);
92f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length2 = u2.length();
93692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length2)
94692e5dbf12901edacf14812a6fae25462920af42Steve Block            return s1;
95692e5dbf12901edacf14812a6fae25462920af42Steve Block        if ((length1 + length2) < length1)
96692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
97692e5dbf12901edacf14812a6fae25462920af42Steve Block
98f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned fiberCount = s1->fiberCount() + 1;
9933fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block        JSGlobalData* globalData = &exec->globalData();
10033fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
101692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount <= JSString::s_maxInternalRopeLength)
102692e5dbf12901edacf14812a6fae25462920af42Steve Block            return new (globalData) JSString(globalData, fiberCount, s1, u2);
10333fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
104692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
105692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
10633fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return throwOutOfMemoryError(exec);
107692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s1);
108692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(u2);
109692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
11033fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    }
11133fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
1126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2)
1136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
114f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length1 = u1.length();
1156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length1)
1166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u2);
117f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length2 = u2.length();
1186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length2)
1196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u1);
1206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if ((length1 + length2) < length1)
1216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return throwOutOfMemoryError(exec);
1226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        JSGlobalData* globalData = &exec->globalData();
1246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return new (globalData) JSString(globalData, u1, u2);
1256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3)
1286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
129f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length1 = u1.length();
130f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length2 = u2.length();
131f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length3 = u3.length();
1326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length1)
1336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u2, u3);
1346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length2)
1356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u1, u3);
1366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length3)
1376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u1, u2);
1386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if ((length1 + length2) < length1)
1406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return throwOutOfMemoryError(exec);
1416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if ((length1 + length2 + length3) < length3)
1426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return throwOutOfMemoryError(exec);
1436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        JSGlobalData* globalData = &exec->globalData();
1456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return new (globalData) JSString(globalData, u1, u2, u3);
1466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
148643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    {
150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(count >= 3);
151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
152692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned fiberCount = 0;
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (unsigned i = 0; i < count; ++i) {
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            JSValue v = strings[i].jsValue();
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (LIKELY(v.isString()))
156f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                fiberCount += asString(v)->fiberCount();
157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            else
158692e5dbf12901edacf14812a6fae25462920af42Steve Block                ++fiberCount;
159643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        JSGlobalData* globalData = &exec->globalData();
162692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount == 3)
163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue());
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
165692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
166692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return throwOutOfMemoryError(exec);
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
169692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length = 0;
170692e5dbf12901edacf14812a6fae25462920af42Steve Block        bool overflow = false;
171692e5dbf12901edacf14812a6fae25462920af42Steve Block
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (unsigned i = 0; i < count; ++i) {
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            JSValue v = strings[i].jsValue();
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (LIKELY(v.isString()))
175692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(asString(v));
176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            else
177692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(v.toString(exec));
178692e5dbf12901edacf14812a6fae25462920af42Steve Block
179692e5dbf12901edacf14812a6fae25462920af42Steve Block            unsigned newLength = ropeBuilder.length();
180692e5dbf12901edacf14812a6fae25462920af42Steve Block            if (newLength < length)
181692e5dbf12901edacf14812a6fae25462920af42Steve Block                overflow = true;
182692e5dbf12901edacf14812a6fae25462920af42Steve Block            length = newLength;
183643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
185692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (overflow)
186692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
187692e5dbf12901edacf14812a6fae25462920af42Steve Block
188692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
190643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue)
192d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
193692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned fiberCount = 0;
194d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (LIKELY(thisValue.isString()))
195f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            fiberCount += asString(thisValue)->fiberCount();
196d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
197692e5dbf12901edacf14812a6fae25462920af42Steve Block            ++fiberCount;
1985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        for (unsigned i = 0; i < exec->argumentCount(); ++i) {
1995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            JSValue v = exec->argument(i);
200d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (LIKELY(v.isString()))
201f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                fiberCount += asString(v)->fiberCount();
202d0825bca7fe65beaee391d30da42e937db621564Steve Block            else
203692e5dbf12901edacf14812a6fae25462920af42Steve Block                ++fiberCount;
204d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
205d0825bca7fe65beaee391d30da42e937db621564Steve Block
206692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
207692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
208d0825bca7fe65beaee391d30da42e937db621564Steve Block            return throwOutOfMemoryError(exec);
209d0825bca7fe65beaee391d30da42e937db621564Steve Block
210d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (LIKELY(thisValue.isString()))
211692e5dbf12901edacf14812a6fae25462920af42Steve Block            ropeBuilder.append(asString(thisValue));
212d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
213692e5dbf12901edacf14812a6fae25462920af42Steve Block            ropeBuilder.append(thisValue.toString(exec));
214692e5dbf12901edacf14812a6fae25462920af42Steve Block
215692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length = 0;
216692e5dbf12901edacf14812a6fae25462920af42Steve Block        bool overflow = false;
217692e5dbf12901edacf14812a6fae25462920af42Steve Block
2185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            JSValue v = exec->argument(i);
220d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (LIKELY(v.isString()))
221692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(asString(v));
222d0825bca7fe65beaee391d30da42e937db621564Steve Block            else
223692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(v.toString(exec));
224692e5dbf12901edacf14812a6fae25462920af42Steve Block
225692e5dbf12901edacf14812a6fae25462920af42Steve Block            unsigned newLength = ropeBuilder.length();
226692e5dbf12901edacf14812a6fae25462920af42Steve Block            if (newLength < length)
227692e5dbf12901edacf14812a6fae25462920af42Steve Block                overflow = true;
228692e5dbf12901edacf14812a6fae25462920af42Steve Block            length = newLength;
229d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
230692e5dbf12901edacf14812a6fae25462920af42Steve Block
231692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (overflow)
232692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
233d0825bca7fe65beaee391d30da42e937db621564Steve Block
234d0825bca7fe65beaee391d30da42e937db621564Steve Block        JSGlobalData* globalData = &exec->globalData();
235692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
236d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
237d0825bca7fe65beaee391d30da42e937db621564Steve Block
238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // ECMA 11.9.3
2395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return equalSlowCase(exec, v1, v2);
245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
246635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        do {
250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isNumber() && v2.isNumber())
251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            bool s1 = v1.isString();
254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            bool s2 = v2.isString();
255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (s1 && s2)
256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return asString(v1)->value(exec) == asString(v2)->value(exec);
257635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
258635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isUndefinedOrNull()) {
259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v2.isUndefinedOrNull())
260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return true;
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (!v2.isCell())
262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v2.isUndefinedOrNull()) {
2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (!v1.isCell())
268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isObject()) {
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v2.isObject())
274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1 == v2;
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                JSValue p1 = v1.toPrimitive(exec);
276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (exec->hadException())
277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                v1 = p1;
2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (v1.isInt32() && v2.isInt32())
280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1 == v2;
281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                continue;
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v2.isObject()) {
2855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                JSValue p2 = v2.toPrimitive(exec);
286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (exec->hadException())
287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                v2 = p2;
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (v1.isInt32() && v2.isInt32())
290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1 == v2;
291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                continue;
292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (s1 || s2) {
295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                double d1 = v1.toNumber(exec);
296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                double d2 = v2.toNumber(exec);
297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return d1 == d2;
298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isBoolean()) {
301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v2.isNumber())
302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return static_cast<double>(v1.getBoolean()) == v2.uncheckedGetNumber();
303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            } else if (v2.isBoolean()) {
304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v1.isNumber())
305635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1.uncheckedGetNumber() == static_cast<double>(v2.getBoolean());
306635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } while (true);
310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // ECMA 11.9.3
313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
3145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(v1.isCell() && v2.isCell());
3165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (v1.asCell()->isString() && v2.asCell()->isString())
318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return asString(v1)->value(exec) == asString(v2)->value(exec);
3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return v1 == v2;
3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2)
324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (v1.isNumber() && v2.isNumber())
329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (!v1.isCell() || !v2.isCell())
332635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
333635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return strictEqualSlowCaseInline(exec, v1, v2);
335635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
336635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
337d0825bca7fe65beaee391d30da42e937db621564Steve Block    ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
3388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return v1.asInt32() < v2.asInt32();
3418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n1;
3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n2;
3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (v1.getNumber(n1) && v2.getNumber(n2))
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 < n2;
3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSGlobalData* globalData = &callFrame->globalData();
3488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isJSString(globalData, v1) && isJSString(globalData, v2))
349643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return asString(v1)->value(callFrame) < asString(v2)->value(callFrame);
3508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p1;
3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p2;
3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
3548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
3558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (wasNotString1 | wasNotString2)
3578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 < n2;
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
359643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return asString(p1)->value(callFrame) < asString(p2)->value(callFrame);
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
3638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
3640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
3650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return v1.asInt32() <= v2.asInt32();
3668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n1;
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n2;
3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (v1.getNumber(n1) && v2.getNumber(n2))
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 <= n2;
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSGlobalData* globalData = &callFrame->globalData();
3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isJSString(globalData, v1) && isJSString(globalData, v2))
374643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return !(asString(v2)->value(callFrame) < asString(v1)->value(callFrame));
3758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p1;
3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p2;
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (wasNotString1 | wasNotString2)
3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 <= n2;
3838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
384643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return !(asString(p2)->value(callFrame) < asString(p1)->value(callFrame));
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Fast-path choices here are based on frequency data from SunSpider:
3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    <times> Add case: <t1> <t2>
3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    ---------------------------
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
3918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    247412  Add case: 5 5
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    20900   Add case: 5 6
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    13962   Add case: 5 3
3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    4000    Add case: 3 5
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
398d0825bca7fe65beaee391d30da42e937db621564Steve Block        double left = 0.0, right;
399d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (v1.getNumber(left) && v2.getNumber(right))
400e14391e94c850b8bd03680c23b38978db68687a8John Reck            return jsNumber(left + right);
401d0825bca7fe65beaee391d30da42e937db621564Steve Block
402d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (v1.isString()) {
403d0825bca7fe65beaee391d30da42e937db621564Steve Block            return v2.isString()
404d0825bca7fe65beaee391d30da42e937db621564Steve Block                ? jsString(callFrame, asString(v1), asString(v2))
405d0825bca7fe65beaee391d30da42e937db621564Steve Block                : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // All other cases are pretty uncommon
4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return jsAddSlowCase(callFrame, v1, v2);
4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
412d0825bca7fe65beaee391d30da42e937db621564Steve Block    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset)
4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
414e14391e94c850b8bd03680c23b38978db68687a8John Reck        JSCell* cell = base.asCell();
4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        size_t count = 0;
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
417cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        while (slotBase != cell) {
4185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValue v = cell->structure()->prototypeForLookup(callFrame);
4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
420cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // If we didn't find slotBase in base's prototype chain, then base
4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // must be a proxy for another object.
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (v.isNull())
4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return 0;
4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
426e14391e94c850b8bd03680c23b38978db68687a8John Reck            cell = v.asCell();
4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Since we're accessing a prototype in a loop, it's a good bet that it
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // should not be treated as a dictionary.
430d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (cell->structure()->isDictionary()) {
4312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                asObject(cell)->flattenDictionaryObject(callFrame->globalData());
432d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (slotBase == cell)
4332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    slotOffset = cell->structure()->get(callFrame->globalData(), propertyName);
434d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
4358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ++count;
4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(count);
4408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return count;
4418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
443cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
444cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    {
445cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        size_t count = 0;
446cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        while (1) {
447cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            JSValue v = base->structure()->prototypeForLookup(callFrame);
448cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            if (v.isNull())
449cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                return count;
450cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
451e14391e94c850b8bd03680c23b38978db68687a8John Reck            base = v.asCell();
452cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
453cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // Since we're accessing a prototype in a loop, it's a good bet that it
454cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // should not be treated as a dictionary.
455cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            if (base->structure()->isDictionary())
4562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                asObject(base)->flattenDictionaryObject(callFrame->globalData());
457cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
458cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            ++count;
459cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        }
460cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
461cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain, bool isStrictPut)
4638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ScopeChainIterator iter = scopeChain->begin();
4658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ScopeChainIterator next = iter;
4668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ++next;
4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ScopeChainIterator end = scopeChain->end();
4688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(iter != end);
4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        PropertySlot slot;
4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSObject* base;
4728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        while (true) {
4732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            base = iter->get();
47481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (next == end) {
47581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (isStrictPut && !base->getPropertySlot(callFrame, property, slot))
47681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    return JSValue();
47781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                return base;
47881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (base->getPropertySlot(callFrame, property, slot))
4808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return base;
4818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            iter = next;
4838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ++next;
4848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT_NOT_REACHED();
4875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return JSValue();
4885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace JSC
490635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // Operations_h
492