Operations.h revision 2fc2651226baac27029e38c9d6ef883fa32084db
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 "JSImmediate.h"
28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "JSNumberCell.h"
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "JSString.h"
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace JSC {
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSValue jsTypeStringForValue(CallFrame*, JSValue);
355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool jsIsObjectType(JSValue);
365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool jsIsFunctionType(JSValue);
378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    {
40692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length1 = s1->length();
41692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length1)
4233fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return s2;
43692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length2 = s2->length();
44692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length2)
4533fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return s1;
46692e5dbf12901edacf14812a6fae25462920af42Steve Block        if ((length1 + length2) < length1)
47692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
4833fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
49f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned fiberCount = s1->fiberCount() + s2->fiberCount();
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        JSGlobalData* globalData = &exec->globalData();
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
52692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount <= JSString::s_maxInternalRopeLength)
53692e5dbf12901edacf14812a6fae25462920af42Steve Block            return new (globalData) JSString(globalData, fiberCount, s1, s2);
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
55692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
56692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return throwOutOfMemoryError(exec);
58692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s1);
59692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s2);
60692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
6333fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
6433fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    {
65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length1 = u1.length();
66692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length1)
67692e5dbf12901edacf14812a6fae25462920af42Steve Block            return s2;
68692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length2 = s2->length();
69692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length2)
70692e5dbf12901edacf14812a6fae25462920af42Steve Block            return jsString(exec, u1);
71692e5dbf12901edacf14812a6fae25462920af42Steve Block        if ((length1 + length2) < length1)
72692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
73692e5dbf12901edacf14812a6fae25462920af42Steve Block
74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned fiberCount = 1 + s2->fiberCount();
7533fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block        JSGlobalData* globalData = &exec->globalData();
7633fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
77692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount <= JSString::s_maxInternalRopeLength)
78692e5dbf12901edacf14812a6fae25462920af42Steve Block            return new (globalData) JSString(globalData, fiberCount, u1, s2);
7933fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
80692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
81692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
8233fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return throwOutOfMemoryError(exec);
83692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(u1);
84692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s2);
85692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
8633fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    }
8733fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
8833fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
8933fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    {
90692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length1 = s1->length();
91692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length1)
92692e5dbf12901edacf14812a6fae25462920af42Steve Block            return jsString(exec, u2);
93f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length2 = u2.length();
94692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!length2)
95692e5dbf12901edacf14812a6fae25462920af42Steve Block            return s1;
96692e5dbf12901edacf14812a6fae25462920af42Steve Block        if ((length1 + length2) < length1)
97692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
98692e5dbf12901edacf14812a6fae25462920af42Steve Block
99f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned fiberCount = s1->fiberCount() + 1;
10033fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block        JSGlobalData* globalData = &exec->globalData();
10133fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
102692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount <= JSString::s_maxInternalRopeLength)
103692e5dbf12901edacf14812a6fae25462920af42Steve Block            return new (globalData) JSString(globalData, fiberCount, s1, u2);
10433fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
105692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
106692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
10733fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block            return throwOutOfMemoryError(exec);
108692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(s1);
109692e5dbf12901edacf14812a6fae25462920af42Steve Block        ropeBuilder.append(u2);
110692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
11133fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block    }
11233fc8ca0ce504ea94c9b038e11968187fc10d13eSteve Block
1136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2)
1146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
115f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length1 = u1.length();
1166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length1)
1176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u2);
118f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length2 = u2.length();
1196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length2)
1206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u1);
1216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if ((length1 + length2) < length1)
1226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return throwOutOfMemoryError(exec);
1236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        JSGlobalData* globalData = &exec->globalData();
1256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return new (globalData) JSString(globalData, u1, u2);
1266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3)
1296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
130f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length1 = u1.length();
131f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length2 = u2.length();
132f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        unsigned length3 = u3.length();
1336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length1)
1346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u2, u3);
1356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length2)
1366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u1, u3);
1376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!length3)
1386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return jsString(exec, u1, u2);
1396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if ((length1 + length2) < length1)
1416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return throwOutOfMemoryError(exec);
1426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if ((length1 + length2 + length3) < length3)
1436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return throwOutOfMemoryError(exec);
1446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        JSGlobalData* globalData = &exec->globalData();
1466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return new (globalData) JSString(globalData, u1, u2, u3);
1476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    {
151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(count >= 3);
152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
153692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned fiberCount = 0;
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (unsigned i = 0; i < count; ++i) {
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            JSValue v = strings[i].jsValue();
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (LIKELY(v.isString()))
157f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                fiberCount += asString(v)->fiberCount();
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            else
159692e5dbf12901edacf14812a6fae25462920af42Steve Block                ++fiberCount;
160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        JSGlobalData* globalData = &exec->globalData();
163692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (fiberCount == 3)
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue());
165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
166692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
167692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return throwOutOfMemoryError(exec);
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
170692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length = 0;
171692e5dbf12901edacf14812a6fae25462920af42Steve Block        bool overflow = false;
172692e5dbf12901edacf14812a6fae25462920af42Steve Block
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (unsigned i = 0; i < count; ++i) {
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            JSValue v = strings[i].jsValue();
175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (LIKELY(v.isString()))
176692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(asString(v));
177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            else
178692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(v.toString(exec));
179692e5dbf12901edacf14812a6fae25462920af42Steve Block
180692e5dbf12901edacf14812a6fae25462920af42Steve Block            unsigned newLength = ropeBuilder.length();
181692e5dbf12901edacf14812a6fae25462920af42Steve Block            if (newLength < length)
182692e5dbf12901edacf14812a6fae25462920af42Steve Block                overflow = true;
183692e5dbf12901edacf14812a6fae25462920af42Steve Block            length = newLength;
184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
185643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
186692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (overflow)
187692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
188692e5dbf12901edacf14812a6fae25462920af42Steve Block
189692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
190643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue)
193d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
194692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned fiberCount = 0;
195d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (LIKELY(thisValue.isString()))
196f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            fiberCount += asString(thisValue)->fiberCount();
197d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
198692e5dbf12901edacf14812a6fae25462920af42Steve Block            ++fiberCount;
1995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            JSValue v = exec->argument(i);
201d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (LIKELY(v.isString()))
202f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                fiberCount += asString(v)->fiberCount();
203d0825bca7fe65beaee391d30da42e937db621564Steve Block            else
204692e5dbf12901edacf14812a6fae25462920af42Steve Block                ++fiberCount;
205d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
206d0825bca7fe65beaee391d30da42e937db621564Steve Block
207692e5dbf12901edacf14812a6fae25462920af42Steve Block        JSString::RopeBuilder ropeBuilder(fiberCount);
208692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
209d0825bca7fe65beaee391d30da42e937db621564Steve Block            return throwOutOfMemoryError(exec);
210d0825bca7fe65beaee391d30da42e937db621564Steve Block
211d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (LIKELY(thisValue.isString()))
212692e5dbf12901edacf14812a6fae25462920af42Steve Block            ropeBuilder.append(asString(thisValue));
213d0825bca7fe65beaee391d30da42e937db621564Steve Block        else
214692e5dbf12901edacf14812a6fae25462920af42Steve Block            ropeBuilder.append(thisValue.toString(exec));
215692e5dbf12901edacf14812a6fae25462920af42Steve Block
216692e5dbf12901edacf14812a6fae25462920af42Steve Block        unsigned length = 0;
217692e5dbf12901edacf14812a6fae25462920af42Steve Block        bool overflow = false;
218692e5dbf12901edacf14812a6fae25462920af42Steve Block
2195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        for (unsigned i = 0; i < exec->argumentCount(); ++i) {
2205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            JSValue v = exec->argument(i);
221d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (LIKELY(v.isString()))
222692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(asString(v));
223d0825bca7fe65beaee391d30da42e937db621564Steve Block            else
224692e5dbf12901edacf14812a6fae25462920af42Steve Block                ropeBuilder.append(v.toString(exec));
225692e5dbf12901edacf14812a6fae25462920af42Steve Block
226692e5dbf12901edacf14812a6fae25462920af42Steve Block            unsigned newLength = ropeBuilder.length();
227692e5dbf12901edacf14812a6fae25462920af42Steve Block            if (newLength < length)
228692e5dbf12901edacf14812a6fae25462920af42Steve Block                overflow = true;
229692e5dbf12901edacf14812a6fae25462920af42Steve Block            length = newLength;
230d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
231692e5dbf12901edacf14812a6fae25462920af42Steve Block
232692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (overflow)
233692e5dbf12901edacf14812a6fae25462920af42Steve Block            return throwOutOfMemoryError(exec);
234d0825bca7fe65beaee391d30da42e937db621564Steve Block
235d0825bca7fe65beaee391d30da42e937db621564Steve Block        JSGlobalData* globalData = &exec->globalData();
236692e5dbf12901edacf14812a6fae25462920af42Steve Block        return new (globalData) JSString(globalData, ropeBuilder.release());
237d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
238d0825bca7fe65beaee391d30da42e937db621564Steve Block
239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // ECMA 11.9.3
2405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return equalSlowCase(exec, v1, v2);
246635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        do {
251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isNumber() && v2.isNumber())
252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            bool s1 = v1.isString();
255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            bool s2 = v2.isString();
256635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (s1 && s2)
257643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return asString(v1)->value(exec) == asString(v2)->value(exec);
258635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isUndefinedOrNull()) {
260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v2.isUndefinedOrNull())
261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return true;
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (!v2.isCell())
263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v2.isUndefinedOrNull()) {
2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (!v1.isCell())
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isObject()) {
274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v2.isObject())
275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1 == v2;
2765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                JSValue p1 = v1.toPrimitive(exec);
277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (exec->hadException())
278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                v1 = p1;
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (v1.isInt32() && v2.isInt32())
281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1 == v2;
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                continue;
283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v2.isObject()) {
2865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                JSValue p2 = v2.toPrimitive(exec);
287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (exec->hadException())
288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                v2 = p2;
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (v1.isInt32() && v2.isInt32())
291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1 == v2;
292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                continue;
293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (s1 || s2) {
296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                double d1 = v1.toNumber(exec);
297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                double d2 = v2.toNumber(exec);
298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return d1 == d2;
299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (v1.isBoolean()) {
302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v2.isNumber())
303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return static_cast<double>(v1.getBoolean()) == v2.uncheckedGetNumber();
304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            } else if (v2.isBoolean()) {
305635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (v1.isNumber())
306635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return v1.uncheckedGetNumber() == static_cast<double>(v2.getBoolean());
307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } while (true);
311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
313635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // ECMA 11.9.3
314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
3155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(v1.isCell() && v2.isCell());
3175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (v1.asCell()->isString() && v2.asCell()->isString())
319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return asString(v1)->value(exec) == asString(v2)->value(exec);
3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return v1 == v2;
3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2)
325635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
3260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (v1.isNumber() && v2.isNumber())
330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
331635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (!v1.isCell() || !v2.isCell())
333635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return v1 == v2;
334635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return strictEqualSlowCaseInline(exec, v1, v2);
336635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
338d0825bca7fe65beaee391d30da42e937db621564Steve Block    ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
3398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return v1.asInt32() < v2.asInt32();
3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n1;
3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n2;
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (v1.getNumber(n1) && v2.getNumber(n2))
3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 < n2;
3478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSGlobalData* globalData = &callFrame->globalData();
3498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isJSString(globalData, v1) && isJSString(globalData, v2))
350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return asString(v1)->value(callFrame) < asString(v2)->value(callFrame);
3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p1;
3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p2;
3548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
3558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (wasNotString1 | wasNotString2)
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 < n2;
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
360643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return asString(p1)->value(callFrame) < asString(p2)->value(callFrame);
3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
3648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
3650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (v1.isInt32() && v2.isInt32())
3660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return v1.asInt32() <= v2.asInt32();
3678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n1;
3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        double n2;
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (v1.getNumber(n1) && v2.getNumber(n2))
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 <= n2;
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSGlobalData* globalData = &callFrame->globalData();
3748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isJSString(globalData, v1) && isJSString(globalData, v2))
375643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return !(asString(v2)->value(callFrame) < asString(v1)->value(callFrame));
3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p1;
3785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSValue p2;
3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (wasNotString1 | wasNotString2)
3838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return n1 <= n2;
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return !(asString(p2)->value(callFrame) < asString(p1)->value(callFrame));
3868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Fast-path choices here are based on frequency data from SunSpider:
3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    <times> Add case: <t1> <t2>
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    ---------------------------
3918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    247412  Add case: 5 5
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    20900   Add case: 5 6
3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    13962   Add case: 5 3
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    //    4000    Add case: 3 5
3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
399d0825bca7fe65beaee391d30da42e937db621564Steve Block        double left = 0.0, right;
400d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (v1.getNumber(left) && v2.getNumber(right))
401e14391e94c850b8bd03680c23b38978db68687a8John Reck            return jsNumber(left + right);
402d0825bca7fe65beaee391d30da42e937db621564Steve Block
403d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (v1.isString()) {
404d0825bca7fe65beaee391d30da42e937db621564Steve Block            return v2.isString()
405d0825bca7fe65beaee391d30da42e937db621564Steve Block                ? jsString(callFrame, asString(v1), asString(v2))
406d0825bca7fe65beaee391d30da42e937db621564Steve Block                : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // All other cases are pretty uncommon
4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return jsAddSlowCase(callFrame, v1, v2);
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
413d0825bca7fe65beaee391d30da42e937db621564Steve Block    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset)
4148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
415e14391e94c850b8bd03680c23b38978db68687a8John Reck        JSCell* cell = base.asCell();
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        size_t count = 0;
4178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
418cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        while (slotBase != cell) {
4195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValue v = cell->structure()->prototypeForLookup(callFrame);
4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
421cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // If we didn't find slotBase in base's prototype chain, then base
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // must be a proxy for another object.
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (v.isNull())
4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return 0;
4268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
427e14391e94c850b8bd03680c23b38978db68687a8John Reck            cell = v.asCell();
4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Since we're accessing a prototype in a loop, it's a good bet that it
4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // should not be treated as a dictionary.
431d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (cell->structure()->isDictionary()) {
4322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                asObject(cell)->flattenDictionaryObject(callFrame->globalData());
433d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (slotBase == cell)
434d0825bca7fe65beaee391d30da42e937db621564Steve Block                    slotOffset = cell->structure()->get(propertyName);
435d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ++count;
4388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(count);
4418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return count;
4428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
444cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
445cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    {
446cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        size_t count = 0;
447cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        while (1) {
448cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            JSValue v = base->structure()->prototypeForLookup(callFrame);
449cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            if (v.isNull())
450cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                return count;
451cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
452e14391e94c850b8bd03680c23b38978db68687a8John Reck            base = v.asCell();
453cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
454cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // Since we're accessing a prototype in a loop, it's a good bet that it
455cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            // should not be treated as a dictionary.
456cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            if (base->structure()->isDictionary())
4572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                asObject(base)->flattenDictionaryObject(callFrame->globalData());
458cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
459cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            ++count;
460cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        }
461cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
462cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain, bool isStrictPut)
4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
4658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ScopeChainIterator iter = scopeChain->begin();
4668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ScopeChainIterator next = iter;
4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ++next;
4688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ScopeChainIterator end = scopeChain->end();
4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(iter != end);
4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        PropertySlot slot;
4728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSObject* base;
4738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        while (true) {
4742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            base = iter->get();
475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (next == end)
476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                return isStrictPut ? JSValue() : base;
477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (base->getPropertySlot(callFrame, property, slot))
4788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return base;
4798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            iter = next;
4818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ++next;
4828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT_NOT_REACHED();
4855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return JSValue();
4865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace JSC
488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // Operations_h
490