1fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdlib.h>
29f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org#include <limits>
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "accessors.h"
3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h"
3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "arguments.h"
361805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#include "bootstrapper.h"
37f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org#include "codegen.h"
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "compilation-cache.h"
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "compiler.h"
4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "cpu.h"
41c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h"
42bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include "dateparser-inl.h"
4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h"
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h"
454efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org#include "date.h"
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "execution.h"
47e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "full-codegen.h"
489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org#include "global-handles.h"
49c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "isolate-inl.h"
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "jsregexp.h"
512f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#include "jsregexp-inl.h"
5240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#include "json-parser.h"
5372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org#include "json-stringifier.h"
54ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#include "liveedit.h"
553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org#include "misc-intrinsics.h"
569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#include "parser.h"
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "platform.h"
58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "runtime-profiler.h"
59fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org#include "runtime.h"
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "scopeinfo.h"
61304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#include "smart-pointers.h"
62fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org#include "string-search.h"
6318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include "stub-cache.h"
642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "uri.h"
65e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "v8conversions.h"
669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#include "v8threads.h"
67fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org#include "vm-state-inl.h"
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#ifdef V8_I18N_SUPPORT
70594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "i18n.h"
71594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/brkiter.h"
72594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/calendar.h"
73594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/coll.h"
74594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/curramt.h"
75594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/datefmt.h"
76594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/dcfmtsym.h"
77594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/decimfmt.h"
78594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/dtfmtsym.h"
79594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/dtptngen.h"
80594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/locid.h"
81594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/numfmt.h"
82594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/numsys.h"
83594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/smpdtfmt.h"
84594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/timezone.h"
85594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/uchar.h"
86594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/ucol.h"
87594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/ucurr.h"
88594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/uloc.h"
89594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/unum.h"
90594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/uversion.h"
91594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#endif
92594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
9377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org#ifndef _STLP_VENDOR_CSTD
9477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org// STLPort doesn't import fpclassify and isless into the std namespace.
9577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgusing std::fpclassify;
9677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgusing std::isless;
9777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org#endif
9877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
9971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
10071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1033e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org#define RUNTIME_ASSERT(value) \
104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!(value)) return isolate->ThrowIllegalOperation();
10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Cast the given object to a value of the specified type and store
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// it in a variable with the given name.  If the object is not of the
10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// expected type call IllegalOperation and return.
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CONVERT_ARG_CHECKED(Type, name, index)                       \
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(args[index]->Is##Type());                           \
111f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Type* name = Type::cast(args[index]);
112f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
113f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
114f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->Is##Type());                           \
11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Type> name = args.at<Type>(index);
11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// Cast the given object to a boolean and store it in a variable with
118bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// the given name.  If the object is not a boolean call IllegalOperation
119bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// and return.
120f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
121f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->IsBoolean());                          \
122f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  bool name = args[index]->IsTrue();
123bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
1246d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// Cast the given argument to a Smi and store its value in an int variable
1256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// with the given name.  If the argument is not a Smi call IllegalOperation
126bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// and return.
1276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#define CONVERT_SMI_ARG_CHECKED(name, index)                         \
1286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  RUNTIME_ASSERT(args[index]->IsSmi());                              \
1296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int name = args.smi_at(index);
130bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
1316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// Cast the given argument to a double and store it in a variable with
1326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// the given name.  If the argument is not a number (as opposed to
13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the number not-a-number) call IllegalOperation and return.
1346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
1356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  RUNTIME_ASSERT(args[index]->IsNumber());                           \
1366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  double name = args.number_at(index);
13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Call the specified converter on the object *comand store the result in
13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// a variable of the specified type with the given name.  If the
14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object is not a Number call IllegalOperation and return.
14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(obj->IsNumber());                                   \
14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  type name = NumberTo##Type(obj);
14443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// Cast the given argument to PropertyDetails and store its value in a
147f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// variable with the given name.  If the argument is not a Smi call
148f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// IllegalOperation and return.
149f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
150f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->IsSmi());                              \
151f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
152f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
153f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// Assert that the given argument has a valid value for a StrictModeFlag
155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org// and store it in a StrictModeFlag variable with the given name.
156f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
157f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->IsSmi());                              \
158f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args.smi_at(index) == kStrictMode ||                \
159f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                 args.smi_at(index) == kNonStrictMode);              \
160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  StrictModeFlag name =                                              \
161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      static_cast<StrictModeFlag>(args.smi_at(index));
162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org// Assert that the given argument has a valid value for a LanguageMode
1651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org// and store it in a LanguageMode variable with the given name.
1661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#define CONVERT_LANGUAGE_MODE_ARG(name, index)                       \
1671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ASSERT(args[index]->IsSmi());                                      \
1681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  ASSERT(args.smi_at(index) == CLASSIC_MODE ||                       \
1691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org         args.smi_at(index) == STRICT_MODE ||                        \
1701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org         args.smi_at(index) == EXTENDED_MODE);                       \
1711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  LanguageMode name =                                                \
1721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      static_cast<LanguageMode>(args.smi_at(index));
1731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
1741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
175236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgstatic Handle<Map> ComputeObjectLiteralMap(
176236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    Handle<Context> context,
177236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    Handle<FixedArray> constant_properties,
1785a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    bool* is_result_from_cache) {
179ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = context->GetIsolate();
180ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  int properties_length = constant_properties->length();
181ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  int number_of_properties = properties_length / 2;
1824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Check that there are only internal strings and array indices among keys.
1834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int number_of_string_keys = 0;
18478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  for (int p = 0; p != properties_length; p += 2) {
18578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    Object* key = constant_properties->get(p);
18678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    uint32_t element_index = 0;
1874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (key->IsInternalizedString()) {
1884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      number_of_string_keys++;
18978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    } else if (key->ToArrayIndex(&element_index)) {
19078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // An index key does not require space in the property backing store.
19178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      number_of_properties--;
19278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    } else {
1934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // Bail out as a non-internalized-string non-index key makes caching
1944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // impossible.
19578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // ASSERT to make sure that the if condition after the loop is false.
1964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      ASSERT(number_of_string_keys != number_of_properties);
19778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      break;
198236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
19978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
2004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // If we only have internalized strings and array indices among keys then we
2014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // can use the map cache in the native context.
20278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  const int kMaxKeys = 10;
2034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if ((number_of_string_keys == number_of_properties) &&
2044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      (number_of_string_keys < kMaxKeys)) {
20578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // Create the fixed array with the key.
20678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    Handle<FixedArray> keys =
2074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        isolate->factory()->NewFixedArray(number_of_string_keys);
2084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (number_of_string_keys > 0) {
20978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      int index = 0;
21078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      for (int p = 0; p < properties_length; p += 2) {
21178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        Object* key = constant_properties->get(p);
2124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        if (key->IsInternalizedString()) {
21378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          keys->set(index++, key);
214ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org        }
215236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      }
2164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      ASSERT(index == number_of_string_keys);
217236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
21878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    *is_result_from_cache = true;
21978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
220236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
2215a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  *is_result_from_cache = false;
222ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->factory()->CopyMap(
2233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      Handle<Map>(context->object_function()->initial_map()),
2243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      number_of_properties);
225236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
226236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
227236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
228bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic Handle<Object> CreateLiteralBoilerplate(
229ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
230bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
231bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> constant_properties);
23241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
233bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
234bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic Handle<Object> CreateObjectLiteralBoilerplate(
235ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
236bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
237f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    Handle<FixedArray> constant_properties,
238ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    bool should_have_fast_elements,
239ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    bool has_function_literal) {
24046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Get the native context from the literals array.  This is the
24141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // context in which the function was created and we use the object
24241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // function from this context to create the object literal.  We do
24346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // not use the object function from the current native context
24441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // because this might be the object function from another context
24541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // which we should not have access to.
246236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  Handle<Context> context =
24746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
248236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
249ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // In case we have function literals, we want the object to be in
250ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // slow properties mode for now. We don't go in the map cache because
251ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // maps with constant functions can't be shared if the functions are
252ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // not the same (which is the common case).
253ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool is_result_from_cache = false;
254ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Map> map = has_function_literal
255ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ? Handle<Map>(context->object_function()->initial_map())
256ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : ComputeObjectLiteralMap(context,
257ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                constant_properties,
258ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                &is_result_from_cache);
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSObject> boilerplate =
26157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      isolate->factory()->NewJSObjectFromMap(
26257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          map, isolate->heap()->GetPretenureMode());
263f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
264f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  // Normalize the elements of the boilerplate to save space if needed.
265f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
266f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
267ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Add the constant properties to the boilerplate.
268ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int length = constant_properties->length();
269ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool should_transform =
270ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      !is_result_from_cache && boilerplate->HasFastProperties();
271ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (should_transform || has_function_literal) {
272ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // Normalize the properties of object to avoid n^2 behavior
273ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // when extending the object multiple properties. Indicate the number of
274ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // properties to be added.
275f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::NormalizeProperties(
276f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
277ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
278ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
279f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // TODO(verwaest): Support tracking representations in the boilerplate.
280ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  for (int index = 0; index < length; index +=2) {
281ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> key(constant_properties->get(index+0), isolate);
282ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> value(constant_properties->get(index+1), isolate);
283ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (value->IsFixedArray()) {
284ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // The value contains the constant_properties of a
285ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // simple object or array literal.
286ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<FixedArray> array = Handle<FixedArray>::cast(value);
287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      value = CreateLiteralBoilerplate(isolate, literals, array);
288ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (value.is_null()) return value;
289ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
290ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> result;
291ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    uint32_t element_index = 0;
292fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    JSReceiver::StoreMode mode = value->IsJSObject()
293fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        ? JSReceiver::FORCE_FIELD
294fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        : JSReceiver::ALLOW_AS_CONSTANT;
2954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (key->IsInternalizedString()) {
296ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
297ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        // Array index as string (uint32).
298f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        result = JSObject::SetOwnElement(
299f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com            boilerplate, element_index, value, kNonStrictMode);
30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
301ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        Handle<String> name(String::cast(*key));
302ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        ASSERT(!name->AsArrayIndex(&element_index));
303f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        result = JSObject::SetLocalPropertyIgnoreAttributes(
304fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            boilerplate, name, value, NONE,
305fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            Object::OPTIMAL_REPRESENTATION, mode);
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    } else if (key->ToArrayIndex(&element_index)) {
308ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // Array index (uint32).
309f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      result = JSObject::SetOwnElement(
310f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          boilerplate, element_index, value, kNonStrictMode);
311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    } else {
312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // Non-uint32 number.
313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ASSERT(key->IsNumber());
314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      double num = key->Number();
315ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      char arr[100];
316ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Vector<char> buffer(arr, ARRAY_SIZE(arr));
317ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      const char* str = DoubleToCString(num, buffer);
318ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<String> name =
319ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector(str));
320f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      result = JSObject::SetLocalPropertyIgnoreAttributes(
321fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org          boilerplate, name, value, NONE,
322fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org          Object::OPTIMAL_REPRESENTATION, mode);
323ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
324ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // If setting the property on the boilerplate throws an
325ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // exception, the exception is converted to an empty handle in
326ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // the handle based operations.  In that case, we need to
327ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // convert back to an exception.
328ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (result.is_null()) return result;
329ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
330ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
331ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Transform to fast properties if necessary. For object literals with
332ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // containing function literals we defer this operation until after all
333ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // computed properties have been assigned so that we can generate
334ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // constant function properties.
335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (should_transform && !has_function_literal) {
336f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::TransformToFastProperties(
337f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        boilerplate, boilerplate->map()->unused_property_fields());
3387be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  }
3397be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
340bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return boilerplate;
341bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
342bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
343bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
344fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgMaybeObject* TransitionElements(Handle<Object> object,
345fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                                ElementsKind to_kind,
346fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                                Isolate* isolate) {
347fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  HandleScope scope(isolate);
348fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
349fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  ElementsKind from_kind =
350fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      Handle<JSObject>::cast(object)->map()->elements_kind();
351fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (Map::IsValidElementsTransition(from_kind, to_kind)) {
352fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    Handle<Object> result = JSObject::TransitionElementsKind(
353fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org        Handle<JSObject>::cast(object), to_kind);
354fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    if (result.is_null()) return isolate->ThrowIllegalOperation();
355fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    return *result;
356fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
357fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  return isolate->ThrowIllegalOperation();
358fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
359fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
360fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
361830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgstatic const int kSmiLiteralMinimumLength = 1024;
362a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
363a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
3647ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.orgHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
365ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
366bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
367bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> elements) {
368bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Create the JSArray.
369bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<JSFunction> constructor(
37046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      JSFunction::NativeContextFromLiterals(*literals)->array_function());
37157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
37257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSArray> object = Handle<JSArray>::cast(
37357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      isolate->factory()->NewJSObject(
37457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          constructor, isolate->heap()->GetPretenureMode()));
375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ElementsKind constant_elements_kind =
377394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
378394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArrayBase> constant_elements_values(
379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      FixedArrayBase::cast(elements->get(1)));
380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
381830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(IsFastElementsKind(constant_elements_kind));
38246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* native_context = isolate->context()->native_context();
38346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Object* maybe_maps_array = native_context->js_array_maps();
384830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(!maybe_maps_array->IsUndefined());
385830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  Object* maybe_map = FixedArray::cast(maybe_maps_array)->get(
386830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      constant_elements_kind);
387830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(maybe_map->IsMap());
388830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  object->set_map(Map::cast(maybe_map));
389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArrayBase> copied_elements_values;
391830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsFastDoubleElementsKind(constant_elements_kind)) {
392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ASSERT(FLAG_smi_only_arrays);
393394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
394394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Handle<FixedDoubleArray>::cast(constant_elements_values));
395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
396830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    const bool is_cow =
398394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        (constant_elements_values->map() ==
399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com         isolate->heap()->fixed_cow_array_map());
400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (is_cow) {
401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      copied_elements_values = constant_elements_values;
402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#if DEBUG
403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> fixed_array_values =
404394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<FixedArray>::cast(copied_elements_values);
405394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      for (int i = 0; i < fixed_array_values->length(); i++) {
406394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ASSERT(!fixed_array_values->get(i)->IsFixedArray());
407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
408a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org#endif
409394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
410394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> fixed_array_values =
411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<FixedArray>::cast(constant_elements_values);
412394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> fixed_array_values_copy =
413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          isolate->factory()->CopyFixedArray(fixed_array_values);
414394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      copied_elements_values = fixed_array_values_copy;
415394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      for (int i = 0; i < fixed_array_values->length(); i++) {
416394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Object* current = fixed_array_values->get(i);
417394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (current->IsFixedArray()) {
418394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          // The value contains the constant_properties of a
419394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          // simple object or array literal.
420394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
421394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<Object> result =
422394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              CreateLiteralBoilerplate(isolate, literals, fa);
423394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          if (result.is_null()) return result;
424394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          fixed_array_values_copy->set(i, *result);
425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
4260b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org      }
427bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
428bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
429394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  object->set_elements(*copied_elements_values);
430394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  object->set_length(Smi::FromInt(copied_elements_values->length()));
431fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
432830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
433fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  //  on or the object is larger than the threshold.
434fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!FLAG_smi_only_arrays &&
435830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      constant_elements_values->length() < kSmiLiteralMinimumLength) {
436830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind elements_kind = object->GetElementsKind();
437830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (!IsFastObjectElementsKind(elements_kind)) {
438830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      if (IsFastHoleyElementsKind(elements_kind)) {
439830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        CHECK(!TransitionElements(object, FAST_HOLEY_ELEMENTS,
440830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                                  isolate)->IsFailure());
441830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      } else {
442830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
443830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      }
444fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    }
445fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
446fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
447830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  object->ValidateElements();
448bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return object;
449bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
450bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
451bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
452bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic Handle<Object> CreateLiteralBoilerplate(
453ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
454bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
455bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> array) {
456bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
457ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  const bool kHasNoFunctionLiteral = false;
458dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  switch (CompileTimeValue::GetLiteralType(array)) {
459f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
460ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return CreateObjectLiteralBoilerplate(isolate,
461ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            literals,
462ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            elements,
463ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            true,
464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            kHasNoFunctionLiteral);
465f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
466ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return CreateObjectLiteralBoilerplate(isolate,
467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            literals,
468ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            elements,
469ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            false,
470ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            kHasNoFunctionLiteral);
471bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    case CompileTimeValue::ARRAY_LITERAL:
4727ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      return Runtime::CreateArrayLiteralBoilerplate(
4737ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          isolate, literals, elements);
474bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    default:
475bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      UNREACHABLE();
476bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return Handle<Object>::null();
477bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
478bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
479bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
480bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
481c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
482ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
483f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  ASSERT(args.length() == 4);
484f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
4856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
486f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
4876d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 3);
488ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
49013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
49113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Check if boilerplate exists. If not, create it first.
492ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> boilerplate(literals->get(literals_index), isolate);
493ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (*boilerplate == isolate->heap()->undefined_value()) {
494ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    boilerplate = CreateObjectLiteralBoilerplate(isolate,
495ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 literals,
496f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org                                                 constant_properties,
497ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 should_have_fast_elements,
498ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 has_function_literal);
499e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
50013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    // Update the functions literal and return the boilerplate.
50113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    literals->set(literals_index, *boilerplate);
50213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
503f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return JSObject::cast(*boilerplate)->DeepCopy(isolate);
50413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
50513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
50613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
507c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
508ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
509f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  ASSERT(args.length() == 4);
510f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
5116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
512f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
5136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 3);
514ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
515ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
51613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
51713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Check if boilerplate exists. If not, create it first.
518ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> boilerplate(literals->get(literals_index), isolate);
519ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (*boilerplate == isolate->heap()->undefined_value()) {
520ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    boilerplate = CreateObjectLiteralBoilerplate(isolate,
521ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 literals,
522f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org                                                 constant_properties,
523ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 should_have_fast_elements,
524ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 has_function_literal);
525e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
52613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    // Update the functions literal and return the boilerplate.
52713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    literals->set(literals_index, *boilerplate);
52813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
529ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
53013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
53113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
53213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
533bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgstatic Handle<AllocationSite> GetLiteralAllocationSite(
534bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Isolate* isolate,
535bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<FixedArray> literals,
536bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    int literals_index,
537bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<FixedArray> elements) {
538bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Check if boilerplate exists. If not, create it first.
539bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<Object> literal_site(literals->get(literals_index), isolate);
540bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<AllocationSite> site;
541bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (*literal_site == isolate->heap()->undefined_value()) {
542bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ASSERT(*elements != isolate->heap()->empty_fixed_array());
543bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<Object> boilerplate =
544bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
545bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    if (boilerplate.is_null()) return site;
546bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    site = isolate->factory()->NewAllocationSite();
547bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    site->set_transition_info(*boilerplate);
548bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    literals->set(literals_index, *site);
549bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else {
550bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    site = Handle<AllocationSite>::cast(literal_site);
551bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
552bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
553bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return site;
554bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
555bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
556bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
557c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
558ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
55913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  ASSERT(args.length() == 3);
560f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
5616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
562f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
56313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
564bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
565bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      literals_index, elements);
566bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, site);
567bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
568bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  JSObject* boilerplate = JSObject::cast(site->transition_info());
569bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return boilerplate->DeepCopy(isolate);
57013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
57113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
57213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
573c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
574ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
57513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  ASSERT(args.length() == 3);
576f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
5776d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
578f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
57913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
580bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
581bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      literals_index, elements);
582bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, site);
583bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
584bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  JSObject* boilerplate = JSObject::cast(site->transition_info());
585bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (boilerplate->elements()->map() ==
586ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->heap()->fixed_cow_array_map()) {
5877979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    isolate->counters()->cow_arrays_created_runtime()->Increment();
5880b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  }
58946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
590bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  AllocationSiteMode mode = AllocationSite::GetMode(
591bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      boilerplate->GetElementsKind());
5924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
593bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    return isolate->heap()->CopyJSObjectWithAllocationSite(
594bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        boilerplate, *site);
5954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
5964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
597bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return isolate->heap()->CopyJSObject(boilerplate);
5984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
5994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
6004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
6014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
602f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
603f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
604f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Handle<Object> name(args[0], isolate);
605f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
606f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Symbol* symbol;
607f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  MaybeObject* maybe = isolate->heap()->AllocateSymbol();
608f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (!maybe->To(&symbol)) return maybe;
609f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (name->IsString()) symbol->set_name(*name);
610f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return symbol;
611f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
612f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
613f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
614f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) {
61579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
616f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
617f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
618f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return symbol->name();
61913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
62013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
62113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
6227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
62379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  ASSERT(args.length() == 2);
625de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
6267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Object* prototype = args[1];
6277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Object* used_prototype =
628d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
6297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  return isolate->heap()->AllocateJSProxy(handler, used_prototype);
6307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
6317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
6327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
63334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) {
63479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
63534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 4);
636de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
63734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* call_trap = args[1];
638de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
639de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSFunction, construct_trap, 2);
64034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* prototype = args[3];
64134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* used_prototype =
64234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
64334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return isolate->heap()->AllocateJSFunctionProxy(
64434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      handler, call_trap, construct_trap, used_prototype);
64534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
64634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
64734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
648d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
64979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
650d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ASSERT(args.length() == 1);
651d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  Object* obj = args[0];
6527c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSProxy());
653d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
654d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
655d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
65634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) {
65779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
65834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 1);
65934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* obj = args[0];
66034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
66134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
66234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
66334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
664d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
66579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
666d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ASSERT(args.length() == 1);
667f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
668d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  return proxy->handler();
669d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
670d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
671d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
67234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
67379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
67434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 1);
675f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
67634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return proxy->call_trap();
67734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
67834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
67934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
68034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
68179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
68234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 1);
683f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
68434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return proxy->construct_trap();
68534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
68634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
68734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
688717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
68979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
690717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  ASSERT(args.length() == 1);
691f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
692717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  proxy->Fix();
6939fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org  return isolate->heap()->undefined_value();
694717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
695717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
696717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
6971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Runtime::FreeArrayBuffer(Isolate* isolate,
6981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                              JSArrayBuffer* phantom_array_buffer) {
6991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (phantom_array_buffer->is_external()) return;
700f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
7011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t allocated_length = NumberToSize(
7021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      isolate, phantom_array_buffer->byte_length());
7031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
7041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
7051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      -static_cast<intptr_t>(allocated_length));
7061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CHECK(V8::ArrayBufferAllocator() != NULL);
707307dd6ea3b729c8058ada645b42a1cf083c92128danno@chromium.org  V8::ArrayBufferAllocator()->Free(
708307dd6ea3b729c8058ada645b42a1cf083c92128danno@chromium.org      phantom_array_buffer->backing_store(),
709307dd6ea3b729c8058ada645b42a1cf083c92128danno@chromium.org      allocated_length);
710f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
711f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
712f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
713a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid Runtime::SetupArrayBuffer(Isolate* isolate,
714ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                               Handle<JSArrayBuffer> array_buffer,
715a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                               bool is_external,
716ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                               void* data,
717ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                               size_t allocated_length) {
718a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(array_buffer->GetInternalFieldCount() ==
719a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      v8::ArrayBuffer::kInternalFieldCount);
720a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
721a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    array_buffer->SetInternalField(i, Smi::FromInt(0));
722a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
723ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  array_buffer->set_backing_store(data);
724a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  array_buffer->set_flag(Smi::FromInt(0));
725a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  array_buffer->set_is_external(is_external);
726ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
727ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Handle<Object> byte_length =
7284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      isolate->factory()->NewNumberFromSize(allocated_length);
729ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
730ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  array_buffer->set_byte_length(*byte_length);
7311fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
7321fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
7331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  isolate->heap()->set_array_buffers_list(*array_buffer);
7341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
735ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
736ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
737ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
738ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgbool Runtime::SetupArrayBufferAllocatingData(
739ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Isolate* isolate,
740ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Handle<JSArrayBuffer> array_buffer,
741d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    size_t allocated_length,
742d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    bool initialize) {
743ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void* data;
744837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  CHECK(V8::ArrayBufferAllocator() != NULL);
745ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (allocated_length != 0) {
746d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (initialize) {
747d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
748d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    } else {
749d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      data =
750d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
751d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
752ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (data == NULL) return false;
753ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
754ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    data = NULL;
755ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
756ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
757a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
758ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
759ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
760ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
761ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return true;
762ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
763ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
764ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
765f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
766f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
767f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 2);
768f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
769f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
770f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  size_t allocated_length;
771f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (byteLength->IsSmi()) {
772f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    allocated_length = Smi::cast(*byteLength)->value();
773f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
774f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    ASSERT(byteLength->IsHeapNumber());
775f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    double value = HeapNumber::cast(*byteLength)->value();
776f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
777f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    ASSERT(value >= 0);
778f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
779f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    if (value > std::numeric_limits<size_t>::max()) {
780f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      return isolate->Throw(
781f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          *isolate->factory()->NewRangeError("invalid_array_buffer_length",
782f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            HandleVector<Object>(NULL, 0)));
783f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
784f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
785f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    allocated_length = static_cast<size_t>(value);
786f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
787f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
788ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (!Runtime::SetupArrayBufferAllocatingData(isolate,
789ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                                               holder, allocated_length)) {
790f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      return isolate->Throw(*isolate->factory()->
791f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          NewRangeError("invalid_array_buffer_length",
792f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            HandleVector<Object>(NULL, 0)));
793f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
794f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
795f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return *holder;
796f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
797f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
798f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
799f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
80079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
801f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
802f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
803f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return holder->byte_length();
804f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
805f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
806f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
807f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
808f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
809f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 3);
810f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
811f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
812f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(first, 2);
813f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  size_t start = static_cast<size_t>(first);
814e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  size_t target_length = NumberToSize(isolate, target->byte_length());
815f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
816b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (target_length == 0) return isolate->heap()->undefined_value();
817f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
818e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start);
819f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
820f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
821f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CopyBytes(target_data, source_data + start, target_length);
822f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return isolate->heap()->undefined_value();
823f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
824f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
825f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
826e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgenum TypedArrayId {
827e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // arrayIds below should be synchromized with typedarray.js natives.
828e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_UINT8 = 1,
829e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_INT8 = 2,
830e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_UINT16 = 3,
831e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_INT16 = 4,
832e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_UINT32 = 5,
833e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_INT32 = 6,
834e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ARRAY_ID_FLOAT32 = 7,
83557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ARRAY_ID_FLOAT64 = 8,
83657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ARRAY_ID_UINT8C = 9
837e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org};
838e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
839d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgstatic void ArrayIdToTypeAndSize(
840d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    int arrayId, ExternalArrayType* array_type, size_t* element_size) {
841e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  switch (arrayId) {
842e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_UINT8:
843d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalUnsignedByteArray;
844d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 1;
845e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
846e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_INT8:
847d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalByteArray;
848d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 1;
849e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
850e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_UINT16:
851d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalUnsignedShortArray;
852d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 2;
853e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
854e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_INT16:
855d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalShortArray;
856d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 2;
857e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
858e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_UINT32:
859d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalUnsignedIntArray;
860d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 4;
861e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_INT32:
863d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalIntArray;
864d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 4;
865e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
866e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_FLOAT32:
867d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalFloatArray;
868d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 4;
869e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
870e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case ARRAY_ID_FLOAT64:
871d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalDoubleArray;
872d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 8;
873e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
87457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    case ARRAY_ID_UINT8C:
875d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *array_type = kExternalPixelArray;
876d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      *element_size = 1;
87757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      break;
878e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    default:
879e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      UNREACHABLE();
880e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
881d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
882d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
883d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
884d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
885d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HandleScope scope(isolate);
886d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(args.length() == 5);
887d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
888d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
889d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2);
890d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
891d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
892d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
893d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(holder->GetInternalFieldCount() ==
894d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      v8::ArrayBufferView::kInternalFieldCount);
895d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
896d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    holder->SetInternalField(i, Smi::FromInt(0));
897d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
898d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
899d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
900d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t element_size = 1;  // Bogus initialization.
901d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
902e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
903e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  holder->set_buffer(*buffer);
904e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  holder->set_byte_offset(*byte_offset_object);
905e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  holder->set_byte_length(*byte_length_object);
906e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
907e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
908e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  size_t byte_length = NumberToSize(isolate, *byte_length_object);
909d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(byte_length % element_size == 0);
910d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t length = byte_length / element_size;
911e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
9124e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
913e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  holder->set_length(*length_obj);
9141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_weak_next(buffer->weak_first_view());
9151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer->set_weak_first_view(*holder);
9164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
917e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Handle<ExternalArray> elements =
918e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      isolate->factory()->NewExternalArray(
919d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          static_cast<int>(length), array_type,
920e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
921e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  holder->set_elements(*elements);
922e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return isolate->heap()->undefined_value();
923e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
926d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Initializes a typed array from an array-like object.
927d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// If an array-like object happens to be a typed array of the same type,
928d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// initializes backing store using memove.
929d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org//
930d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Returns true if backing store was initialized or false otherwise.
931d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
932d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HandleScope scope(isolate);
933d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(args.length() == 4);
934d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
935d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
936d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
937d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3);
938d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
939d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(holder->GetInternalFieldCount() ==
940d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      v8::ArrayBufferView::kInternalFieldCount);
941d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
942d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    holder->SetInternalField(i, Smi::FromInt(0));
943d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
944d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
945d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
946d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t element_size = 1;  // Bogus initialization.
947d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
948d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
949d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
950d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t length = NumberToSize(isolate, *length_obj);
9515d91fcbf5af3a22a952906704953f3e48ee5cabedanno@chromium.org  if (length > (kMaxInt / element_size)) {
952d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return isolate->Throw(*isolate->factory()->
953d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          NewRangeError("invalid_array_buffer_length",
954d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            HandleVector<Object>(NULL, 0)));
955d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
9565d91fcbf5af3a22a952906704953f3e48ee5cabedanno@chromium.org  size_t byte_length = length * element_size;
957d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
958d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // We assume that the caller of this function will initialize holder
959d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // with the loop
960d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
961d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // If source is a typed array, this loop will always run to completion,
962d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // so we are sure that the backing store will be initialized.
963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Otherwise, we do not know (the indexing operation might throw).
964d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Hence we require zero initialization unless our source is a typed array.
965d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  bool should_zero_initialize = !source->IsJSTypedArray();
966d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
967d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (!Runtime::SetupArrayBufferAllocatingData(
968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        isolate, buffer, byte_length, should_zero_initialize)) {
969d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return isolate->Throw(*isolate->factory()->
970d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          NewRangeError("invalid_array_buffer_length",
971d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            HandleVector<Object>(NULL, 0)));
972d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
973d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
974d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_buffer(*buffer);
975d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_byte_offset(Smi::FromInt(0));
976d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Handle<Object> byte_length_obj(
977d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      isolate->factory()->NewNumberFromSize(byte_length));
978d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_byte_length(*byte_length_obj);
979d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_length(*length_obj);
980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_weak_next(buffer->weak_first_view());
981d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  buffer->set_weak_first_view(*holder);
982d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
983d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Handle<ExternalArray> elements =
984d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      isolate->factory()->NewExternalArray(
985d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          static_cast<int>(length), array_type,
986d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          static_cast<uint8_t*>(buffer->backing_store()));
987d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_elements(*elements);
988d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
989d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (source->IsJSTypedArray()) {
990d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
991d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
992d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (typed_array->type() == holder->type()) {
993d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      uint8_t* backing_store =
994d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        static_cast<uint8_t*>(
995d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          JSArrayBuffer::cast(typed_array->buffer())->backing_store());
996d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      size_t source_byte_offset =
997d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          NumberToSize(isolate, typed_array->byte_offset());
998d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      OS::MemCopy(
999d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          buffer->backing_store(),
1000d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          backing_store + source_byte_offset,
1001d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          byte_length);
1002d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      return *isolate->factory()->true_value();
1003d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    } else {
1004d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      return *isolate->factory()->false_value();
1005d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
1006d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1007d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1008d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  return *isolate->factory()->false_value();
1009d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1010d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1011d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1012e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define TYPED_ARRAY_GETTER(getter, accessor) \
101357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) {             \
101457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    HandleScope scope(isolate);                                               \
101557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(args.length() == 1);                                               \
101657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);                            \
101757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (!holder->IsJSTypedArray())                                            \
101857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      return isolate->Throw(*isolate->factory()->NewTypeError(                \
101957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          "not_typed_array", HandleVector<Object>(NULL, 0)));                 \
102057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));            \
102157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return typed_array->accessor();                                           \
1022e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1023e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1024e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgTYPED_ARRAY_GETTER(Buffer, buffer)
1025e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgTYPED_ARRAY_GETTER(ByteLength, byte_length)
1026e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgTYPED_ARRAY_GETTER(ByteOffset, byte_offset)
1027e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgTYPED_ARRAY_GETTER(Length, length)
1028e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1029e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#undef TYPED_ARRAY_GETTER
1030e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1031d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Return codes for Runtime_TypedArraySetFastCases.
1032d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Should be synchronized with typedarray.js natives.
1033d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgenum TypedArraySetResultCodes {
1034d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from typed array of the same type.
1035d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // This is processed by TypedArraySetFastCases
1036d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
1037d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from typed array of the different type, overlapping in memory.
1038d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
1039d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from typed array of the different type, non-overlapping.
1040d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
1041d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from non-typed array.
1042d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
1043d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org};
1044d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1045d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
104657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
104757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  HandleScope scope(isolate);
104857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
104957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
105057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
105157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
105257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (!target_obj->IsJSTypedArray())
105357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return isolate->Throw(*isolate->factory()->NewTypeError(
105457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        "not_typed_array", HandleVector<Object>(NULL, 0)));
105557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
105657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (!source_obj->IsJSTypedArray())
1057d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
105857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
105957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
106057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
106157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t offset = NumberToSize(isolate, *offset_obj);
106257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t target_length = NumberToSize(isolate, target->length());
106357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t source_length = NumberToSize(isolate, source->length());
106457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t target_byte_length = NumberToSize(isolate, target->byte_length());
106557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
106657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (offset > target_length ||
106757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      offset + source_length > target_length ||
106857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      offset + source_length < offset)  // overflow
106957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return isolate->Throw(*isolate->factory()->NewRangeError(
107057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
107157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
107257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t target_offset = NumberToSize(isolate, target->byte_offset());
107357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t source_offset = NumberToSize(isolate, source->byte_offset());
107457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  uint8_t* target_base =
1075d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      static_cast<uint8_t*>(
1076d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        JSArrayBuffer::cast(target->buffer())->backing_store()) + target_offset;
107757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  uint8_t* source_base =
1078d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      static_cast<uint8_t*>(
1079d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        JSArrayBuffer::cast(source->buffer())->backing_store()) + source_offset;
108057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
108157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  // Typed arrays of the same type: use memmove.
108257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (target->type() == source->type()) {
108357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    memmove(target_base + offset * target->element_size(),
108457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        source_base, source_byte_length);
1085d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
108657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
108757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
108857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  // Typed arrays of different types over the same backing store
108957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if ((source_base <= target_base &&
109057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        source_base + source_byte_length > target_base) ||
109157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      (target_base <= source_base &&
109257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        target_base + target_byte_length > source_base)) {
1093d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // We do not support overlapping ArrayBuffers
1094d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(
1095d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      JSArrayBuffer::cast(target->buffer())->backing_store() ==
1096d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      JSArrayBuffer::cast(source->buffer())->backing_store());
1097d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
109857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  } else {  // Non-overlapping typed arrays
1099d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
110057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
110157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
110257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
110357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
11041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
11051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
11061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 4);
11071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
11081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
11091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2);
11101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3);
11111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1112e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  ASSERT(holder->GetInternalFieldCount() ==
1113e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      v8::ArrayBufferView::kInternalFieldCount);
1114e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1115e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    holder->SetInternalField(i, Smi::FromInt(0));
1116e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
1117e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
11181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_buffer(*buffer);
11191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(byte_offset->IsNumber());
11201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(
11211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, buffer->byte_length()) >=
11221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        NumberToSize(isolate, *byte_offset)
11231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        + NumberToSize(isolate, *byte_length));
11241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_byte_offset(*byte_offset);
11251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(byte_length->IsNumber());
11261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_byte_length(*byte_length);
11271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_weak_next(buffer->weak_first_view());
11291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer->set_weak_first_view(*holder);
11301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return isolate->heap()->undefined_value();
11321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
11361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
11371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 1);
11381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
11391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return data_view->buffer();
11401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
11441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
11451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 1);
11461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
11471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return data_view->byte_offset();
11481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
11521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
11531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 1);
11541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
11551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return data_view->byte_length();
11561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline static bool NeedToFlipBytes(bool is_little_endian) {
11601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#ifdef V8_TARGET_LITTLE_ENDIAN
11611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return !is_little_endian;
11621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#else
11631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return is_little_endian;
11641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#endif
11651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<int n>
11691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline void CopyBytes(uint8_t* target, uint8_t* source) {
11701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (int i = 0; i < n; i++) {
11711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    *(target++) = *(source++);
11721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
11731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<int n>
11771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline void FlipBytes(uint8_t* target, uint8_t* source) {
11781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  source = source + (n-1);
11791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (int i = 0; i < n; i++) {
11801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    *(target++) = *(source--);
11811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
11821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
11831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<typename T>
11861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline static bool DataViewGetValue(
11871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Isolate* isolate,
11881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<JSDataView> data_view,
11891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Object> byte_offset_obj,
11901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    bool is_little_endian,
11911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T* result) {
11921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
11931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
11941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_offset =
11961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_offset());
11971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_length =
11981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_length());
11991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (byte_offset + sizeof(T) > data_view_byte_length ||
12001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      byte_offset + sizeof(T) < byte_offset)  {  // overflow
12011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return false;
12021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  union Value {
12051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T data;
12061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    uint8_t bytes[sizeof(T)];
12071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  };
12081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Value value;
12101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t buffer_offset = data_view_byte_offset + byte_offset;
12111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(
12121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, buffer->byte_length())
12131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      >= buffer_offset + sizeof(T));
12141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  uint8_t* source =
12151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
12161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (NeedToFlipBytes(is_little_endian)) {
12171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    FlipBytes<sizeof(T)>(value.bytes, source);
12181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else {
12191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CopyBytes<sizeof(T)>(value.bytes, source);
12201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  *result = value.data;
12221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return true;
12231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
12241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<typename T>
12271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic bool DataViewSetValue(
12281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Isolate* isolate,
12291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<JSDataView> data_view,
12301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Object> byte_offset_obj,
12311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    bool is_little_endian,
12321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T data) {
12331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
12341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
12351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_offset =
12371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_offset());
12381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_length =
12391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_length());
12401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (byte_offset + sizeof(T) > data_view_byte_length ||
12411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      byte_offset + sizeof(T) < byte_offset)  {  // overflow
12421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return false;
12431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  union Value {
12461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T data;
12471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    uint8_t bytes[sizeof(T)];
12481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  };
12491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Value value;
12511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  value.data = data;
12521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t buffer_offset = data_view_byte_offset + byte_offset;
12531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(
12541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, buffer->byte_length())
12551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      >= buffer_offset + sizeof(T));
12561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  uint8_t* target =
12571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
12581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (NeedToFlipBytes(is_little_endian)) {
12591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    FlipBytes<sizeof(T)>(target, value.bytes);
12601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else {
12611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CopyBytes<sizeof(T)>(target, value.bytes);
12621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return true;
12641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
12651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
12681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) {             \
12691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HandleScope scope(isolate);                                               \
12701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ASSERT(args.length() == 3);                                               \
12711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
12721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
12731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
12741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Type result;                                                              \
12751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (DataViewGetValue(                                                     \
12761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          isolate, holder, offset, is_little_endian, &result)) {              \
12771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->heap()->Converter(result);                              \
12781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else {                                                                  \
12791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->Throw(*isolate->factory()->NewRangeError(               \
12801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          "invalid_data_view_accessor_offset",                                \
12811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          HandleVector<Object>(NULL, 0)));                                    \
12821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }                                                                         \
12831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32)
12861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32)
12871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32)
12881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32)
12891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32)
12901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32)
12911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Float32, float, NumberFromDouble)
12921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_GETTER(Float64, double, NumberFromDouble)
12931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#undef DATA_VIEW_GETTER
12951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
129610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
129710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <typename T>
129810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgstatic T DataViewConvertValue(double value);
129910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
130010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
130110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
130210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgint8_t DataViewConvertValue<int8_t>(double value) {
130310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<int8_t>(DoubleToInt32(value));
130410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
130510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
130610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
130710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
130810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgint16_t DataViewConvertValue<int16_t>(double value) {
130910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<int16_t>(DoubleToInt32(value));
131010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
131110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
131210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
131310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
131410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgint32_t DataViewConvertValue<int32_t>(double value) {
131510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return DoubleToInt32(value);
131610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
131710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
131810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
131910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
132010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orguint8_t DataViewConvertValue<uint8_t>(double value) {
132110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<uint8_t>(DoubleToUint32(value));
132210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
132310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
132410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
132510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
132610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orguint16_t DataViewConvertValue<uint16_t>(double value) {
132710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<uint16_t>(DoubleToUint32(value));
132810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
132910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
133010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
133110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
133210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orguint32_t DataViewConvertValue<uint32_t>(double value) {
133310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return DoubleToUint32(value);
133410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
133510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
133610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
133710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
133810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgfloat DataViewConvertValue<float>(double value) {
133910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<float>(value);
134010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
134110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
134210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
134310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
134410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgdouble DataViewConvertValue<double>(double value) {
134510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return value;
134610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
134710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
134810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
13491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#define DATA_VIEW_SETTER(TypeName, Type)                                      \
13501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) {             \
13511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HandleScope scope(isolate);                                               \
13521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ASSERT(args.length() == 4);                                               \
13531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
13541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
13551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);                             \
13561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
135710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Type v = DataViewConvertValue<Type>(value->Number());                     \
13581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (DataViewSetValue(                                                     \
13591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          isolate, holder, offset, is_little_endian, v)) {                    \
13601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->heap()->undefined_value();                              \
13611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else {                                                                  \
13621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->Throw(*isolate->factory()->NewRangeError(               \
13631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          "invalid_data_view_accessor_offset",                                \
13641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          HandleVector<Object>(NULL, 0)));                                    \
13651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }                                                                         \
13661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Uint8, uint8_t)
13691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Int8, int8_t)
13701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Uint16, uint16_t)
13711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Int16, int16_t)
13721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Uint32, uint32_t)
13731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Int32, int32_t)
13741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Float32, float)
13751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Float64, double)
13761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#undef DATA_VIEW_SETTER
13781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
1381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
1383f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1384394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
1385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
1386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *holder;
1387394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
1391394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1393f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
139409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> key(args[1], isolate);
1395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1396394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  table = ObjectHashSetAdd(table, key);
1397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
13985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
1399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1402394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
1403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1404394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1405f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
140609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> key(args[1], isolate);
1407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1408394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return isolate->heap()->ToBoolean(table->Contains(*key));
1409394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1410394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1412394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
1413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1414394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1415f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
141609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> key(args[1], isolate);
1417394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1418394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  table = ObjectHashSetRemove(table, key);
1419394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
14205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
1421394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1422394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1423394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1424e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
1425e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  HandleScope scope(isolate);
1426e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 1);
1427e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1428e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1429e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return Smi::FromInt(table->NumberOfElements());
1430e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1431e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1432e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1433394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
1434394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1435394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
1436f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1437394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
1438394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
1439394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *holder;
1440394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1441394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1442394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1443394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
1444394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1445394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1446f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
14477a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
14487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
144909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> lookup(table->Lookup(*key), isolate);
14507a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
14517a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
14527a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
14537a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
14547a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
14557a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
14567a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
14577a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
14587a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
14597a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
146009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> lookup(table->Lookup(*key), isolate);
14617a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
14627a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
14637a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
14647a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
14657a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
14667a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
14677a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
14687a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
14697a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
14707a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
147109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> lookup(table->Lookup(*key), isolate);
14727a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  Handle<ObjectHashTable> new_table =
14737a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org      PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
14747a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  holder->set_table(*new_table);
14757a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1476394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1477394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1478394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1479394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
1480394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 3);
1482f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
14837a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
14847a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1486394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
1487394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*new_table);
14885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
1489394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1490394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1491394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1492e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
1493e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  HandleScope scope(isolate);
1494e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 1);
1495e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1496e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1497e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return Smi::FromInt(table->NumberOfElements());
1498e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1499e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1500e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1501ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic JSWeakCollection* WeakCollectionInitialize(Isolate* isolate,
1502ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSWeakCollection> weak_collection) {
1503ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(weak_collection->map()->inobject_properties() == 0);
15047c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
1505ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_table(*table);
1506ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_next(Smi::FromInt(0));
1507ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *weak_collection;
15087c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
15097c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
15107c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1511ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionInitialize) {
15122f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  HandleScope scope(isolate);
15132f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  ASSERT(args.length() == 1);
1514ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1515ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return WeakCollectionInitialize(isolate, weak_collection);
15162f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org}
15172f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org
15182f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org
1519ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionGet) {
15207a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
15217a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
1522ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1523750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1524ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(
1525ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ObjectHashTable::cast(weak_collection->table()));
152609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> lookup(table->Lookup(*key), isolate);
15277a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
15287a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
15297a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
15307a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1531ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionHas) {
15327a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
15337c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 2);
1534ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1535750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1536ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(
1537ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ObjectHashTable::cast(weak_collection->table()));
153809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> lookup(table->Lookup(*key), isolate);
15397a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
15407a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
15417a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
15427a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1543ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
15447a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
15457a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
1546ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1547750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1548ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(ObjectHashTable::cast(
1549ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      weak_collection->table()));
155009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> lookup(table->Lookup(*key), isolate);
15517a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  Handle<ObjectHashTable> new_table =
15527a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org      PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
1553ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_table(*new_table);
15547a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
15557c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
15567c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
15577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1558ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
15597c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  HandleScope scope(isolate);
15607c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 3);
1561ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1562750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
156309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> value(args[2], isolate);
1564ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(
1565ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ObjectHashTable::cast(weak_collection->table()));
15667c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
1567ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_table(*new_table);
15685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
15697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
15707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
15717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1572c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
157379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
157443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
157543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* obj = args[0];
1576ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!obj->IsJSObject()) return isolate->heap()->null_value();
157743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return JSObject::cast(obj)->class_name();
157843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
157943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15805a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
1581d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
158279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1583d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ASSERT(args.length() == 1);
1584e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
15854668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  // We don't expect access checks to be needed on JSProxy objects.
15864668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
15876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  do {
15884668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    if (obj->IsAccessCheckNeeded() &&
15894668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        !isolate->MayNamedAccess(JSObject::cast(obj),
15904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                                 isolate->heap()->proto_string(),
15914668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org                                 v8::ACCESS_GET)) {
15924668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
1593169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
15944668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      return isolate->heap()->undefined_value();
15954668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    }
15968432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    obj = obj->GetPrototype(isolate);
15976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  } while (obj->IsJSObject() &&
15986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org           JSObject::cast(obj)->map()->is_hidden_prototype());
1599d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  return obj;
1600d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
1601d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
1602d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
1603e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate,
1604e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                                       Object* receiver) {
1605e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Object* current = receiver->GetPrototype(isolate);
1606e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  while (current->IsJSObject() &&
1607e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org         JSObject::cast(current)->map()->is_hidden_prototype()) {
1608e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    current = current->GetPrototype(isolate);
1609e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return current;
1611e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
1612e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1613e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1614750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
1615c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HandleScope scope(isolate);
1616750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(args.length() == 2);
1617c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1618c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (FLAG_harmony_observation && obj->map()->is_observed()) {
1620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Object> old_value(
1621c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
1622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1623c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
1624e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate, result);
1625e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Object> new_value(
1627c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
1628e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (!new_value->SameValue(*old_value)) {
1629c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      JSObject::EnqueueChangeRecord(obj, "prototype",
1630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                    isolate->factory()->proto_string(),
1631e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                    old_value);
1632e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
1633c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    return *result;
1634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1635c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
1636e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
1637c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  return *result;
1638750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
1639750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1640750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1641c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
164279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* O = args[0];
164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* V = args[1];
164743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (true) {
16488432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Object* prototype = V->GetPrototype(isolate);
1649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (prototype->IsNull()) return isolate->heap()->false_value();
1650ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (O == prototype) return isolate->heap()->true_value();
165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    V = prototype;
165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic bool CheckAccessException(Object* callback,
16578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                 v8::AccessType access_type) {
16588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (callback->IsAccessorInfo()) {
16598e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    AccessorInfo* info = AccessorInfo::cast(callback);
16608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return
16618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        (access_type == v8::ACCESS_HAS &&
16628e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org           (info->all_can_read() || info->all_can_write())) ||
16638e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        (access_type == v8::ACCESS_GET && info->all_can_read()) ||
16648e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        (access_type == v8::ACCESS_SET && info->all_can_write());
16658e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
16668e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return false;
16678e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
16680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1669753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
16708e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgtemplate<class Key>
16718e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic bool CheckGenericAccess(
16728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    JSObject* receiver,
16738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    JSObject* holder,
16748e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Key key,
16758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    v8::AccessType access_type,
16768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    bool (Isolate::*mayAccess)(JSObject*, Key, v8::AccessType)) {
16778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Isolate* isolate = receiver->GetIsolate();
16788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (JSObject* current = receiver;
16798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org       true;
16808e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org       current = JSObject::cast(current->GetPrototype())) {
16818e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (current->IsAccessCheckNeeded() &&
16828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        !(isolate->*mayAccess)(current, key, access_type)) {
16838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      return false;
16848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
16858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (current == holder) break;
16868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
16878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return true;
16880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
16890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
16900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
16918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgenum AccessCheckResult {
16928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ACCESS_FORBIDDEN,
16938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ACCESS_ALLOWED,
16948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ACCESS_ABSENT
16958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org};
16968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
16978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
16988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic AccessCheckResult CheckPropertyAccess(
16998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    JSObject* obj,
1700750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Name* name,
17018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    v8::AccessType access_type) {
17028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  uint32_t index;
17038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (name->AsArrayIndex(&index)) {
1704169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // TODO(1095): we should traverse hidden prototype hierachy as well.
1705169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (CheckGenericAccess(
1706169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org            obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
1707169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      return ACCESS_ALLOWED;
1708169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
1709169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1710169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1711169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return ACCESS_FORBIDDEN;
17128e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
1713fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
17148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  LookupResult lookup(obj->GetIsolate());
17158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  obj->LocalLookup(name, &lookup, true);
1716fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
17178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (!lookup.IsProperty()) return ACCESS_ABSENT;
17188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (CheckGenericAccess<Object*>(
17198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) {
17208e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return ACCESS_ALLOWED;
172183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
172283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
17238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Access check callback denied the access, but some properties
17248e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // can have a special permissions which override callbacks descision
17258e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // (currently see v8::AccessControl).
172683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // API callbacks can have per callback access exceptions.
17278e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  switch (lookup.type()) {
17288e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case CALLBACKS:
17298e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
17308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        return ACCESS_ALLOWED;
173183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
173283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      break;
17338e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case INTERCEPTOR:
173483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      // If the object has an interceptor, try real named properties.
173583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      // Overwrite the result to fetch the correct property later.
17368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      lookup.holder()->LookupRealNamedProperty(name, &lookup);
17378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
17388e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
17398e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          return ACCESS_ALLOWED;
174083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        }
174183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
174283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      break;
174383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    default:
174483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      break;
174583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
174683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
17478e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
17488e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return ACCESS_FORBIDDEN;
1749f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org}
1750f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
1751f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
175230ce411529579186181838984710b0b0980857aaricow@chromium.org// Enumerator used as indices into the array returned from GetOwnProperty
175330ce411529579186181838984710b0b0980857aaricow@chromium.orgenum PropertyDescriptorIndices {
175430ce411529579186181838984710b0b0980857aaricow@chromium.org  IS_ACCESSOR_INDEX,
175530ce411529579186181838984710b0b0980857aaricow@chromium.org  VALUE_INDEX,
175630ce411529579186181838984710b0b0980857aaricow@chromium.org  GETTER_INDEX,
175730ce411529579186181838984710b0b0980857aaricow@chromium.org  SETTER_INDEX,
175830ce411529579186181838984710b0b0980857aaricow@chromium.org  WRITABLE_INDEX,
175930ce411529579186181838984710b0b0980857aaricow@chromium.org  ENUMERABLE_INDEX,
176030ce411529579186181838984710b0b0980857aaricow@chromium.org  CONFIGURABLE_INDEX,
176130ce411529579186181838984710b0b0980857aaricow@chromium.org  DESCRIPTOR_SIZE
176230ce411529579186181838984710b0b0980857aaricow@chromium.org};
176330ce411529579186181838984710b0b0980857aaricow@chromium.org
1764bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1765bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comstatic MaybeObject* GetOwnProperty(Isolate* isolate,
1766bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com                                   Handle<JSObject> obj,
1767750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                   Handle<Name> name) {
1768ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
17698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Due to some WebKit tests, we want to make sure that we do not log
17708e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // more than one access failure here.
1771169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  AccessCheckResult access_check_result =
1772169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS);
1773169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1774169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  switch (access_check_result) {
17758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case ACCESS_FORBIDDEN: return heap->false_value();
17768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case ACCESS_ALLOWED: break;
17778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case ACCESS_ABSENT: return heap->undefined_value();
1778f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org  }
1779f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
17808e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name);
1781169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (attrs == ABSENT) {
1782169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1783169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return heap->undefined_value();
1784169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
1785169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!isolate->has_scheduled_exception());
178646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name);
178746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  Handle<AccessorPair> accessors(raw_accessors, isolate);
1788f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
17898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
17908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
17918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
179246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL));
17938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
179446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  if (raw_accessors == NULL) {
17958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
17968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // GetProperty does access check.
179709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> value = GetProperty(isolate, obj, name);
1798e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate, value);
17998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    elms->set(VALUE_INDEX, *value);
18008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  } else {
18018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // Access checks are performed for both accessors separately.
18028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // When they fail, the respective field is not set in the descriptor.
18035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Object* getter = accessors->GetComponent(ACCESSOR_GETTER);
18048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Object* setter = accessors->GetComponent(ACCESSOR_SETTER);
18058e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) {
1806169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      ASSERT(!isolate->has_scheduled_exception());
18075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      elms->set(GETTER_INDEX, getter);
1808169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
1809169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
181083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
18118e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) {
1812169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      ASSERT(!isolate->has_scheduled_exception());
18135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      elms->set(SETTER_INDEX, setter);
1814169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
1815169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
181683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
18170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
18180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
18198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return *isolate->factory()->NewJSArrayWithElements(elms);
18200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
18210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
18220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1823bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com// Returns an array with the property description:
1824bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//  if args[1] is not a property on args[0]
1825bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//          returns undefined
1826bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//  if args[1] is a data property on args[0]
1827bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//         [false, value, Writeable, Enumerable, Configurable]
1828bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//  if args[1] is an accessor on args[0]
1829bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//         [true, GetFunction, SetFunction, Enumerable, Configurable]
1830bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
1831bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  HandleScope scope(isolate);
18326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 2);
1833bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1834750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1835bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return GetOwnProperty(isolate, obj, name);
1836bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
1837bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1838bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
1839c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
184079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
184169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  ASSERT(args.length() == 1);
1842f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj, 0);
184369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  return obj->PreventExtensions();
184469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
184569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
1846d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
1847c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
184879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1849b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
1850f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj, 0);
1851d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  if (obj->IsJSGlobalProxy()) {
1852d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    Object* proto = obj->GetPrototype();
1853ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (proto->IsNull()) return isolate->heap()->false_value();
1854d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    ASSERT(proto->IsJSGlobalObject());
1855d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    obj = JSObject::cast(proto);
1856d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  }
18577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
1858b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
1859b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1860b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1861c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
1862ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
186343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
1864f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
1865f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
1866f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
18675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<Object> result =
18681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      RegExpImpl::Compile(re, pattern, flags);
1869e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
18703bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  return *result;
187143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
187243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
187343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1874c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) {
1875ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1877f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
1878ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->CreateApiFunction(data);
187943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
188043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
188143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1882c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsTemplate) {
188379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
188543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* arg = args[0];
18869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
1887ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->ToBoolean(result);
188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
188943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1891c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
189279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1894f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(HeapObject, templ, 0);
1895f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 1)
18969bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  int offset = index * kPointerSize + HeapObject::kHeaderSize;
18979bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  InstanceType type = templ->map()->instance_type();
18989bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  RUNTIME_ASSERT(type ==  FUNCTION_TEMPLATE_INFO_TYPE ||
18999bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org                 type ==  OBJECT_TEMPLATE_INFO_TYPE);
19009bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  RUNTIME_ASSERT(offset > 0);
19019d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
19029bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
19039bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  } else {
19049bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
19059bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
19069bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  return *HeapObject::RawField(templ, offset);
190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
190843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1910c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
191179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1912870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT(args.length() == 1);
1913f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(HeapObject, object, 0);
19143291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  Map* old_map = object->map();
19153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  bool needs_access_checks = old_map->is_access_check_needed();
19163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  if (needs_access_checks) {
19173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    // Copy map so it won't interfere constructor's initial map.
1918753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    Map* new_map;
1919de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    MaybeObject* maybe_new_map = old_map->Copy();
1920753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
19213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
1922753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    new_map->set_is_access_check_needed(false);
1923753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    object->set_map(new_map);
19243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
19257c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(needs_access_checks);
1926870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
1927870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
1928870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
1929c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
193079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1931870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT(args.length() == 1);
1932f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(HeapObject, object, 0);
19333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  Map* old_map = object->map();
19343291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  if (!old_map->is_access_check_needed()) {
19353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    // Copy map so it won't interfere constructor's initial map.
1936753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    Map* new_map;
1937de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    MaybeObject* maybe_new_map = old_map->Copy();
1938753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    if (!maybe_new_map->To(&new_map)) return maybe_new_map;
19393291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
1940753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    new_map->set_is_access_check_needed(true);
1941753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    object->set_map(new_map);
19423291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
1943ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1944870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
1945870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
1946870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
1947ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic Failure* ThrowRedeclarationError(Isolate* isolate,
1948ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        const char* type,
1949ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        Handle<String> name) {
1950ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1951ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> type_handle =
1952ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewStringFromAscii(CStrVector(type));
195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> args[2] = { type_handle, name };
195443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> error =
1955ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2));
1956ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->Throw(*error);
195743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
195843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
195943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1960c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
1961ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
19626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 3);
1963ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<GlobalObject> global = Handle<GlobalObject>(
196446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->context()->global_object());
196543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  Handle<Context> context = args.at<Context>(0);
1967f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
19681805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 2);
196943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
197043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the name/value pairs and set the properties.
197143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = pairs->length();
197243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < length; i += 2) {
1973ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
197443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<String> name(String::cast(pairs->get(i)));
1975ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> value(pairs->get(i + 1), isolate);
197643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
197743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // We have to declare a global const property. To capture we only
197843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // assign to it when evaluating the assignment for "const x =
197943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // <expr>" the initial value is the hole.
1980ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_var = value->IsUndefined();
1981ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_const = value->IsTheHole();
1982ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_function = value->IsSharedFunctionInfo();
19838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    ASSERT(is_var + is_const + is_function == 1);
1984ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
1985ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (is_var || is_const) {
198643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Lookup the property in the global object, and don't set the
198743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // value of the variable if the property is already there.
19885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // Do the lookup locally only, see ES5 erratum.
1989394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate);
19905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      if (FLAG_es52_globals) {
19918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        global->LocalLookup(*name, &lookup, true);
19925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      } else {
199388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org        global->Lookup(*name, &lookup);
19945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      }
1995753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      if (lookup.IsFound()) {
1996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // We found an existing property. Unless it was an interceptor
1997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // that claims the property is absent, skip this declaration.
1998de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org        if (!lookup.IsInterceptor()) continue;
199943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        PropertyAttributes attributes = global->GetPropertyAttribute(*name);
2000ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        if (attributes != ABSENT) continue;
2001c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Fall-through and introduce the absent property by using
2002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // SetProperty.
200343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
2004ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    } else if (is_function) {
200543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Copy the function and update its context. Use it as value.
20065d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      Handle<SharedFunctionInfo> shared =
20075d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org          Handle<SharedFunctionInfo>::cast(value);
200843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<JSFunction> function =
2009ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          isolate->factory()->NewFunctionFromSharedFunctionInfo(
2010ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              shared, context, TENURED);
201143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      value = function;
201243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
201343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2014394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    LookupResult lookup(isolate);
20158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    global->LocalLookup(*name, &lookup, true);
201643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2017ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // Compute the property attributes. According to ECMA-262,
2018ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // the property must be non-configurable except in eval.
20191805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    int attr = NONE;
2020ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
20218e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!is_eval) {
20221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      attr |= DONT_DELETE;
20231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
2024394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bool is_native = DeclareGlobalsNativeFlag::decode(flags);
20258e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (is_const || (is_native && is_function)) {
20261805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      attr |= READ_ONLY;
20271805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
20281805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
20292c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
20302c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
20318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!lookup.IsFound() || is_function) {
2032ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // If the local property exists, check that we can reconfigure it
2033ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // as required for function declarations.
2034753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      if (lookup.IsFound() && lookup.IsDontDelete()) {
2035ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
203699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org            lookup.IsPropertyCallbacks()) {
20378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          return ThrowRedeclarationError(isolate, "function", name);
20382c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org        }
2039ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        // If the existing property is not configurable, keep its attributes.
2040ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        attr = lookup.GetAttributes();
20419ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      }
2042ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Define or redefine own property.
2043ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      RETURN_IF_EMPTY_HANDLE(isolate,
2044ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          JSObject::SetLocalPropertyIgnoreAttributes(
2045ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              global, name, value, static_cast<PropertyAttributes>(attr)));
204643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
2047ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Do a [[Put]] on the existing (own) property.
2048ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      RETURN_IF_EMPTY_HANDLE(isolate,
2049ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          JSObject::SetProperty(
2050ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              global, name, value, static_cast<PropertyAttributes>(attr),
2051ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              language_mode == CLASSIC_MODE ? kNonStrictMode : kStrictMode));
205243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
205343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
20547c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
2055ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!isolate->has_pending_exception());
2056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
205743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
205843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
205943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2060c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
2061ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
20627c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  ASSERT(args.length() == 4);
206343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
206446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Declarations are always made in a function or native context.  In the
2065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // case of eval code, the context passed is the context of the caller,
2066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // which may be some nested context and not the declaration context.
2067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RUNTIME_ASSERT(args[0]->IsContext());
2068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Context> context(Context::cast(args[0])->declaration_context());
2069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
20707c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  Handle<String> name(String::cast(args[1]));
20716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
2072c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
2073ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> initial_value(args[3], isolate);
207443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
207543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
207643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
207743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
207880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
20795a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Handle<Object> holder =
208080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org      context->Lookup(name, flags, &index, &attributes, &binding_flags);
208143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (attributes != ABSENT) {
2083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The name was declared before; check for conflicting re-declarations.
2084ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // Note: this is actually inconsistent with what happens for globals (where
2085ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // we silently ignore such declarations).
208643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
208743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Functions are not read-only.
208843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
208943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
2090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return ThrowRedeclarationError(isolate, type, name);
209143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
209243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
209343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Initialize it if necessary.
209443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (*initial_value != NULL) {
209543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (index >= 0) {
2096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(holder.is_identical_to(context));
2097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (((attributes & READ_ONLY) == 0) ||
2098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            context->get(index)->IsTheHole()) {
2099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          context->set(index, *initial_value);
210043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
210143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
2102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Slow case: The property is in the context extension object of a
210346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        // function context or the global object of a native context.
2104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Handle<JSObject> object = Handle<JSObject>::cast(holder);
2105496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        RETURN_IF_EMPTY_HANDLE(
2106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            isolate,
2107f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com            JSReceiver::SetProperty(object, name, initial_value, mode,
2108f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                    kNonStrictMode));
210943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
211043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
211143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
211243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
21137c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // The property is not in the function context. It needs to be
2114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // "declared" in the function context's extension context or as a
2115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // property of the the global object.
2116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<JSObject> object;
21179fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    if (context->has_extension()) {
2118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object = Handle<JSObject>(JSObject::cast(context->extension()));
21197c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    } else {
2120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Context extension objects are allocated lazily.
2121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(context->IsFunctionContext());
2122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object = isolate->factory()->NewJSObject(
2123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->context_extension_function());
2124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      context->set_extension(*object);
21257c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    }
2126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(*object != NULL);
21277c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
21287c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // Declare the property by setting it to the initial value if provided,
21297c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
21307c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // constant declarations).
2131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(!object->HasLocalProperty(*name));
2132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> value(isolate->heap()->undefined_value(), isolate);
21337c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    if (*initial_value != NULL) value = initial_value;
21343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Declaring a const context slot is a conflicting declaration if
21353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // there is a callback with that name in a prototype. It is
21363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // allowed to introduce const variables in
21373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // JSContextExtensionObjects. They are treated specially in
21383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // SetProperty and no setters are invoked for those since they are
21393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // not real JSObjects.
21403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (initial_value->IsTheHole() &&
2141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        !object->IsJSContextExtensionObject()) {
2142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate);
2143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object->Lookup(*name, &lookup);
2144753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      if (lookup.IsPropertyCallbacks()) {
2145ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return ThrowRedeclarationError(isolate, "const", name);
21463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      }
21473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
2148ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (object->IsJSGlobalObject()) {
2149ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Define own property on the global object.
2150ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      RETURN_IF_EMPTY_HANDLE(isolate,
2151ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com         JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
2152ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    } else {
2153ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      RETURN_IF_EMPTY_HANDLE(isolate,
2154ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com         JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
2155ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
21567c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
21577c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
2158ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
215943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
216043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
216143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2162c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
216379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
21649ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // args[0] == name
21651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // args[1] == language_mode
21669ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // args[2] == value (optional)
216743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
216843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Determine if we need to assign to the variable if it already
216943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // exists (based on the number of arguments).
21709ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
21719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  bool assign = args.length() == 3;
217243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2173f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
217446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  GlobalObject* global = isolate->context()->global_object();
21759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(args[1]->IsSmi());
21761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
21771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
21781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      ? kNonStrictMode : kStrictMode;
217943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
218043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // According to ECMA-262, section 12.2, page 62, the property must
218143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not be deletable.
218243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes = DONT_DELETE;
218343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
218443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Lookup the property locally in the global object. If it isn't
21852abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // there, there is a property with this name in the prototype chain.
21862abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // We follow Safari and Firefox behavior and only set the property
21872abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // locally if there is an explicit initialization value that we have
21883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // to assign to the property.
2189ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Note that objects can have hidden prototypes, so we need to traverse
2190ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // the whole chain of hidden prototypes to do a 'local' lookup.
2191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Object* object = global;
2192394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult lookup(isolate);
21938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  JSObject::cast(object)->LocalLookup(*name, &lookup, true);
21948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (lookup.IsInterceptor()) {
21958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    HandleScope handle_scope(isolate);
21968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    PropertyAttributes intercepted =
21978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        lookup.holder()->GetPropertyAttribute(*name);
21988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
21998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      // Found an interceptor that's not read only.
22008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (assign) {
22018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        return lookup.holder()->SetProperty(
22028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org            &lookup, *name, args[2], attributes, strict_mode_flag);
22038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      } else {
22048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        return isolate->heap()->undefined_value();
2205ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      }
22062abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    }
220743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Reload global in case the loop above performed a GC.
221046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  global = isolate->context()->global_object();
22119ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  if (assign) {
22121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return global->SetProperty(*name, args[2], attributes, strict_mode_flag);
22139ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
2214ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
221543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
221643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
221743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2218c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
221979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // All constants are declared with an initial value. The name
222143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of the constant is the first argument and the initial value
222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is the second.
222343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(args.length() == 2);
2224f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
222543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> value = args.at<Object>(1);
222643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
222743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the current global object from top.
222846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  GlobalObject* global = isolate->context()->global_object();
222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // According to ECMA-262, section 12.2, page 62, the property must
223143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not be deletable. Since it's a const, it must be READ_ONLY too.
223243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes =
223343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
223443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
223543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Lookup the property locally in the global object. If it isn't
223643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // there, we add the property and take special precautions to always
223743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // add it as a local property even in case of callbacks in the
223843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // prototype chain (this rules out using SetProperty).
2239d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  // We use SetLocalPropertyIgnoreAttributes instead
2240394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult lookup(isolate);
224143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  global->LocalLookup(*name, &lookup);
2242753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (!lookup.IsFound()) {
2243d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    return global->SetLocalPropertyIgnoreAttributes(*name,
2244d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    *value,
2245d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    attributes);
224643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
224743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
224843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!lookup.IsReadOnly()) {
224943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Restore global object from context (in case of GC) and continue
2250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // with setting the value.
2251ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope handle_scope(isolate);
225246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Handle<GlobalObject> global(isolate->context()->global_object());
225343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2254496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // BUG 1213575: Handle the case where we have to set a read-only
225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // property through an interceptor and only do it if it's
225643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // uninitialized, e.g. the hole. Nirk...
22579ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Passing non-strict mode because the property is writable.
2258f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    RETURN_IF_EMPTY_HANDLE(
2259f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        isolate,
2260f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        JSReceiver::SetProperty(global, name, value, attributes,
2261f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                kNonStrictMode));
226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
226343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Set the value, but only if we're assigning the initial value to a
226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // constant. For now, we determine this by checking if the
226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // current value is the hole.
2268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Strict mode handling not needed (const is disallowed in strict mode).
2269de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  if (lookup.IsField()) {
227043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    FixedArray* properties = global->properties();
2271eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org    int index = lookup.GetFieldIndex().field_index();
2272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
227343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      properties->set(index, *value);
227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
2275de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  } else if (lookup.IsNormal()) {
2276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
2277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        !lookup.IsReadOnly()) {
2278e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      HandleScope scope(isolate);
2279e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
228043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
228143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
228243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Ignore re-initialization of constants that have already been
2283fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // assigned a constant value.
2284fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
228543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
228743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Use the set value as the result of the operation.
228843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
228943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
229043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2292c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
2293ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2296ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> value(args[0], isolate);
229743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!value->IsTheHole());
229843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
229946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Initializations are always done in a function or native context.
2300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RUNTIME_ASSERT(args[1]->IsContext());
2301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Context> context(Context::cast(args[1])->declaration_context());
2302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<String> name(String::cast(args[2]));
230443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
230543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
230643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
2307ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  ContextLookupFlags flags = FOLLOW_CHAINS;
230880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
23095a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Handle<Object> holder =
231080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org      context->Lookup(name, flags, &index, &attributes, &binding_flags);
231143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
231243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= 0) {
2313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(holder->IsContext());
2314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Property was found in a context.  Perform the assignment if we
2315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // found some non-constant or an uninitialized constant.
2316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<Context> context = Handle<Context>::cast(holder);
2317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
2318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      context->set(index, *value);
231943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
232043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
232243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The property could not be found, we introduce it as a property of the
2324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // global object.
2325ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  if (attributes == ABSENT) {
2326ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<JSObject> global = Handle<JSObject>(
232746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->context()->global_object());
23289ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Strict mode not needed (const disallowed in strict mode).
23299ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    RETURN_IF_EMPTY_HANDLE(
2330ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
2331f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        JSReceiver::SetProperty(global, name, value, NONE, kNonStrictMode));
2332ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    return *value;
2333ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
233443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The property was present in some function's context extension object,
2336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // as a property on the subject of a with, or as a property of the global
2337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object.
2338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // In most situations, eval-introduced consts should still be present in
2340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the context extension object.  However, because declaration and
2341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // initialization are separate, the property might have been deleted
2342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // before we reach the initialization point.
2343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Example:
2345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //    function f() { eval("delete x; const x;"); }
2347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // In that case, the initialization behaves like a normal assignment.
2349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<JSObject> object = Handle<JSObject>::cast(holder);
235043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (*object == context->extension()) {
2352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // This is the property that was introduced by the const declaration.
2353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Set it if it hasn't been set before.  NOTE: We cannot use
2354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // GetProperty() to get the current value as it 'unholes' the value.
2355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    LookupResult lookup(isolate);
2356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    object->LocalLookupRealNamedProperty(*name, &lookup);
235705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    ASSERT(lookup.IsFound());  // the property was declared
2358ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
2359ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
2360de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    if (lookup.IsField()) {
2361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FixedArray* properties = object->properties();
2362eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org      int index = lookup.GetFieldIndex().field_index();
2363ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      if (properties->get(index)->IsTheHole()) {
2364ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        properties->set(index, *value);
2365ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
2366de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    } else if (lookup.IsNormal()) {
2367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
2368e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        JSObject::SetNormalizedProperty(object, &lookup, value);
2369ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
2370ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    } else {
2371ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      // We should not reach here. Any real, named property should be
2372ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      // either a field or a dictionary slot.
2373ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      UNREACHABLE();
237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
237543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
2376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The property was found on some other object.  Set it if it is not a
2377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // read-only property.
2378ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    if ((attributes & READ_ONLY) == 0) {
23799ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      // Strict mode not needed (const disallowed in strict mode).
2380496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      RETURN_IF_EMPTY_HANDLE(
2381ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate,
2382f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          JSReceiver::SetProperty(object, name, value, attributes,
2383f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                  kNonStrictMode));
2384ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
238543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2386ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
238743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
238843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
238943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
239043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2391c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*,
2392c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                 Runtime_OptimizeObjectForAddingMultipleProperties) {
2393ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2394911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  ASSERT(args.length() == 2);
2395f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
23966d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(properties, 1);
2397911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  if (object->HasFastProperties()) {
2398f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
2399911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  }
2400911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  return *object;
2401911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org}
2402911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
2403911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
2404c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
2405ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
24067be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  ASSERT(args.length() == 4);
2407f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2408f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
240968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // Due to the way the JS calls are constructed this must be less than the
24107be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // length of a string, i.e. it is always a Smi.  We check anyway for security.
24116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 2);
2412f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
241368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  RUNTIME_ASSERT(index >= 0);
241468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  RUNTIME_ASSERT(index <= subject->length());
2415ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->regexp_entry_runtime()->Increment();
24167be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  Handle<Object> result = RegExpImpl::Exec(regexp,
24177be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org                                           subject,
241868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org                                           index,
24195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                           last_match_info);
2420e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
2421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return *result;
242243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
242343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
242443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2425c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
242679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2427b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  ASSERT(args.length() == 3);
24286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(elements_count, 0);
24292c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  if (elements_count < 0 ||
24302c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      elements_count > FixedArray::kMaxLength ||
24312c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      !Smi::IsValid(elements_count)) {
2432ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->ThrowIllegalOperation();
2433b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
2434303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* new_object;
2435303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_new_object =
24368dec82379e3dc6c6a3292879ba64f8bee40d2d98jkummerow@chromium.org        isolate->heap()->AllocateFixedArray(elements_count);
2437303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
2438303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2439b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  FixedArray* elements = FixedArray::cast(new_object);
2440ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw(
2441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
2442303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
2443303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
2444b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  {
244579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
2446ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
2447b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    reinterpret_cast<HeapObject*>(new_object)->
244846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        set_map(isolate->native_context()->regexp_result_map());
2449b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
2450b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  JSArray* array = JSArray::cast(new_object);
2451ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  array->set_properties(isolate->heap()->empty_fixed_array());
2452b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  array->set_elements(elements);
2453b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  array->set_length(Smi::FromInt(elements_count));
2454b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // Write in-object properties after the length of the array.
2455b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
2456b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
2457b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  return array;
2458b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
2459b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2460b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2461c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
246279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
246379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
246425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(args.length() == 5);
2465f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
2466f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, source, 1);
2467efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  // If source is the empty string we set it to "(?:)" instead as
2468efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  // suggested by ECMA-262, 5th, section 15.10.4.1.
24694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (source->length() == 0) source = isolate->heap()->query_colon_string();
247025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
247125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Object* global = args[2];
2472ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!global->IsTrue()) global = isolate->heap()->false_value();
247325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
247425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Object* ignoreCase = args[3];
2475ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value();
247625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
247725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Object* multiline = args[4];
2478ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!multiline->IsTrue()) multiline = isolate->heap()->false_value();
247925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
248025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Map* map = regexp->map();
248125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Object* constructor = map->constructor();
248225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  if (constructor->IsJSFunction() &&
248325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      JSFunction::cast(constructor)->initial_map() == map) {
248425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // If we still have the original map, set in-object properties directly.
248525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
24860ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // Both true and false are immovable immortal objects so no need for write
24870ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // barrier.
24880ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    regexp->InObjectPropertyAtPut(
24890ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER);
24900ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    regexp->InObjectPropertyAtPut(
24910ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
24920ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    regexp->InObjectPropertyAtPut(
24930ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry        JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
24946bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org    regexp->InObjectPropertyAtPut(
24956bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org        JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
249625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return regexp;
249725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
249825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
2499ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Map has changed, so use generic, but slower, method.
250025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  PropertyAttributes final =
250125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
250225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  PropertyAttributes writable =
250325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2504ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
2505303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* result;
25064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_string(),
2507d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    source,
2508d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    final);
250959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // TODO(jkummerow): Turn these back into ASSERTs when we can be certain
251059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // that it never fires in Release mode in the wild.
251159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CHECK(!result->IsFailure());
25124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_string(),
2513d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    global,
2514d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    final);
251559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CHECK(!result->IsFailure());
2516303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  result =
25174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_string(),
2518d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                               ignoreCase,
2519d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                               final);
252059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CHECK(!result->IsFailure());
25214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_string(),
2522d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    multiline,
2523d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                    final);
252459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CHECK(!result->IsFailure());
2525303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  result =
25264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_string(),
2527d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                               Smi::FromInt(0),
2528d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                               writable);
252959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CHECK(!result->IsFailure());
2530303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  USE(result);
253125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  return regexp;
253225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
253325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
253425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
2535c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
2536ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2537ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 1);
2538f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
2539ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // This is necessary to enable fast checks for absence of elements
2540ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // on Array.prototype and below.
2541ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  prototype->set_elements(isolate->heap()->empty_fixed_array());
2542ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return Smi::FromInt(0);
2543ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
2544ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2545ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2546ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic Handle<JSFunction> InstallBuiltin(Isolate* isolate,
2547ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         Handle<JSObject> holder,
2548f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org                                         const char* name,
2549720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                                         Builtins::Name builtin_name) {
25504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
2551ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Code> code(isolate->builtins()->builtin(builtin_name));
2552ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSFunction> optimized =
2553ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFunction(key,
2554ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      JS_OBJECT_TYPE,
2555ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      JSObject::kHeaderSize,
2556ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      code,
2557ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                      false);
2558f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  optimized->shared()->DontAdaptArguments();
2559f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  JSReceiver::SetProperty(holder, key, optimized, NONE, kStrictMode);
2560f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  return optimized;
2561f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
2562f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2563f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2564c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
2565ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2566f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  ASSERT(args.length() == 1);
2567f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
2568f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
25697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
25707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
25717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
25727979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
25737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
25747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
25757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
2576f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2577f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  return *holder;
2578f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
2579f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2580f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2581e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsClassicModeFunction) {
258279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2583e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(args.length() == 1);
2584e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2585e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!callable->IsJSFunction()) {
2586e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    HandleScope scope(isolate);
2587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    bool threw = false;
2588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Object> delegate =
2589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
2590e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (threw) return Failure::Exception();
2591e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    callable = JSFunction::cast(*delegate);
2592e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
2593e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JSFunction* function = JSFunction::cast(callable);
2594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  SharedFunctionInfo* shared = function->shared();
2595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return isolate->heap()->ToBoolean(shared->is_classic_mode());
2596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
2597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
25994668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
260079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
26014668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  ASSERT(args.length() == 1);
2602f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
260305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
260405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (!callable->IsJSFunction()) {
260505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    HandleScope scope(isolate);
260605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    bool threw = false;
260705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    Handle<Object> delegate =
260805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org        Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
260905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    if (threw) return Failure::Exception();
261005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    callable = JSFunction::cast(*delegate);
261105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
261205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  JSFunction* function = JSFunction::cast(callable);
261305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
26144668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  SharedFunctionInfo* shared = function->shared();
26151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (shared->native() || !shared->is_classic_mode()) {
26164668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    return isolate->heap()->undefined_value();
26174668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  }
26184668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  // Returns undefined for strict or native functions, or
26194668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  // the associated global receiver for "normal" functions.
26204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
262146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* native_context =
262246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      function->context()->global_object()->native_context();
262346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return native_context->global_object()->global_receiver();
2624357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
2625357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
2626357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
2627c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
2628ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
262943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 4);
2630f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
26316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int index = args.smi_at(1);
263243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> pattern = args.at<String>(2);
263343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> flags = args.at<String>(3);
263443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
263541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Get the RegExp function from the context in the literals array.
263641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // This is the RegExp function from the context in which the
263741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // function was created.  We do not use the RegExp function from the
263846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // current native context because this might be the RegExp function
263941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // from another context which we should not have access to.
26409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<JSFunction> constructor =
2641236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      Handle<JSFunction>(
264246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
264343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the regular expression literal.
264443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool has_pending_exception;
264543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> regexp =
26469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags,
26479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com                                      &has_pending_exception);
264843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (has_pending_exception) {
2649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ASSERT(isolate->has_pending_exception());
265043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Failure::Exception();
265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  literals->set(index, *regexp);
265343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *regexp;
265443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
265543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
265643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2657c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetName) {
265879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
265943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
266043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2661f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
266243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return f->shared()->name();
266343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
266443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
266543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2666c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
266779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2668236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  ASSERT(args.length() == 2);
2669236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
2670f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
2671f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, name, 1);
2672236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  f->shared()->set_name(name);
2673ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
2674236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
2675236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
2676236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
26777c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
267879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
26797c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 1);
2680f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
26817c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(
26827c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      f->shared()->name_should_print_as_anonymous());
26837c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
26847c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
26857c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
26867c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
268779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
26887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 1);
2689f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
26907c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  f->shared()->set_name_should_print_as_anonymous(true);
26917c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->undefined_value();
26927c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
26937c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
26947c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
269557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsGenerator) {
269679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
269757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ASSERT(args.length() == 1);
269857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
269957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  return isolate->heap()->ToBoolean(f->shared()->is_generator());
270057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
270157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
270257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
2703c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
270479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
27054111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  ASSERT(args.length() == 1);
27064111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
2707f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
2708de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  f->RemovePrototype();
27094111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
2710ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
27114111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
27124111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
27134111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
2714c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScript) {
2715ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
271643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
271743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2718f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2719ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
2720ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!script->IsScript()) return isolate->heap()->undefined_value();
272143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
272243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *GetScriptWrapper(Handle<Script>::cast(script));
272343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
272443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
272543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2726c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetSourceCode) {
272778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  HandleScope scope(isolate);
272843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2730f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
273178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  Handle<SharedFunctionInfo> shared(f->shared());
273278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  return *shared->GetSourceCode();
273343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
273443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2736c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScriptSourcePosition) {
273779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
273843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
273943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2740f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
274143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos = fun->shared()->start_position();
274243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(pos);
274343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
274443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
274543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2746c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
274779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
27482abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(args.length() == 2);
27492abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
2750f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(Code, code, 0);
27512abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
27522abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
27532abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  RUNTIME_ASSERT(0 <= offset && offset < code->Size());
27542abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
27552abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  Address pc = code->address() + offset;
2756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return Smi::FromInt(code->SourcePosition(pc));
27572abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
27582abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
27592abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
2760c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetInstanceClassName) {
276179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
276243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
276343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2764f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2765f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, name, 1);
276643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fun->SetInstanceClassName(name);
2767ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
276943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
277043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2771c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
277279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2775f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2776f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(length, 1);
2777f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  fun->shared()->set_length(length);
2778f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return isolate->heap()->undefined_value();
277943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
278043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
278143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2782c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
278379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
278443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
278543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2786f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
27874111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  ASSERT(fun->should_have_prototype());
2788303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
2789303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj =
2790303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        Accessors::FunctionSetPrototype(fun, args[1], NULL);
2791303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2792303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
279343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return args[0];  // return TOS
279443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
279543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
279643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
27972c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
279879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
27992c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  RUNTIME_ASSERT(args.length() == 1);
2800f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, function, 0);
28012c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
28024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  String* name = isolate->heap()->prototype_string();
28032c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
28042c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  if (function->HasFastProperties()) {
28052c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    // Construct a new field descriptor with updated attributes.
28062c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    DescriptorArray* instance_desc = function->map()->instance_descriptors();
2807753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
280806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    int index = instance_desc->SearchWithCache(name, function->map());
28092c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    ASSERT(index != DescriptorArray::kNotFound);
2810ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    PropertyDetails details = instance_desc->GetDetails(index);
2811753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
28122c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    CallbacksDescriptor new_desc(name,
28132c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        instance_desc->GetValue(index),
281457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
2815753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
28162c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    // Create a new map featuring the new field descriptors array.
2817657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    Map* new_map;
2818753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    MaybeObject* maybe_map =
2819753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org        function->map()->CopyReplaceDescriptor(
2820c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org            instance_desc, &new_desc, index, OMIT_TRANSITION);
2821753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    if (!maybe_map->To(&new_map)) return maybe_map;
2822753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
28232c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    function->set_map(new_map);
28242c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  } else {  // Dictionary properties.
28252c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    // Directly manipulate the property details.
28262c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    int entry = function->property_dictionary()->FindEntry(name);
2827750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    ASSERT(entry != NameDictionary::kNotFound);
28282c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
28292c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    PropertyDetails new_details(
28302c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
28312c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        details.type(),
283246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        details.dictionary_index());
28332c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    function->property_dictionary()->DetailsAtPut(entry, new_details);
28342c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  }
28352c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  return function;
28362c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org}
28372c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
28382c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
2839c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
284079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
284137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  ASSERT(args.length() == 1);
284237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
2843f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
28447c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
284537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
284637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
2847ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
2848c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
284979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
28502bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  ASSERT(args.length() == 1);
28512bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
2852f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
28537c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(f->IsBuiltin());
28542bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com}
28552bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
285637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
2857c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
2858ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
285943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
286043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2861f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
286243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> code = args.at<Object>(1);
286343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (code->IsNull()) return *target;
28657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  RUNTIME_ASSERT(code->IsJSFunction());
28667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<JSFunction> source = Handle<JSFunction>::cast(code);
28677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<SharedFunctionInfo> target_shared(target->shared());
28687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<SharedFunctionInfo> source_shared(source->shared());
286943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!JSFunction::EnsureCompiled(source, KEEP_EXCEPTION)) {
28717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    return Failure::Exception();
287243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
287343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2874906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // Mark both, the source and the target, as un-flushable because the
2875906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // shared unoptimized code makes them impossible to enqueue in a list.
2876906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  ASSERT(target_shared->code()->gc_metadata() == NULL);
2877906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  ASSERT(source_shared->code()->gc_metadata() == NULL);
2878906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  target_shared->set_dont_flush(true);
2879906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  source_shared->set_dont_flush(true);
2880906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
28817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Set the code, scope info, formal parameter count, and the length
28827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // of the target shared function info.  Set the source code of the
28837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // target function to undefined.  SetCode is only used for built-in
28847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // constructors like String, Array, and Object, and some web code
28857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // doesn't like seeing source code for constructors.
28869768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  target_shared->ReplaceCode(source_shared->code());
28877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_scope_info(source_shared->scope_info());
28887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_length(source_shared->length());
28897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_formal_parameter_count(
28907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      source_shared->formal_parameter_count());
28917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_script(isolate->heap()->undefined_value());
28927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
28937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Since we don't store the source we should never optimize this.
28947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->code()->set_optimizable(false);
28957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
28967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Set the code of the target function.
28977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target->ReplaceCode(source_shared->code());
289889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  ASSERT(target->next_function_link()->IsUndefined());
28997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
29007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Make sure we get a fresh copy of the literal vector to avoid cross
29017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // context contamination.
29027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<Context> context(source->context());
29037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  int number_of_literals = source->NumberOfLiterals();
29047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<FixedArray> literals =
29057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
29067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (number_of_literals > 0) {
290746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    literals->set(JSFunction::kLiteralNativeContextIndex,
290846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                  context->native_context());
29097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
291043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  target->set_context(*context);
29117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target->set_literals(*literals);
29127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
2913355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (isolate->logger()->is_logging_code_events() ||
2914f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      isolate->cpu_profiler()->is_profiling()) {
29157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    isolate->logger()->LogExistingFunction(
29167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        source_shared, Handle<Code>(source_shared->code()));
29177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
29187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
291943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *target;
292043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
292143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
292243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2923c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
2924ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2925d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  ASSERT(args.length() == 2);
2926f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
29276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(num, 1);
2928d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  RUNTIME_ASSERT(num >= 0);
2929d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  SetExpectedNofProperties(function, num);
2930ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
2931d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org}
2932d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
2933d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
2934e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
293579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2936e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(args.length() == 0);
293777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
2938e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JavaScriptFrameIterator it(isolate);
2939e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JavaScriptFrame* frame = it.frame();
2940169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  JSFunction* function = frame->function();
2941e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  RUNTIME_ASSERT(function->shared()->is_generator());
2942e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2943e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JSGeneratorObject* generator;
2944e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (frame->IsConstructor()) {
2945e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    generator = JSGeneratorObject::cast(frame->receiver());
2946e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
2947e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    MaybeObject* maybe_generator =
2948e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        isolate->heap()->AllocateJSGeneratorObject(function);
2949e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (!maybe_generator->To(&generator)) return maybe_generator;
2950e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
2951e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  generator->set_function(function);
295277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  generator->set_context(Context::cast(frame->context()));
2953ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  generator->set_receiver(frame->receiver());
2954e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  generator->set_continuation(0);
2955e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  generator->set_operand_stack(isolate->heap()->empty_fixed_array());
295657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  generator->set_stack_handler_index(-1);
2957e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2958e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return generator;
2959e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
2960e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2961e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
296277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) {
296379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
296477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  ASSERT(args.length() == 1);
2965f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
296677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
296777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  JavaScriptFrameIterator stack_iterator(isolate);
2968f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  JavaScriptFrame* frame = stack_iterator.frame();
2969169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
2970169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT_EQ(frame->function(), generator_object->function());
29711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
29721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // The caller should have saved the context and continuation already.
29731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
29741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT_LT(0, generator_object->continuation());
297577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
2976f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // We expect there to be at least two values on the operand stack: the return
2977f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // value of the yield expression, and the argument to this runtime call.
2978f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // Neither of those should be saved.
2979f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int operands_count = frame->ComputeOperandsCount();
29801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT_GE(operands_count, 2);
2981f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  operands_count -= 2;
298277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
2983f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (operands_count == 0) {
29841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // Although it's semantically harmless to call this function with an
29851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // operands_count of zero, it is also unnecessary.
298677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    ASSERT_EQ(generator_object->operand_stack(),
298777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org              isolate->heap()->empty_fixed_array());
298857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT_EQ(generator_object->stack_handler_index(), -1);
298977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // If there are no operands on the stack, there shouldn't be a handler
2990ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    // active either.
299177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    ASSERT(!frame->HasHandler());
299277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  } else {
299357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    int stack_handler_index = -1;
2994f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count);
299557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    FixedArray* operand_stack;
2996f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (!alloc->To(&operand_stack)) return alloc;
299757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    frame->SaveOperandStack(operand_stack, &stack_handler_index);
2998f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    generator_object->set_operand_stack(operand_stack);
299957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    generator_object->set_stack_handler_index(stack_handler_index);
300077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
300177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
30021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return isolate->heap()->undefined_value();
300377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org}
300477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
300577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
3006ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Note that this function is the slow path for resuming generators.  It is only
3007ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// called if the suspended activation had operands on the stack, stack handlers
3008ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// needing rewinding, or if the resume should throw an exception.  The fast path
3009ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
30108a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
30118a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// called in any case, as it needs to reconstruct the stack frame and make space
30128a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// for arguments and operands.
3013ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ResumeJSGeneratorObject) {
301479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
3015ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(args.length() == 3);
3016f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
3017f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  CONVERT_ARG_CHECKED(Object, value, 1);
3018ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
3019ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  JavaScriptFrameIterator stack_iterator(isolate);
3020f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  JavaScriptFrame* frame = stack_iterator.frame();
3021ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3022ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT_EQ(frame->function(), generator_object->function());
3023594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(frame->function()->is_compiled());
3024ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3025ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0);
3026ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0);
3027ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3028ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Address pc = generator_object->function()->code()->instruction_start();
3029ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  int offset = generator_object->continuation();
3030ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(offset > 0);
3031ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  frame->set_pc(pc + offset);
3032ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
3033ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3034f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  FixedArray* operand_stack = generator_object->operand_stack();
3035f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int operands_count = operand_stack->length();
3036f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (operands_count != 0) {
303757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    frame->RestoreOperandStack(operand_stack,
303857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                               generator_object->stack_handler_index());
3039f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
304057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    generator_object->set_stack_handler_index(-1);
3041ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
3042ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3043ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  JSGeneratorObject::ResumeMode resume_mode =
3044ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
3045ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  switch (resume_mode) {
30468a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    case JSGeneratorObject::NEXT:
3047f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      return value;
3048ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    case JSGeneratorObject::THROW:
3049f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      return isolate->Throw(value);
3050ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
3051ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3052ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  UNREACHABLE();
3053ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return isolate->ThrowIllegalOperation();
3054ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3055ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3056ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3057ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowGeneratorStateError) {
3058ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HandleScope scope(isolate);
3059ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(args.length() == 1);
3060ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
3061ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  int continuation = generator->continuation();
3062f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
3063ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      "generator_finished" : "generator_running";
3064ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
3065ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Handle<Object> error = isolate->factory()->NewError(message, argv);
3066ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return isolate->Throw(*error);
3067ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3068ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3069ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3070a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) {
307179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
3072a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(args.length() == 1);
3073a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  CONVERT_ARG_CHECKED(JSObject, object, 0);
3074a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  return object->Freeze(isolate);
3075a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
3076a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3077a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
3079ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                 Object* char_code) {
3080b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (char_code->IsNumber()) {
3081b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    return isolate->heap()->LookupSingleCharacterStringFromCode(
3082b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        NumberToUint32(char_code) & 0xffff);
30830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
3084ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->empty_string();
30850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
30860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
30870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3088c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAt) {
308979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
309143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3092f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, subject, 0);
3093de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
309443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30951af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Flatten the string.  If someone wants to get a char at an index
30961af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // in a cons string, it is likely that more indices will be
30971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // accessed.
3098303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* flat;
3099303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_flat = subject->TryFlatten();
3100303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_flat->ToObject(&flat)) return maybe_flat;
3101303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
31021af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  subject = String::cast(flat);
31030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
31041af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (i >= static_cast<uint32_t>(subject->length())) {
3105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->nan_value();
310674e4e5ea6d118c13967c54fe92c7782ebdcb6eb7kasperl@chromium.org  }
31071af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
31081af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  return Smi::FromInt(subject->Get(i));
31090c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
31100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
31110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3112c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CharFromCode) {
311379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
311443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
3115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return CharFromCode(isolate, args[0]);
311643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
311743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
311825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
311925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgclass FixedArrayBuilder {
312025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org public:
3121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
3122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
3123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        length_(0),
3124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        has_non_smi_elements_(false) {
312525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // Require a non-zero initial size. Ensures that doubling the size to
312625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // extend the array will work.
312725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(initial_capacity > 0);
312825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
312925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
313025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
313125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      : array_(backing_store),
3132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        length_(0),
3133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        has_non_smi_elements_(false) {
313425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // Require a non-zero initial size. Ensures that doubling the size to
313525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // extend the array will work.
313625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(backing_store->length() > 0);
313725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
313825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
313925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  bool HasCapacity(int elements) {
314025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int length = array_->length();
314125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int required_length = length_ + elements;
314225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return (length >= required_length);
314325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
314425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
314525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void EnsureCapacity(int elements) {
314625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int length = array_->length();
314725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int required_length = length_ + elements;
314825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (length < required_length) {
314925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      int new_length = length;
315025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      do {
315125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org        new_length *= 2;
315225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      } while (new_length < required_length);
315325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      Handle<FixedArray> extended_array =
3154ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
315525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      array_->CopyTo(0, *extended_array, 0, length_);
315625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      array_ = extended_array;
315725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    }
315825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
315925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
316025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void Add(Object* value) {
3161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(!value->IsSmi());
316225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(length_ < capacity());
316325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_->set(length_, value);
316425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    length_++;
3165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    has_non_smi_elements_ = true;
316625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
316725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
316825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void Add(Smi* value) {
3169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(value->IsSmi());
317025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(length_ < capacity());
317125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_->set(length_, value);
317225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    length_++;
317325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
317425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
317525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Handle<FixedArray> array() {
317625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return array_;
317725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
317825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
317925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int length() {
318025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return length_;
318125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
318225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
318325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int capacity() {
318425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return array_->length();
318525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
318625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
318725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
3188d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    Factory* factory = target_array->GetIsolate()->factory();
3189d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    factory->SetContent(target_array, array_);
319025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    target_array->set_length(Smi::FromInt(length_));
319125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return target_array;
319225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
319325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
319478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
319525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org private:
319625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Handle<FixedArray> array_;
319725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int length_;
3198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_non_smi_elements_;
319925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org};
320025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
320125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
3202bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Forward declarations.
320325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgconst int kStringBuilderConcatHelperLengthBits = 11;
320425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgconst int kStringBuilderConcatHelperPositionBits = 19;
3205bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3206bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgtemplate <typename schar>
3207bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic inline void StringBuilderConcatHelper(String*,
3208bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                             schar*,
3209bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                             FixedArray*,
3210bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                             int);
3211bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
321225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgtypedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
321325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    StringBuilderSubstringLength;
321425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgtypedef BitField<int,
321525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                 kStringBuilderConcatHelperLengthBits,
321625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                 kStringBuilderConcatHelperPositionBits>
321725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    StringBuilderSubstringPosition;
321825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
3219bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3220bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgclass ReplacementStringBuilder {
3221bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org public:
3222ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ReplacementStringBuilder(Heap* heap,
3223ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           Handle<String> subject,
3224ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           int estimated_part_count)
3225ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : heap_(heap),
3226ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        array_builder_(heap->isolate(), estimated_part_count),
322725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org        subject_(subject),
3228bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        character_count_(0),
32298e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        is_ascii_(subject->IsOneByteRepresentation()) {
3230bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Require a non-zero initial size. Ensures that doubling the size to
3231bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // extend the array will work.
3232bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(estimated_part_count > 0);
3233bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3234bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
323525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  static inline void AddSubjectSlice(FixedArrayBuilder* builder,
323625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                     int from,
323725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                     int to) {
3238bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(from >= 0);
3239bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int length = to - from;
3240bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(length > 0);
3241bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (StringBuilderSubstringLength::is_valid(length) &&
3242bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        StringBuilderSubstringPosition::is_valid(from)) {
3243bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int encoded_slice = StringBuilderSubstringLength::encode(length) |
3244bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          StringBuilderSubstringPosition::encode(from);
324525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      builder->Add(Smi::FromInt(encoded_slice));
3246bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else {
3247c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      // Otherwise encode as two smis.
324825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      builder->Add(Smi::FromInt(-length));
324925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      builder->Add(Smi::FromInt(from));
3250bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
325125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
325225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
325325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
325425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void EnsureCapacity(int elements) {
325525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_builder_.EnsureCapacity(elements);
325625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
325725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
325825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
325925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void AddSubjectSlice(int from, int to) {
326025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    AddSubjectSlice(&array_builder_, from, to);
326125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    IncrementCharacterCount(to - from);
3262bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3263bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3264bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3265bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void AddString(Handle<String> string) {
3266bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int length = string->length();
3267bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(length > 0);
3268bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    AddElement(*string);
32698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!string->IsOneByteRepresentation()) {
3270bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      is_ascii_ = false;
3271bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3272bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    IncrementCharacterCount(length);
3273bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3274bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3275bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3276bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<String> ToString() {
327725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (array_builder_.length() == 0) {
3278ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return heap_->isolate()->factory()->empty_string();
3279bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3280bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3281bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<String> joined_string;
3282bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (is_ascii_) {
3283fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_);
328479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
328559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      uint8_t* char_buffer = seq->GetChars();
3286bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      StringBuilderConcatHelper(*subject_,
3287bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                char_buffer,
328825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                *array_builder_.array(),
328925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                array_builder_.length());
329004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      joined_string = Handle<String>::cast(seq);
3291bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else {
3292bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      // Non-ASCII.
329304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
329479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
3295bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      uc16* char_buffer = seq->GetChars();
3296bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      StringBuilderConcatHelper(*subject_,
3297bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                char_buffer,
329825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                *array_builder_.array(),
329925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                array_builder_.length());
330004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      joined_string = Handle<String>::cast(seq);
3301bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3302bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return joined_string;
3303bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3304bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3305bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3306bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void IncrementCharacterCount(int by) {
33070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if (character_count_ > String::kMaxLength - by) {
3308bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      V8::FatalProcessOutOfMemory("String.replace result too large.");
3309bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3310bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    character_count_ += by;
3311bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3312bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
331325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org private:
3314fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  Handle<SeqOneByteString> NewRawOneByteString(int length) {
3315fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return heap_->isolate()->factory()->NewRawOneByteString(length);
3316bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3317bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3318bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
331904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
332004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    return heap_->isolate()->factory()->NewRawTwoByteString(length);
3321bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3322bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3323bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3324bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void AddElement(Object* element) {
3325bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(element->IsSmi() || element->IsString());
332625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(array_builder_.capacity() > array_builder_.length());
332725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_builder_.Add(element);
3328bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3329bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3330ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap_;
333125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  FixedArrayBuilder array_builder_;
3332bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<String> subject_;
3333bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int character_count_;
3334bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  bool is_ascii_;
3335bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org};
3336bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3337bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3338bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgclass CompiledReplacement {
3339bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org public:
33407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  explicit CompiledReplacement(Zone* zone)
3341355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
3342bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3343355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Return whether the replacement is simple.
3344355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool Compile(Handle<String> replacement,
3345bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org               int capture_count,
3346bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org               int subject_length);
3347bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3348355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Use Apply only if Compile returned false.
3349bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void Apply(ReplacementStringBuilder* builder,
3350bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org             int match_from,
3351bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org             int match_to,
3352355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org             int32_t* match);
3353bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3354bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Number of distinct parts of the replacement pattern.
3355bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int parts() {
3356bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return parts_.length();
3357bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3358e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
33597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone() const { return zone_; }
33607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
3361bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org private:
3362bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  enum PartType {
3363bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    SUBJECT_PREFIX = 1,
3364bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    SUBJECT_SUFFIX,
3365bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    SUBJECT_CAPTURE,
3366bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    REPLACEMENT_SUBSTRING,
3367bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    REPLACEMENT_STRING,
3368bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3369bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    NUMBER_OF_PART_TYPES
3370bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  };
3371bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3372bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  struct ReplacementPart {
3373bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectMatch() {
3374bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_CAPTURE, 0);
3375bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3376bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectCapture(int capture_index) {
3377bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_CAPTURE, capture_index);
3378bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3379bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectPrefix() {
3380bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_PREFIX, 0);
3381bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3382bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectSuffix(int subject_length) {
3383bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_SUFFIX, subject_length);
3384bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3385bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart ReplacementString() {
3386bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(REPLACEMENT_STRING, 0);
3387bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3388bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart ReplacementSubString(int from, int to) {
3389bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      ASSERT(from >= 0);
3390bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      ASSERT(to > from);
3391bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(-from, to);
3392bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3393bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3394bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // If tag <= 0 then it is the negation of a start index of a substring of
3395bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // the replacement pattern, otherwise it's a value from PartType.
3396bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ReplacementPart(int tag, int data)
3397bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        : tag(tag), data(data) {
3398bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      // Must be non-positive or a PartType value.
3399bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      ASSERT(tag < NUMBER_OF_PART_TYPES);
3400bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3401bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Either a value of PartType or a non-positive number that is
3402bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // the negation of an index into the replacement string.
3403bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int tag;
3404bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // The data value's interpretation depends on the value of tag:
3405bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == SUBJECT_PREFIX ||
3406bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == SUBJECT_SUFFIX:  data is unused.
3407bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == SUBJECT_CAPTURE: data is the number of the capture.
3408bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == REPLACEMENT_SUBSTRING ||
3409bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == REPLACEMENT_STRING:    data is index into array of substrings
3410bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //                               of the replacement string.
3411bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag <= 0: Temporary representation of the substring of the replacement
3412bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //           string ranging over -tag .. data.
3413bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
3414bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //           substring objects.
3415bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int data;
3416bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  };
3417bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3418bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  template<typename Char>
3419355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
3420355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               Vector<Char> characters,
3421355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               int capture_count,
3422355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               int subject_length,
3423355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               Zone* zone) {
3424bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int length = characters.length();
3425bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int last = 0;
3426bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    for (int i = 0; i < length; i++) {
3427bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      Char c = characters[i];
3428bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      if (c == '$') {
3429bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int next_index = i + 1;
3430bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (next_index == length) {  // No next character!
3431bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3432bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3433bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        Char c2 = characters[next_index];
3434bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        switch (c2) {
3435bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '$':
3436bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
3437bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            // There is a substring before. Include the first "$".
34387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
34397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       zone);
3440bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            last = next_index + 1;  // Continue after the second "$".
3441bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          } else {
3442bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            // Let the next substring start with the second "$".
3443bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            last = next_index;
3444bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3445bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3446bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3447bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '`':
3448bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
34497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3450bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
34517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          parts->Add(ReplacementPart::SubjectPrefix(), zone);
3452bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3453bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          last = i + 1;
3454bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3455bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '\'':
3456bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
34577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3458bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
34597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
3460bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3461bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          last = i + 1;
3462bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3463bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '&':
3464bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
34657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3466bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
34677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          parts->Add(ReplacementPart::SubjectMatch(), zone);
3468bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3469bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          last = i + 1;
3470bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3471bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '0':
3472bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '1':
3473bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '2':
3474bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '3':
3475bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '4':
3476bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '5':
3477bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '6':
3478bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '7':
3479bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '8':
3480bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '9': {
3481bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          int capture_ref = c2 - '0';
3482bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (capture_ref > capture_count) {
3483bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            i = next_index;
3484bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            continue;
3485bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3486bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          int second_digit_index = next_index + 1;
3487bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (second_digit_index < length) {
3488bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            // Peek ahead to see if we have two digits.
3489bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            Char c3 = characters[second_digit_index];
3490bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            if ('0' <= c3 && c3 <= '9') {  // Double digits.
3491bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org              int double_digit_ref = capture_ref * 10 + c3 - '0';
3492bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org              if (double_digit_ref <= capture_count) {
3493bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                next_index = second_digit_index;
3494bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                capture_ref = double_digit_ref;
3495bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org              }
3496bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            }
3497bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3498bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (capture_ref > 0) {
3499bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            if (i > last) {
35007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org              parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3501bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            }
350271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org            ASSERT(capture_ref <= capture_count);
35037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
3504bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            last = next_index + 1;
3505bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3506bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3507bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3508bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3509bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        default:
3510bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3511bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3512bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3513bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3514bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3515bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (length > last) {
3516bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      if (last == 0) {
3517355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // Replacement is simple.  Do not use Apply to do the replacement.
351855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        return true;
3519bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      } else {
35207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
3521bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3522bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
352355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    return false;
3524bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3525bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3526bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ZoneList<ReplacementPart> parts_;
3527bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ZoneList<Handle<String> > replacement_substrings_;
35287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone_;
3529bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org};
3530bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3531bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3532355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgbool CompiledReplacement::Compile(Handle<String> replacement,
3533bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                  int capture_count,
3534bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                  int subject_length) {
3535ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  {
353679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
3537ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    String::FlatContent content = replacement->GetFlatContent();
3538ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    ASSERT(content.IsFlat());
3539355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    bool simple = false;
3540ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (content.IsAscii()) {
3541355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      simple = ParseReplacementPattern(&parts_,
354259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                       content.ToOneByteVector(),
3543355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       capture_count,
3544355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       subject_length,
3545355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       zone());
3546ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    } else {
3547ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      ASSERT(content.IsTwoByte());
3548355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      simple = ParseReplacementPattern(&parts_,
3549355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       content.ToUC16Vector(),
3550355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       capture_count,
3551355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       subject_length,
3552355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       zone());
3553ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    }
3554355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (simple) return true;
3555bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3556355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3557ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = replacement->GetIsolate();
3558c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Find substrings of replacement string and create them as String objects.
3559bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int substring_index = 0;
3560bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  for (int i = 0, n = parts_.length(); i < n; i++) {
3561bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int tag = parts_[i].tag;
3562bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (tag <= 0) {  // A replacement string slice.
3563bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int from = -tag;
3564bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int to = parts_[i].data;
3565ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      replacement_substrings_.Add(
35667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          isolate->factory()->NewSubString(replacement, from, to), zone());
3567bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      parts_[i].tag = REPLACEMENT_SUBSTRING;
3568bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      parts_[i].data = substring_index;
3569bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      substring_index++;
3570bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else if (tag == REPLACEMENT_STRING) {
35717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      replacement_substrings_.Add(replacement, zone());
3572bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      parts_[i].data = substring_index;
3573bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      substring_index++;
3574bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3575bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3576355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  return false;
3577bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3578bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3579bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3580bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgvoid CompiledReplacement::Apply(ReplacementStringBuilder* builder,
3581bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                int match_from,
3582bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                int match_to,
3583355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                int32_t* match) {
3584355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT_LT(0, parts_.length());
3585bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  for (int i = 0, n = parts_.length(); i < n; i++) {
3586bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ReplacementPart part = parts_[i];
3587bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    switch (part.tag) {
3588bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case SUBJECT_PREFIX:
3589bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (match_from > 0) builder->AddSubjectSlice(0, match_from);
3590bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3591bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case SUBJECT_SUFFIX: {
3592bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int subject_length = part.data;
3593bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (match_to < subject_length) {
3594bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          builder->AddSubjectSlice(match_to, subject_length);
3595bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3596bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3597bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3598bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case SUBJECT_CAPTURE: {
3599bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int capture = part.data;
3600355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        int from = match[capture * 2];
3601355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        int to = match[capture * 2 + 1];
3602bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (from >= 0 && to > from) {
3603bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          builder->AddSubjectSlice(from, to);
3604bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3605bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3606bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3607bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case REPLACEMENT_SUBSTRING:
3608bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case REPLACEMENT_STRING:
3609bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        builder->AddString(replacement_substrings_[part.data]);
3610bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3611bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      default:
3612bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        UNREACHABLE();
3613bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3614bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3615bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3616bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3617bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
361859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid FindAsciiStringIndices(Vector<const uint8_t> subject,
361955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            char pattern,
362055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            ZoneList<int>* indices,
36217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            unsigned int limit,
36227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            Zone* zone) {
362355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(limit > 0);
362455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Collect indices of pattern in subject using memchr.
362555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Stop after finding at most limit values.
362659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const uint8_t* subject_start = subject.start();
362759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const uint8_t* subject_end = subject_start + subject.length();
362859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const uint8_t* pos = subject_start;
362955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  while (limit > 0) {
363059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    pos = reinterpret_cast<const uint8_t*>(
363155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        memchr(pos, pattern, subject_end - pos));
363255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (pos == NULL) return;
36337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    indices->Add(static_cast<int>(pos - subject_start), zone);
363455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    pos++;
363555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    limit--;
363655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
363755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
363855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
363955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
364049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgvoid FindTwoByteStringIndices(const Vector<const uc16> subject,
364149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              uc16 pattern,
364249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              ZoneList<int>* indices,
364349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              unsigned int limit,
364449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              Zone* zone) {
364549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  ASSERT(limit > 0);
364649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  const uc16* subject_start = subject.start();
364749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  const uc16* subject_end = subject_start + subject.length();
364849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
364949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    if (*pos == pattern) {
365049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      indices->Add(static_cast<int>(pos - subject_start), zone);
365149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      limit--;
365249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
365349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
365449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
365549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
365649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
365755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgtemplate <typename SubjectChar, typename PatternChar>
365855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgvoid FindStringIndices(Isolate* isolate,
365955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       Vector<const SubjectChar> subject,
366055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       Vector<const PatternChar> pattern,
366155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       ZoneList<int>* indices,
36627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       unsigned int limit,
36637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       Zone* zone) {
366455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(limit > 0);
366555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Collect indices of pattern in subject.
366655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Stop after finding at most limit values.
366755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int pattern_length = pattern.length();
366855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int index = 0;
366955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
367055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  while (limit > 0) {
367155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    index = search.Search(subject, index);
367255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (index < 0) return;
36737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    indices->Add(index, zone);
367455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    index += pattern_length;
367555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    limit--;
367655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
367755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
367855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
367955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
368055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgvoid FindStringIndicesDispatch(Isolate* isolate,
368155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                               String* subject,
368255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                               String* pattern,
368355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                               ZoneList<int>* indices,
36847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                               unsigned int limit,
36857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                               Zone* zone) {
368655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  {
368779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
368855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    String::FlatContent subject_content = subject->GetFlatContent();
368955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    String::FlatContent pattern_content = pattern->GetFlatContent();
369055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    ASSERT(subject_content.IsFlat());
369155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    ASSERT(pattern_content.IsFlat());
369255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (subject_content.IsAscii()) {
369359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
369455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      if (pattern_content.IsAscii()) {
369559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        Vector<const uint8_t> pattern_vector =
369659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            pattern_content.ToOneByteVector();
369755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        if (pattern_vector.length() == 1) {
369855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org          FindAsciiStringIndices(subject_vector,
369955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                                 pattern_vector[0],
370055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                                 indices,
37017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                 limit,
37027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                 zone);
370355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        } else {
370455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org          FindStringIndices(isolate,
370555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            subject_vector,
370655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            pattern_vector,
370755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            indices,
37087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            limit,
37097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            zone);
371055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        }
371155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      } else {
371255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        FindStringIndices(isolate,
371355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          subject_vector,
371455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          pattern_content.ToUC16Vector(),
371555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          indices,
37167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                          limit,
37177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                          zone);
371855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      }
371955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    } else {
372055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (pattern_content.IsAscii()) {
372259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        Vector<const uint8_t> pattern_vector =
372359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            pattern_content.ToOneByteVector();
372449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        if (pattern_vector.length() == 1) {
372549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindTwoByteStringIndices(subject_vector,
372649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   pattern_vector[0],
372749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   indices,
372849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   limit,
372949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   zone);
373049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        } else {
373149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindStringIndices(isolate,
373249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            subject_vector,
373349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            pattern_vector,
373449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            indices,
373549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            limit,
373649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            zone);
373749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        }
373855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      } else {
373949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
374049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        if (pattern_vector.length() == 1) {
374149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindTwoByteStringIndices(subject_vector,
374249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   pattern_vector[0],
374349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   indices,
374449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   limit,
374549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   zone);
374649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        } else {
374749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindStringIndices(isolate,
374849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            subject_vector,
374949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            pattern_vector,
375049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            indices,
375149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            limit,
375249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            zone);
375349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        }
375455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      }
375555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
375655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
375755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
375855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
375955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
376055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgtemplate<typename ResultSeqString>
37618432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgMUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
376255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    Isolate* isolate,
376355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    Handle<String> subject,
376455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    Handle<JSRegExp> pattern_regexp,
3765efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    Handle<String> replacement,
3766355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSArray> last_match_info) {
376755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(subject->IsFlat());
376855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(replacement->IsFlat());
376955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3770c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
3771c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneList<int> indices(8, zone_scope.zone());
377255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
377355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  String* pattern =
377455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
377555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int subject_len = subject->length();
377655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int pattern_len = pattern->length();
377755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int replacement_len = replacement->length();
377855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3779355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  FindStringIndicesDispatch(
3780c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
378155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
378255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int matches = indices.length();
37838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (matches == 0) return *subject;
378455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3785400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  // Detect integer overflow.
3786400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  int64_t result_len_64 =
3787400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      (static_cast<int64_t>(replacement_len) -
3788400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org       static_cast<int64_t>(pattern_len)) *
3789400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      static_cast<int64_t>(matches) +
3790400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      static_cast<int64_t>(subject_len);
379159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (result_len_64 > INT_MAX) return Failure::OutOfMemoryException(0x11);
3792400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  int result_len = static_cast<int>(result_len_64);
3793400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org
379455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int subject_pos = 0;
379555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int result_pos = 0;
379655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
379755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  Handle<ResultSeqString> result;
379855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  if (ResultSeqString::kHasAsciiEncoding) {
379955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    result = Handle<ResultSeqString>::cast(
3800fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        isolate->factory()->NewRawOneByteString(result_len));
380155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  } else {
380255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    result = Handle<ResultSeqString>::cast(
380355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        isolate->factory()->NewRawTwoByteString(result_len));
380455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
380555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
380655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  for (int i = 0; i < matches; i++) {
380755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    // Copy non-matched subject content.
380855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (subject_pos < indices.at(i)) {
380955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      String::WriteToFlat(*subject,
381055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          result->GetChars() + result_pos,
381155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          subject_pos,
381255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          indices.at(i));
381355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      result_pos += indices.at(i) - subject_pos;
381455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
381555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
381655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    // Replace match.
381755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (replacement_len > 0) {
381855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      String::WriteToFlat(*replacement,
381955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          result->GetChars() + result_pos,
382055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          0,
382155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          replacement_len);
382255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      result_pos += replacement_len;
382355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
382455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
382555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    subject_pos = indices.at(i) + pattern_len;
382655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
382755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Add remaining subject content at the end.
382855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  if (subject_pos < subject_len) {
382955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    String::WriteToFlat(*subject,
383055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                        result->GetChars() + result_pos,
383155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                        subject_pos,
383255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                        subject_len);
383355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
3834efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
3835355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int32_t match_indices[] = { indices.at(matches - 1),
3836355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                              indices.at(matches - 1) + pattern_len };
3837355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
3838efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
383955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  return *result;
384055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
384155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3842bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
38438432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgMUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
3844ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
3845355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> subject,
3846355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSRegExp> regexp,
3847355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> replacement,
3848355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSArray> last_match_info) {
3849bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(subject->IsFlat());
3850bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(replacement->IsFlat());
3851bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3852355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int capture_count = regexp->CaptureCount();
3853355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int subject_length = subject->length();
3854bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3855bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // CompiledReplacement uses zone allocation.
3856c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
3857c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  CompiledReplacement compiled_replacement(zone_scope.zone());
3858355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool simple_replace = compiled_replacement.Compile(replacement,
3859355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                     capture_count,
3860355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                     subject_length);
3861bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
386255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Shortcut for simple non-regexp global replacements
38638432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
3864f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (subject->HasOnlyOneByteChars() &&
3865f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        replacement->HasOnlyOneByteChars()) {
38668432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
3867355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, replacement, last_match_info);
3868355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else {
38698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
3870355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, replacement, last_match_info);
387155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
387255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
387355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
38748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
3875355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (global_cache.HasException()) return Failure::Exception();
3876355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3877355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int32_t* current_match = global_cache.FetchNext();
3878355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (current_match == NULL) {
3879355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (global_cache.HasException()) return Failure::Exception();
38808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    return *subject;
3881355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
3882355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3883bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Guessing the number of parts that the final result string is built
3884bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // from. Global regexps can match any number of times, so we guess
3885bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // conservatively.
38868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
3887ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ReplacementStringBuilder builder(isolate->heap(),
3888355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                   subject,
3889ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                   expected_parts);
3890bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
38916141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // Number of parts added by compiled replacement plus preceeding
38926141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // string and possibly suffix after last match.  It is possible for
38936141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // all components to use two elements when encoded as two smis.
38946141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
3895355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3896355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int prev = 0;
3897355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3898bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  do {
3899bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    builder.EnsureCapacity(parts_added_per_loop);
3900bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3901355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int start = current_match[0];
3902355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int end = current_match[1];
3903bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3904bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (prev < start) {
3905bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      builder.AddSubjectSlice(prev, start);
3906bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3907471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
3908355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (simple_replace) {
3909355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      builder.AddString(replacement);
3910355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else {
3911355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      compiled_replacement.Apply(&builder,
3912355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                 start,
3913355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                 end,
3914355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                 current_match);
3915355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
3916bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    prev = end;
3917bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3918355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    current_match = global_cache.FetchNext();
3919355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  } while (current_match != NULL);
3920bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3921355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (global_cache.HasException()) return Failure::Exception();
3922bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3923355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (prev < subject_length) {
3924355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    builder.EnsureCapacity(2);
3925355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    builder.AddSubjectSlice(prev, subject_length);
3926bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3927bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3928355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(last_match_info,
3929355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               subject,
3930355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               capture_count,
3931355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               global_cache.LastSuccessfulMatch());
3932355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3933bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return *(builder.ToString());
3934bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3935bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3936bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
39374a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.comtemplate <typename ResultSeqString>
39388432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgMUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
3939ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
3940355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> subject,
3941355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSRegExp> regexp,
3942355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSArray> last_match_info) {
39434a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  ASSERT(subject->IsFlat());
39444a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
394555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Shortcut for simple non-regexp global replacements
39468432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (regexp->TypeTag() == JSRegExp::ATOM) {
3947fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Handle<String> empty_string = isolate->factory()->empty_string();
394859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (subject->IsOneByteRepresentation()) {
39498432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
39508432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org          isolate, subject, regexp, empty_string, last_match_info);
395155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    } else {
39528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
39538432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org          isolate, subject, regexp, empty_string, last_match_info);
395455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
395555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
395655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
39578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
3958355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (global_cache.HasException()) return Failure::Exception();
395908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
3960355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int32_t* current_match = global_cache.FetchNext();
3961355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (current_match == NULL) {
3962355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (global_cache.HasException()) return Failure::Exception();
39638432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    return *subject;
39644a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
39654a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
3966355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int start = current_match[0];
3967355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int end = current_match[1];
3968355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int capture_count = regexp->CaptureCount();
3969355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int subject_length = subject->length();
3970efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
3971355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int new_length = subject_length - (end - start);
3972355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (new_length == 0) return isolate->heap()->empty_string();
3973efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
39744a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  Handle<ResultSeqString> answer;
39754a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  if (ResultSeqString::kHasAsciiEncoding) {
3976ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    answer = Handle<ResultSeqString>::cast(
3977fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        isolate->factory()->NewRawOneByteString(new_length));
39784a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  } else {
3979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    answer = Handle<ResultSeqString>::cast(
3980ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewRawTwoByteString(new_length));
39814a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
39824a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
3983355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int prev = 0;
39844a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int position = 0;
39854a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
39864a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  do {
3987355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    start = current_match[0];
3988355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    end = current_match[1];
39894a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    if (prev < start) {
39904a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      // Add substring subject[prev;start] to answer string.
39918432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
39924a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      position += start - prev;
39934a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    }
39944a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    prev = end;
39954a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
3996355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    current_match = global_cache.FetchNext();
3997355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  } while (current_match != NULL);
3998355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3999355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (global_cache.HasException()) return Failure::Exception();
4000355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4001355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(last_match_info,
4002355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               subject,
4003355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               capture_count,
4004355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               global_cache.LastSuccessfulMatch());
4005355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4006355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (prev < subject_length) {
40074a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    // Add substring subject[prev;length] to answer string.
4008355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    String::WriteToFlat(
4009355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        *subject, answer->GetChars() + position, prev, subject_length);
4010355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    position += subject_length - prev;
40114a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
40124a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
4013355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (position == 0) return isolate->heap()->empty_string();
40144a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40154a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // Shorten string and fill
40164a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int string_size = ResultSeqString::SizeFor(position);
40174a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int allocated_string_size = ResultSeqString::SizeFor(new_length);
40184a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int delta = allocated_string_size - string_size;
40194a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40204a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  answer->set_length(position);
40214a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  if (delta == 0) return *answer;
40224a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40234a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  Address end_of_string = answer->address() + string_size;
4024ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->heap()->CreateFillerObjectAt(end_of_string, delta);
4025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) {
40262efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    MemoryChunk::IncrementLiveBytesFromMutator(answer->address(), -delta);
4027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
40284a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40294a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  return *answer;
40304a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com}
40314a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40324a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40338432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) {
4034355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  HandleScope scope(isolate);
40356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 4);
4036471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
4037355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4038355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
4039355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4040355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
4041355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
40428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  ASSERT(regexp->GetFlags().is_global());
4043d922884ea003c46279731a1528135f57788e9128yangguo@chromium.org
40448432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (!subject->IsFlat()) subject = FlattenGetString(subject);
4045bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
40464a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  if (replacement->length() == 0) {
4047f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (subject->HasOnlyOneByteChars()) {
40488432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
4049355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, last_match_info);
40504a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    } else {
40518432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
4052355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, last_match_info);
40534a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    }
40544a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
40554a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
40568432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (!replacement->IsFlat()) replacement = FlattenGetString(replacement);
40578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
40588432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  return StringReplaceGlobalRegExpWithString(
4059355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      isolate, subject, regexp, replacement, last_match_info);
4060bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
4061bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4062bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4063de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
4064de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                              Handle<String> subject,
4065de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                              Handle<String> search,
4066de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                              Handle<String> replace,
4067de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                              bool* found,
4068de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                              int recursion_limit) {
40692efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (recursion_limit == 0) return Handle<String>::null();
40702efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (subject->IsConsString()) {
40712efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    ConsString* cons = ConsString::cast(*subject);
40722efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> first = Handle<String>(cons->first());
40732efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> second = Handle<String>(cons->second());
40742efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> new_first =
40752efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        StringReplaceOneCharWithString(isolate,
40762efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       first,
40772efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       search,
40782efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       replace,
40792efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       found,
40802efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       recursion_limit - 1);
40812efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (*found) return isolate->factory()->NewConsString(new_first, second);
40822efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (new_first.is_null()) return new_first;
40832efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
40842efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> new_second =
40852efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        StringReplaceOneCharWithString(isolate,
40862efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       second,
40872efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       search,
40882efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       replace,
40892efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       found,
40902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                                       recursion_limit - 1);
40912efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (*found) return isolate->factory()->NewConsString(first, new_second);
40922efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (new_second.is_null()) return new_second;
40932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
40942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    return subject;
40952efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  } else {
4096de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    int index = Runtime::StringMatch(isolate, subject, search, 0);
40972efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (index == -1) return subject;
40982efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    *found = true;
40992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
41002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
41012efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> second =
41022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        isolate->factory()->NewSubString(subject, index + 1, subject->length());
41032efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    return isolate->factory()->NewConsString(cons1, second);
41042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  }
41052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org}
41062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
41072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
41082efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
41092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  HandleScope scope(isolate);
41106e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 3);
4111f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4112f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
4113f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
41142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
41152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // If the cons string tree is too deep, we simply abort the recursion and
41162efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // retry with a flattened subject string.
41172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  const int kRecursionLimit = 0x1000;
41182efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  bool found = false;
4119de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  Handle<String> result = StringReplaceOneCharWithString(isolate,
4120de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                                         subject,
4121de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                                         search,
4122de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                                         replace,
4123de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                                         &found,
4124de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                                         kRecursionLimit);
41252efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (!result.is_null()) return *result;
4126de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  return *StringReplaceOneCharWithString(isolate,
4127de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                         FlattenGetString(subject),
4128de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                         search,
4129de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                         replace,
4130de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                         &found,
4131de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org                                         kRecursionLimit);
41322efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org}
41332efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
41342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
41357c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org// Perform string match of pattern on subject, starting at start index.
41367c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org// Caller must ensure that 0 <= start_index <= sub->length(),
4137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// and should check that pat->length() + start_index <= sub->length().
4138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint Runtime::StringMatch(Isolate* isolate,
4139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                         Handle<String> sub,
41407c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                         Handle<String> pat,
41417c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                         int start_index) {
41427c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  ASSERT(0 <= start_index);
4143bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(start_index <= sub->length());
41447c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
4145c3e50d815532238589ae8c2f65b6467e4adae811ager@chromium.org  int pattern_length = pat->length();
41467c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  if (pattern_length == 0) return start_index;
41477c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
4148bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int subject_length = sub->length();
41497c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  if (start_index + pattern_length > subject_length) return -1;
41507c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
4151d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (!sub->IsFlat()) FlattenString(sub);
4152d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (!pat->IsFlat()) FlattenString(pat);
41537c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
415479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
415532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  // Extract flattened substrings of cons strings before determining asciiness.
4156ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent seq_sub = sub->GetFlatContent();
4157ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent seq_pat = pat->GetFlatContent();
415832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
41597c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // dispatch on type of strings
4160ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (seq_pat.IsAscii()) {
416159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
4162ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (seq_sub.IsAscii()) {
4163ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return SearchString(isolate,
416459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                          seq_sub.ToOneByteVector(),
4165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                          pat_vector,
4166ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                          start_index);
416743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
4168ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return SearchString(isolate,
4169ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                        seq_sub.ToUC16Vector(),
4170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        pat_vector,
4171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        start_index);
417243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4173ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
4174ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (seq_sub.IsAscii()) {
4175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return SearchString(isolate,
417659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                        seq_sub.ToOneByteVector(),
4177ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        pat_vector,
4178ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        start_index);
41797c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
4180ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return SearchString(isolate,
4181ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                      seq_sub.ToUC16Vector(),
4182ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                      pat_vector,
4183ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                      start_index);
418441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org}
418541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
418641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
4187c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) {
41886e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
418941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  ASSERT(args.length() == 3);
419041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
4191f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4192f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
41937c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
419441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  Object* index = args[2];
419541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  uint32_t start_index;
419630ce411529579186181838984710b0b0980857aaricow@chromium.org  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
419741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
4198870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
4199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int position =
4200ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Runtime::StringMatch(isolate, sub, pat, start_index);
42017c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  return Smi::FromInt(position);
420243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
420343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
420443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4205b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgtemplate <typename schar, typename pchar>
42062ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.orgstatic int StringMatchBackwards(Vector<const schar> subject,
42072ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org                                Vector<const pchar> pattern,
4208b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                int idx) {
42092ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  int pattern_length = pattern.length();
42102ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  ASSERT(pattern_length >= 1);
42112ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  ASSERT(idx + pattern_length <= subject.length());
4212b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4213b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
42142ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    for (int i = 0; i < pattern_length; i++) {
42152ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org      uc16 c = pattern[i];
421659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (c > String::kMaxOneByteCharCode) {
4217b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org        return -1;
4218b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      }
4219b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4220b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4221b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
42222ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  pchar pattern_first_char = pattern[0];
4223b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  for (int i = idx; i >= 0; i--) {
42242ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    if (subject[i] != pattern_first_char) continue;
4225b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    int j = 1;
42262ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    while (j < pattern_length) {
42272ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org      if (pattern[j] != subject[i+j]) {
4228b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org        break;
4229b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      }
4230b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      j++;
4231b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
42322ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    if (j == pattern_length) {
4233b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      return i;
4234b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4235b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4236b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  return -1;
4237b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org}
4238b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4239e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
4240c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
42416e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
424243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
424343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4244f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4245f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
424643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4247b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  Object* index = args[2];
424843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t start_index;
424930ce411529579186181838984710b0b0980857aaricow@chromium.org  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
425043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4251b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  uint32_t pat_length = pat->length();
4252bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  uint32_t sub_length = sub->length();
425343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4254b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  if (start_index + pat_length > sub_length) {
4255b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    start_index = sub_length - pat_length;
4256bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  }
425743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4258b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  if (pat_length == 0) {
4259b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    return Smi::FromInt(start_index);
4260b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4261b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4262d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (!sub->IsFlat()) FlattenString(sub);
4263d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (!pat->IsFlat()) FlattenString(pat);
4264b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4265ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  int position = -1;
426679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4267b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4268ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent sub_content = sub->GetFlatContent();
4269ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent pat_content = pat->GetFlatContent();
4270b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4271ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (pat_content.IsAscii()) {
427259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
4273ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (sub_content.IsAscii()) {
427459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      position = StringMatchBackwards(sub_content.ToOneByteVector(),
4275b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4276b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4277b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    } else {
4278ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      position = StringMatchBackwards(sub_content.ToUC16Vector(),
4279b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4280b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4281b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4282b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  } else {
4283ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
4284ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (sub_content.IsAscii()) {
428559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      position = StringMatchBackwards(sub_content.ToOneByteVector(),
4286b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4287b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4288b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    } else {
4289ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      position = StringMatchBackwards(sub_content.ToUC16Vector(),
4290b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4291b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4292b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4293b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4294b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4295b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  return Smi::FromInt(position);
429643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
429743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
429843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4299c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
430079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
430143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
430243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4303f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, str1, 0);
4304f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, str2, 1);
430543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
430643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (str1 == str2) return Smi::FromInt(0);  // Equal.
4307bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int str1_length = str1->length();
4308bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int str2_length = str2->length();
430943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
431043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Decide trivial cases without flattening.
431143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (str1_length == 0) {
431243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (str2_length == 0) return Smi::FromInt(0);  // Equal.
431343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Smi::FromInt(-str2_length);
431443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
431543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (str2_length == 0) return Smi::FromInt(str1_length);
431643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
431743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
431843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int end = str1_length < str2_length ? str1_length : str2_length;
431943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
432043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No need to flatten if we are going to find the answer on the first
432143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // character.  At this point we know there is at least one character
432243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in each string, due to the trivial case handling above.
4323bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int d = str1->Get(0) - str2->Get(0);
432443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (d != 0) return Smi::FromInt(d);
432543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4326ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  str1->TryFlatten();
4327ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  str2->TryFlatten();
432843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ConsStringIteratorOp* op1 =
43304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      isolate->runtime_state()->string_locale_compare_it1();
43314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ConsStringIteratorOp* op2 =
43324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      isolate->runtime_state()->string_locale_compare_it2();
43334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  // TODO(dcarney) Can do array compares here more efficiently.
43344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream1(str1, op1);
43354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream2(str2, op2);
433643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
433743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < end; i++) {
43384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t char1 = stream1.GetNext();
43394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t char2 = stream2.GetNext();
434043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (char1 != char2) return Smi::FromInt(char1 - char2);
434143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
434243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
434343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(str1_length - str2_length);
434443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
434543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
434643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4347c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
434879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
434943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
435043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4351f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, value, 0);
43526141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  int start, end;
43536141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // We have a fast integer-only case here to avoid a conversion to double in
43546141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // the common case where from and to are Smis.
43556d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (args[1]->IsSmi() && args[2]->IsSmi()) {
43566d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_SMI_ARG_CHECKED(from_number, 1);
43576d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_SMI_ARG_CHECKED(to_number, 2);
43586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    start = from_number;
43596d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    end = to_number;
43606141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  } else {
43616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
43626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
4363ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    start = FastD2IChecked(from_number);
4364ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    end = FastD2IChecked(to_number);
43656141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
436643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(end >= start);
436743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(start >= 0);
4368c3e50d815532238589ae8c2f65b6467e4adae811ager@chromium.org  RUNTIME_ASSERT(end <= value->length());
4369ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->sub_string_runtime()->Increment();
43702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (end - start == 1) {
43712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org     return isolate->heap()->LookupSingleCharacterStringFromCode(
43722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org         value->Get(start));
43732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4374c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  return value->SubString(start, end);
437543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
437643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
437743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4378c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
43796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope handles(isolate);
438041826e77311db718135ef6517b846933dfd275f3ager@chromium.org  ASSERT_EQ(3, args.length());
438141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
4382f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4383f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4384f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
438541826e77311db718135ef6517b846933dfd275f3ager@chromium.org
4386355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4387355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (global_cache.HasException()) return Failure::Exception();
4388471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
4389355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int capture_count = regexp->CaptureCount();
4390d922884ea003c46279731a1528135f57788e9128yangguo@chromium.org
4391c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
4392c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneList<int> offsets(8, zone_scope.zone());
4393355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4394355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  while (true) {
4395355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int32_t* match = global_cache.FetchNext();
4396355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (match == NULL) break;
4397c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    offsets.Add(match[0], zone_scope.zone());  // start
4398c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    offsets.Add(match[1], zone_scope.zone());  // end
4399355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
4400355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4401355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (global_cache.HasException()) return Failure::Exception();
4402355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4403355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (offsets.length() == 0) {
4404355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // Not a single match.
4405355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    return isolate->heap()->null_value();
4406355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
4407355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4408355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(regexp_info,
4409355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               subject,
4410355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               capture_count,
4411355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               global_cache.LastSuccessfulMatch());
4412355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
441341826e77311db718135ef6517b846933dfd275f3ager@chromium.org  int matches = offsets.length() / 2;
4414ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
4415355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Handle<String> substring =
4416355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
441704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  elements->set(0, *substring);
4418355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  for (int i = 1; i < matches; i++) {
4419355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    HandleScope temp_scope(isolate);
442041826e77311db718135ef6517b846933dfd275f3ager@chromium.org    int from = offsets.at(i * 2);
442141826e77311db718135ef6517b846933dfd275f3ager@chromium.org    int to = offsets.at(i * 2 + 1);
4422355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> substring =
4423355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        isolate->factory()->NewProperSubString(subject, from, to);
442404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    elements->set(i, *substring);
442541826e77311db718135ef6517b846933dfd275f3ager@chromium.org  }
4426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
442741826e77311db718135ef6517b846933dfd275f3ager@chromium.org  result->set_length(Smi::FromInt(matches));
442841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  return *result;
442941826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
443041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
443141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
443208eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
443308eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org// separate last match info.  See comment on that function.
4434355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgtemplate<bool has_capture>
443578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.orgstatic MaybeObject* SearchRegExpMultiple(
443608eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Isolate* isolate,
443708eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Handle<String> subject,
443808eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Handle<JSRegExp> regexp,
443908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Handle<JSArray> last_match_array,
444078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    Handle<JSArray> result_array) {
444108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  ASSERT(subject->IsFlat());
4442355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
444308eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
444408eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  int capture_count = regexp->CaptureCount();
444508eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  int subject_length = subject->length();
444608eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
444778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  static const int kMinLengthToCache = 0x1000;
444878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
444978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (subject_length > kMinLengthToCache) {
445078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    Handle<Object> cached_answer(RegExpResultsCache::Lookup(
445178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        isolate->heap(),
445278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        *subject,
445378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        regexp->data(),
445409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
445578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (*cached_answer != Smi::FromInt(0)) {
445678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Handle<FixedArray> cached_fixed_array =
445778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          Handle<FixedArray>(FixedArray::cast(*cached_answer));
445878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // The cache FixedArray is a COW-array and can therefore be reused.
445978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      isolate->factory()->SetContent(result_array, cached_fixed_array);
446078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // The actual length of the result array is stored in the last element of
446178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // the backing store (the backing FixedArray may have a larger capacity).
446278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Object* cached_fixed_array_last_element =
446378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          cached_fixed_array->get(cached_fixed_array->length() - 1);
446478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
446578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      result_array->set_length(js_array_length);
446678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      RegExpImpl::SetLastMatchInfo(
446778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          last_match_array, subject, capture_count, NULL);
446878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      return *result_array;
446978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
447078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
447178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
447278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
447378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (global_cache.HasException()) return Failure::Exception();
447478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
447578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  Handle<FixedArray> result_elements;
447678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (result_array->HasFastObjectElements()) {
447778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    result_elements =
447878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        Handle<FixedArray>(FixedArray::cast(result_array->elements()));
447978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
448078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (result_elements.is_null() || result_elements->length() < 16) {
448178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
448278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
448378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
448478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  FixedArrayBuilder builder(result_elements);
448578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
448608eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  // Position to search from.
4487355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int match_start = -1;
448808eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  int match_end = 0;
448908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  bool first = true;
449008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4491355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Two smis before and after the match, for very long strings.
4492355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  static const int kMaxBuilderEntriesPerRegExpMatch = 5;
4493355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4494355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  while (true) {
4495355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int32_t* current_match = global_cache.FetchNext();
4496355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (current_match == NULL) break;
4497355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    match_start = current_match[0];
449878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
4499355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (match_end < match_start) {
450078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      ReplacementStringBuilder::AddSubjectSlice(&builder,
4501355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                match_end,
4502355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                match_start);
4503355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
4504355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    match_end = current_match[1];
4505355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    {
4506355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // Avoid accumulating new handles inside loop.
4507355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      HandleScope temp_scope(isolate);
4508355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      Handle<String> match;
4509355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (!first) {
4510355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        match = isolate->factory()->NewProperSubString(subject,
4511355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                       match_start,
4512355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                       match_end);
4513355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      } else {
4514355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        match = isolate->factory()->NewSubString(subject,
4515355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                 match_start,
4516355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                 match_end);
451708eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org        first = false;
451808eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org      }
451908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4520355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (has_capture) {
4521355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // Arguments array to replace function is match, captures, index and
4522355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // subject, i.e., 3 + capture count in total.
4523355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        Handle<FixedArray> elements =
4524355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            isolate->factory()->NewFixedArray(3 + capture_count);
4525355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4526355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        elements->set(0, *match);
4527355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        for (int i = 1; i <= capture_count; i++) {
4528355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          int start = current_match[i * 2];
4529355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          if (start >= 0) {
4530355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            int end = current_match[i * 2 + 1];
4531355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            ASSERT(start <= end);
4532355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            Handle<String> substring =
4533355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                isolate->factory()->NewSubString(subject, start, end);
4534355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            elements->set(i, *substring);
4535355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          } else {
4536355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            ASSERT(current_match[i * 2 + 1] < 0);
4537355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            elements->set(i, isolate->heap()->undefined_value());
4538355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          }
453908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org        }
4540355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        elements->set(capture_count + 1, Smi::FromInt(match_start));
4541355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        elements->set(capture_count + 2, *subject);
454278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
4543355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      } else {
454478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        builder.Add(*match);
454508eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org      }
4546355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
4547355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
454808eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
454978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (global_cache.HasException()) return Failure::Exception();
455008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4551355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (match_start >= 0) {
4552355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // Finished matching, with at least one match.
4553355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (match_end < subject_length) {
455478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      ReplacementStringBuilder::AddSubjectSlice(&builder,
4555355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                match_end,
4556355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                subject_length);
455708eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    }
4558355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4559355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    RegExpImpl::SetLastMatchInfo(
4560355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        last_match_array, subject, capture_count, NULL);
4561355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
456278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (subject_length > kMinLengthToCache) {
456378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // Store the length of the result array into the last element of the
456478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // backing FixedArray.
456578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      builder.EnsureCapacity(1);
456678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Handle<FixedArray> fixed_array = builder.array();
456778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      fixed_array->set(fixed_array->length() - 1,
456878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                       Smi::FromInt(builder.length()));
456978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // Cache the result and turn the FixedArray into a COW array.
457078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      RegExpResultsCache::Enter(isolate->heap(),
457178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                *subject,
457278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                regexp->data(),
457378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                *fixed_array,
457478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
457578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
457678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return *builder.ToJSArray(result_array);
4577355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  } else {
457878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return isolate->heap()->null_value();  // No matches at all.
457908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  }
458008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org}
458108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
458208eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4583efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org// This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
4584efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org// lastMatchInfoOverride to maintain the last match info, so we don't need to
4585efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org// set any other last match array info.
4586c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
4587ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handles(isolate);
45886e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 4);
458925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
4590f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
45914668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  if (!subject->IsFlat()) FlattenString(subject);
4592f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
4593f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
4594f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
459525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
459625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(regexp->GetFlags().is_global());
459725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
459825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  if (regexp->CaptureCount() == 0) {
459978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return SearchRegExpMultiple<false>(
460078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        isolate, subject, regexp, last_match_info, result_array);
460125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  } else {
460278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return SearchRegExpMultiple<true>(
460378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        isolate, subject, regexp, last_match_info, result_array);
460425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
460525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
460625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
460725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
4608c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
460979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
461043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
46116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(radix, 1);
4612c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  RUNTIME_ASSERT(2 <= radix && radix <= 36);
461343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4614eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Fast case where the result is a one character string.
4615c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  if (args[0]->IsSmi()) {
46166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int value = args.smi_at(0);
4617eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    if (value >= 0 && value < radix) {
4618eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      // Character array used for conversion.
4619eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
4620ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->heap()->
4621ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          LookupSingleCharacterStringFromCode(kCharTable[value]);
4622eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
4623eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
4624eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4625eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Slow case.
46266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
462777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(value)) {
46284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return *isolate->factory()->nan_string();
462943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
463077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isinf(value)) {
463143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (value < 0) {
46324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return *isolate->factory()->minus_infinity_string();
463343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
46344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return *isolate->factory()->infinity_string();
463543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
463643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToRadixCString(value, radix);
4637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MaybeObject* result =
46388e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
463943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
464043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
464143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
464243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
464343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4644c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
464579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
464643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
464743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
46496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4650ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  int f = FastD2IChecked(f_number);
465143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(f >= 0);
465243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToFixedCString(value, f);
4653ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MaybeObject* res =
46548e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
465543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4656ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return res;
465743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
465843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
465943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4660c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
466179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
466243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
466343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46646d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
46656d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4666ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  int f = FastD2IChecked(f_number);
466743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(f >= -1 && f <= 20);
466843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToExponentialCString(value, f);
4669ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MaybeObject* res =
46708e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
467143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4672ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return res;
467343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
467443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
467543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4676c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
467779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
467843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
467943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
46816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4682ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  int f = FastD2IChecked(f_number);
468343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(f >= 1 && f <= 21);
468443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToPrecisionCString(value, f);
4685ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MaybeObject* res =
46868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
468743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return res;
468943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
469043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
469143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
469243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns a single character string where first character equals
469343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// string->Get(index).
46949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
4695bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (index < static_cast<uint32_t>(string->length())) {
4696ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    string->TryFlatten();
4697870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    return LookupSingleCharacterStringFromCode(
469809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        string->GetIsolate(),
4699bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        string->Get(index));
470043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
47019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return Execution::CharAt(string, index);
470243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
470343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
470443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
470577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgMaybeObject* Runtime::GetElementOrCharAtOrFail(Isolate* isolate,
470677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                                               Handle<Object> object,
470777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org                                               uint32_t index) {
470877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
470977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      GetElementOrCharAt(isolate, object, index));
471077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org}
471177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
471277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
4713ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
4714ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         Handle<Object> object,
4715303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         uint32_t index) {
471643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle [] indexing on Strings
471743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsString()) {
47189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
47199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (!result->IsUndefined()) return *result;
472043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
472143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
472243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle [] indexing on String objects
472343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsStringObjectWithCharacterAt(index)) {
47249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<JSValue> js_value = Handle<JSValue>::cast(object);
47259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> result =
47269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        GetCharAt(Handle<String>(String::cast(js_value->value())), index);
47279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (!result->IsUndefined()) return *result;
472843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
472943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
473043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
47318432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    return object->GetPrototype(isolate)->GetElement(index);
473243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
473343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
473443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return object->GetElement(index);
473543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
473643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
473743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4738e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgMaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
4739e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                        Handle<JSReceiver> object,
4740e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                        Handle<Object> key) {
4741e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  HandleScope scope(isolate);
4742e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4743e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Check if the given key is an array index.
4744e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  uint32_t index;
4745e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (key->ToArrayIndex(&index)) {
4746e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return isolate->heap()->ToBoolean(object->HasElement(index));
4747e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4748e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4749e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Convert the key to a name - possibly by calling back into JavaScript.
4750e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Handle<Name> name;
4751e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (key->IsName()) {
4752e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    name = Handle<Name>::cast(key);
4753e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
4754e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    bool has_pending_exception = false;
4755e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Object> converted =
4756e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        Execution::ToString(key, &has_pending_exception);
4757e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (has_pending_exception) return Failure::Exception();
4758e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    name = Handle<Name>::cast(converted);
4759e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4760e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4761e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return isolate->heap()->ToBoolean(object->HasProperty(*name));
4762e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
4763e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4764b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgMaybeObject* Runtime::GetObjectPropertyOrFail(
4765b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Isolate* isolate,
4766b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Handle<Object> object,
4767b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Handle<Object> key) {
4768b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
4769b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      GetObjectProperty(isolate, object, key));
4770b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
4771e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4772ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
4773ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        Handle<Object> object,
4774303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                        Handle<Object> key) {
4775ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
47769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
477743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsUndefined() || object->IsNull()) {
47789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> args[2] = { key, object };
477943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> error =
4780ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("non_object_property_load",
4781ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         HandleVector(args, 2));
4782ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*error);
478343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
478443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
478543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the given key is an array index.
478643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
478730ce411529579186181838984710b0b0980857aaricow@chromium.org  if (key->ToArrayIndex(&index)) {
4788ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return GetElementOrCharAt(isolate, object, index);
478943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
479043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4791750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Convert the key to a name - possibly by calling back into JavaScript.
4792750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Name> name;
4793750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
4794750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = Handle<Name>::cast(key);
479543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
479643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    bool has_pending_exception = false;
479743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> converted =
47989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        Execution::ToString(key, &has_pending_exception);
479943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (has_pending_exception) return Failure::Exception();
4800750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = Handle<Name>::cast(converted);
480143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
480243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Check if the name is trivially convertible to an index and get
480443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the element if so.
480543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
4806ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return GetElementOrCharAt(isolate, object, index);
480743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
4808d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    return object->GetProperty(*name);
480943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
481043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
481143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
481243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4813c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
481479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
481543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
481643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
481743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> object = args.at<Object>(0);
48189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<Object> key = args.at<Object>(1);
481943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return Runtime::GetObjectProperty(isolate, object, key);
482143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
482243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
482343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4824750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
4825c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
482679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
48277c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  ASSERT(args.length() == 2);
48287c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
48295a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Fast cases for getting named properties of the receiver JSObject
48308bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // itself.
48318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  //
48328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // The global proxy objects has to be excluded since LocalLookup on
48333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // the global proxy object can return a valid result even though the
48348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // global proxy object never has properties.  This is the case
48358bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // because the global proxy object forwards everything to its hidden
48368bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // prototype including local lookups.
48378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  //
48388bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // Additionally, we need to make sure that we do not cache results
48398bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // for objects that require access checks.
4840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (args[0]->IsJSObject()) {
4841c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (!args[0]->IsJSGlobalProxy() &&
4842c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        !args[0]->IsAccessCheckNeeded() &&
4843750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        args[1]->IsName()) {
4844c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      JSObject* receiver = JSObject::cast(args[0]);
4845750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      Name* key = Name::cast(args[1]);
4846c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (receiver->HasFastProperties()) {
4847c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Attempt to use lookup cache.
4848c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        Map* receiver_map = receiver->map();
4849c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
4850c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int offset = keyed_lookup_cache->Lookup(receiver_map, key);
4851c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (offset != -1) {
485257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          // Doubles are not cached, so raw read the value.
485357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          Object* value = receiver->RawFastPropertyAt(offset);
4854c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          return value->IsTheHole()
4855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              ? isolate->heap()->undefined_value()
4856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              : value;
4857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
4858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Lookup cache miss.  Perform lookup and update the cache if
4859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // appropriate.
4860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        LookupResult result(isolate);
4861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        receiver->LocalLookup(key, &result);
4862de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org        if (result.IsField()) {
4863eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org          int offset = result.GetFieldIndex().field_index();
486457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          // Do not track double fields in the keyed lookup cache. Reading
486557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          // double values requires boxing.
486657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          if (!FLAG_track_double_fields ||
486757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org              !result.representation().IsDouble()) {
486857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            keyed_lookup_cache->Update(receiver_map, key, offset);
486957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          }
487057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          return receiver->FastPropertyAt(result.representation(), offset);
4871c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
4872c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      } else {
4873c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Attempt dictionary lookup.
4874750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        NameDictionary* dictionary = receiver->property_dictionary();
4875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int entry = dictionary->FindEntry(key);
4876750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        if ((entry != NameDictionary::kNotFound) &&
4877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            (dictionary->DetailsAt(entry).type() == NORMAL)) {
4878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          Object* value = dictionary->ValueAt(entry);
4879c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (!receiver->IsGlobalObject()) return value;
4880b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          value = PropertyCell::cast(value)->value();
4881c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (!value->IsTheHole()) return value;
4882c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // If value is the hole do the general lookup.
4883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
48845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
4885c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
4886750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      // JSObject without a name key. If the key is a Smi, check for a
4887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // definite out-of-bounds access to elements, which is a strong indicator
4888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // that subsequent accesses will also call the runtime. Proactively
4889830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
4890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // doubles for those future calls in the case that the elements would
4891c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // become FAST_DOUBLE_ELEMENTS.
4892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<JSObject> js_object(args.at<JSObject>(0));
4893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ElementsKind elements_kind = js_object->GetElementsKind();
4894fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (IsFastDoubleElementsKind(elements_kind)) {
4895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        FixedArrayBase* elements = js_object->elements();
4896c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (args.at<Smi>(1)->value() >= elements->length()) {
4897830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          if (IsFastHoleyElementsKind(elements_kind)) {
4898830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            elements_kind = FAST_HOLEY_ELEMENTS;
4899830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          } else {
4900830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            elements_kind = FAST_ELEMENTS;
4901830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          }
4902c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          MaybeObject* maybe_object = TransitionElements(js_object,
4903830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                                                         elements_kind,
4904c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                         isolate);
4905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (maybe_object->IsFailure()) return maybe_object;
4906c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
4907fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      } else {
4908fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4909fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org               !IsFastElementsKind(elements_kind));
49105a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
49117c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    }
49120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  } else if (args[0]->IsString() && args[1]->IsSmi()) {
49130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    // Fast case for string indexing using [] with a smi index.
4914ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
49150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    Handle<String> str = args.at<String>(0);
49166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int index = args.smi_at(1);
491783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    if (index >= 0 && index < str->length()) {
491883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      Handle<Object> result = GetCharAt(str, index);
491983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      return *result;
492083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
49217c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
49225a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
49235a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Fall back to GetObjectProperty.
4924ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return Runtime::GetObjectProperty(isolate,
4925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                    args.at<Object>(0),
49267c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                                    args.at<Object>(1));
49277c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org}
49287c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
4929bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4930bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comstatic bool IsValidAccessor(Handle<Object> obj) {
4931bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
4932bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
4933bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
4934bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
493583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Implements part of 8.12.9 DefineOwnProperty.
493683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// There are 3 cases that lead here:
493783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 4b - define a new accessor property.
493883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Steps 9c & 12 - replace an existing data property with an accessor property.
493983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 12 - update an existing accessor property with an accessor or generic
494083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org//           descriptor.
4941c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
4942ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
49436e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 5);
4944f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
4945bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  RUNTIME_ASSERT(!obj->IsNull());
4946750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4947bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4948bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  RUNTIME_ASSERT(IsValidAccessor(getter));
4949bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4950bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  RUNTIME_ASSERT(IsValidAccessor(setter));
4951f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(unchecked, 4);
49525c838251403b0be9a882540f1922577abba4c872ager@chromium.org  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
49535c838251403b0be9a882540f1922577abba4c872ager@chromium.org  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
49547ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
495588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  bool fast = obj->HasFastProperties();
495688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  JSObject::DefineAccessor(obj, name, getter, setter, attr);
4957169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
495888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  if (fast) JSObject::TransformToFastProperties(obj, 0);
4959bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return isolate->heap()->undefined_value();
49605c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
49615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4962e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
496383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Implements part of 8.12.9 DefineOwnProperty.
496483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// There are 3 cases that lead here:
496583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 4a - define a new data property.
496683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Steps 9b & 12 - replace an existing accessor property with a data property.
496783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 12 - update an existing data property with a data or generic
496883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org//           descriptor.
4969c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
4970ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
49716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 4);
4972f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
4973750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4974bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
4975f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(unchecked, 3);
49765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
49772c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
49782c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
4979394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult result(isolate);
49807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  js_object->LocalLookupRealNamedProperty(*name, &result);
49815c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4982e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org  // Special case for callback properties.
4983753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (result.IsPropertyCallbacks()) {
4984e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    Object* callback = result.GetCallbackObject();
4985e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // To be compatible with Safari we do not change the value on API objects
4986e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // in Object.defineProperty(). Firefox disagrees here, and actually changes
4987e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // the value.
4988e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    if (callback->IsAccessorInfo()) {
4989e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org      return isolate->heap()->undefined_value();
4990e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    }
4991e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // Avoid redefining foreign callback as data property, just use the stored
4992e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // setter to update the value instead.
4993e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // TODO(mstarzinger): So far this only works if property attributes don't
4994e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    // change, this should be fixed once we cleanup the underlying code.
4995e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    if (callback->IsForeign() && result.GetAttributes() == attr) {
4996e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org      return js_object->SetPropertyWithCallback(callback,
4997e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org                                                *name,
4998e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org                                                *obj_value,
4999e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org                                                result.holder(),
5000e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org                                                kStrictMode);
5001e78f9fcf40d01605c74cacb606ccabae36ba46bddanno@chromium.org    }
5002f5a18a2b51aa9fa5f65d297d3a7c2719a9eeaf44ricow@chromium.org  }
5003f5a18a2b51aa9fa5f65d297d3a7c2719a9eeaf44ricow@chromium.org
50045c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Take special care when attributes are different and there is already
50055c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // a property. For simplicity we normalize the property which enables us
50065c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // to not worry about changing the instance_descriptor and creating a new
50075c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // map. The current version of SetObjectProperty does not handle attributes
50085c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // correctly in the case where a property is a field and is reset with
50095c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // new attributes.
5010753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (result.IsFound() &&
501199aa490225c81012235659d9a183226b286178c8yangguo@chromium.org      (attr != result.GetAttributes() || result.IsPropertyCallbacks())) {
50125c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // New attributes - normalize to avoid writing to instance descriptor
5013d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    if (js_object->IsJSGlobalProxy()) {
5014d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      // Since the result is a property, the prototype will exist so
5015d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      // we don't have to check for null.
5016d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
501783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
5018f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
50195c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Use IgnoreAttributes version since a readonly property may be
50205c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // overridden and SetProperty does not allow this.
5021d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    return js_object->SetLocalPropertyIgnoreAttributes(*name,
5022d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                       *obj_value,
5023d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org                                                       attr);
50245c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
50252c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
5026ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return Runtime::ForceSetObjectProperty(isolate,
5027ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         js_object,
5028ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         name,
5029ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         obj_value,
5030ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         attr);
50315c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
50325c838251403b0be9a882540f1922577abba4c872ager@chromium.org
50335c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5034e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org// Return property without being observable by accessors or interceptors.
5035e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
503679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
5037e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 2);
5038e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5039750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5040e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  LookupResult lookup(isolate);
5041e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  object->LookupRealNamedProperty(*key, &lookup);
5042e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (!lookup.IsFound()) return isolate->heap()->undefined_value();
5043e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  switch (lookup.type()) {
5044e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case NORMAL:
5045e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      return lookup.holder()->GetNormalizedProperty(&lookup);
5046e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case FIELD:
5047eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org      return lookup.holder()->FastPropertyAt(
504857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          lookup.representation(),
5049eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org          lookup.GetFieldIndex().field_index());
5050fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    case CONSTANT:
5051fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      return lookup.GetConstant();
5052e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case CALLBACKS:
5053e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case HANDLER:
5054e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case INTERCEPTOR:
5055e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case TRANSITION:
5056e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      return isolate->heap()->undefined_value();
5057e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case NONEXISTENT:
5058e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      UNREACHABLE();
5059e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
5060e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return isolate->heap()->undefined_value();
5061e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
5062e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
5063e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
5064b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgMaybeObject* Runtime::SetObjectPropertyOrFail(
5065b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Isolate* isolate,
5066b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Handle<Object> object,
5067b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Handle<Object> key,
5068b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    Handle<Object> value,
5069b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    PropertyAttributes attr,
5070b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    StrictModeFlag strict_mode) {
5071b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
5072b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      SetObjectProperty(isolate, object, key, value, attr, strict_mode));
5073b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
5074b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
5075b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
5076ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
5077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        Handle<Object> object,
5078303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                        Handle<Object> key,
5079303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                        Handle<Object> value,
50809ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                                        PropertyAttributes attr,
50818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                        StrictModeFlag strict_mode) {
5082ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
5083ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
50849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
508543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsUndefined() || object->IsNull()) {
50869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> args[2] = { key, object };
508743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> error =
5088ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("non_object_property_store",
5089ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         HandleVector(args, 2));
5090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*error);
509143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
509243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (object->IsJSProxy()) {
5094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bool has_pending_exception = false;
5095750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Object> name = key->IsSymbol()
5096750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        ? key : Execution::ToString(key, &has_pending_exception);
5097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (has_pending_exception) return Failure::Exception();
5098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return JSProxy::cast(*object)->SetProperty(
5099750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        Name::cast(*name), *value, attr, strict_mode);
5100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
510243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the object isn't a JavaScript object, we ignore the store.
510343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!object->IsJSObject()) return *value;
510443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51059a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
51069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
510743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the given key is an array index.
510843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
510930ce411529579186181838984710b0b0980857aaricow@chromium.org  if (key->ToArrayIndex(&index)) {
511043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
511143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // of a string using [] notation.  We need to support this too in
511243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // JavaScript.
511343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // In the case of a String object we just need to redirect the assignment to
511443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // the underlying string if the index is in range.  Since the underlying
511543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // string does nothing with the assignment then we can ignore such
511643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // assignments.
51179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (js_object->IsStringObjectWithCharacterAt(index)) {
511843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return *value;
51199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
512043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5121830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    js_object->ValidateElements();
5122b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (js_object->HasExternalArrayElements()) {
5123b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (!value->IsNumber() && !value->IsUndefined()) {
5124b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        bool has_exception;
5125b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        Handle<Object> number = Execution::ToNumber(value, &has_exception);
5126b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (has_exception) return Failure::Exception();
5127b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        value = number;
5128b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
5129b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
5130b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    MaybeObject* result = js_object->SetElement(
5131b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        index, *value, attr, strict_mode, true, set_mode);
5132830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    js_object->ValidateElements();
5133b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (result->IsFailure()) return result;
513443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
513543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
513643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5137750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
5138b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    MaybeObject* result;
5139750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name = Handle<Name>::cast(key);
5140750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (name->AsArrayIndex(&index)) {
5141b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (js_object->HasExternalArrayElements()) {
5142b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (!value->IsNumber() && !value->IsUndefined()) {
5143b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          bool has_exception;
5144b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          Handle<Object> number = Execution::ToNumber(value, &has_exception);
5145b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          if (has_exception) return Failure::Exception();
5146b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          value = number;
5147b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
5148b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
5149b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      result = js_object->SetElement(
5150b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          index, *value, attr, strict_mode, true, set_mode);
515143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
5152750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5153b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      result = js_object->SetProperty(*name, *value, attr, strict_mode);
515443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
5155b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (result->IsFailure()) return result;
515643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
515743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
515843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
515943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call-back into JavaScript to convert the key to a string.
516043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool has_pending_exception = false;
516143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
516243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (has_pending_exception) return Failure::Exception();
516343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> name = Handle<String>::cast(converted);
516443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
516543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
5166ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    return js_object->SetElement(
5167ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        index, *value, attr, strict_mode, true, set_mode);
516843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
51698f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return js_object->SetProperty(*name, *value, attr, strict_mode);
517043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
517143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
517243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
517343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5174ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
5175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             Handle<JSObject> js_object,
5176303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                             Handle<Object> key,
5177303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                             Handle<Object> value,
5178303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                             PropertyAttributes attr) {
5179ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
518065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
518165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Check if the given key is an array index.
518265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  uint32_t index;
518330ce411529579186181838984710b0b0980857aaricow@chromium.org  if (key->ToArrayIndex(&index)) {
518465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
518565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // of a string using [] notation.  We need to support this too in
518665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // JavaScript.
518765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // In the case of a String object we just need to redirect the assignment to
518865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // the underlying string if the index is in range.  Since the underlying
518965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // string does nothing with the assignment then we can ignore such
519065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // assignments.
519165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    if (js_object->IsStringObjectWithCharacterAt(index)) {
519265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      return *value;
519365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    }
519465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
5195ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    return js_object->SetElement(
5196ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
519765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
519865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
5199750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
5200750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name = Handle<Name>::cast(key);
5201750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (name->AsArrayIndex(&index)) {
5202ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      return js_object->SetElement(
5203ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org          index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
520465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    } else {
5205750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5206750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
520765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    }
520865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
520965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
521065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Call-back into JavaScript to convert the key to a string.
521165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  bool has_pending_exception = false;
521265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
521365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  if (has_pending_exception) return Failure::Exception();
521465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  Handle<String> name = Handle<String>::cast(converted);
521565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
521665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  if (name->AsArrayIndex(&index)) {
5217ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    return js_object->SetElement(
5218ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
521965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  } else {
5220d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
522165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
522265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
522365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
522465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
5225e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgMaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
5226e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                           Handle<JSReceiver> receiver,
5227e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                           Handle<Object> key,
5228e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                           JSReceiver::DeleteMode mode) {
5229ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5230e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5231e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  // Check if the given key is an array index.
5232e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  uint32_t index;
5233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (key->ToArrayIndex(&index)) {
5234e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // In Firefox/SpiderMonkey, Safari and Opera you can access the
5235e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // characters of a string using [] notation.  In the case of a
5236e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // String object we just need to redirect the deletion to the
5237e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // underlying string if the index is in range.  Since the
5238e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // underlying string does nothing with the deletion, we can ignore
5239e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // such deletions.
524084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (receiver->IsStringObjectWithCharacterAt(index)) {
5241ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->heap()->true_value();
5242e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    }
5243e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5244ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<Object> result = JSReceiver::DeleteElement(receiver, index, mode);
5245ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate, result);
5246ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return *result;
5247e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
5248e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Name> name;
5250750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
5251750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = Handle<Name>::cast(key);
5252e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  } else {
5253e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // Call-back into JavaScript to convert the key to a string.
5254e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    bool has_pending_exception = false;
5255e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
5256e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    if (has_pending_exception) return Failure::Exception();
5257750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = Handle<String>::cast(converted);
5258e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
5259e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5260750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5261ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode);
5262ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
5263ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
5264e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org}
5265e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5266e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5267c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
526879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
52699ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
527043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
527143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> object = args.at<Object>(0);
527243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> key = args.at<Object>(1);
527343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> value = args.at<Object>(2);
52746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
52759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(
52769ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
527743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute attributes.
52789ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  PropertyAttributes attributes =
52799ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      static_cast<PropertyAttributes>(unchecked_attributes);
52809ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
52818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  StrictModeFlag strict_mode = kNonStrictMode;
52829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  if (args.length() == 5) {
5283f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
5284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    strict_mode = strict_mode_flag;
528543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
52869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
5287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return Runtime::SetObjectProperty(isolate,
5288ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                    object,
52898f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                    key,
52908f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                    value,
52918f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                    attributes,
52928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                    strict_mode);
529343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
529443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
529543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
529694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) {
529794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HandleScope scope(isolate);
529894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  RUNTIME_ASSERT(args.length() == 2);
529994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
530094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
530194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  JSObject::TransitionElementsKind(array, map->elements_kind());
530294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  return *array;
530394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
530494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
530594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
5306d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org// Set the native flag on the function.
53076fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org// This is used to decide if we should transform null and undefined
53086fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org// into the global object when doing call and apply.
5309d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
531079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
53116fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  RUNTIME_ASSERT(args.length() == 1);
53126fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
53136fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  Handle<Object> object = args.at<Object>(0);
53146fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
53156fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  if (object->IsJSFunction()) {
53166fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org    JSFunction* func = JSFunction::cast(*object);
5317d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    func->shared()->set_native(true);
53186fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  }
53196fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  return isolate->heap()->undefined_value();
53206fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org}
53216fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
53226fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
5323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
53246e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
5325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RUNTIME_ASSERT(args.length() == 5);
5326f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5327c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(store_index, 1);
5328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<Object> value = args.at<Object>(2);
5329f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
5330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
5331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5332bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Object* raw_literal_cell = literals->get(literal_index);
5333bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  JSArray* boilerplate = NULL;
5334bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (raw_literal_cell->IsAllocationSite()) {
5335bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
5336bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    boilerplate = JSArray::cast(site->transition_info());
5337bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else {
5338bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    boilerplate = JSArray::cast(raw_literal_cell);
5339bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
5340bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<JSArray> boilerplate_object(boilerplate);
5341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ElementsKind elements_kind = object->GetElementsKind();
5342830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(IsFastElementsKind(elements_kind));
5343c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Smis should never trigger transitions.
5344c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!value->IsSmi());
5345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5346c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (value->IsNumber()) {
5347830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastSmiElementsKind(elements_kind));
5348830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5349830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        ? FAST_HOLEY_DOUBLE_ELEMENTS
5350830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        : FAST_DOUBLE_ELEMENTS;
5351830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (IsMoreGeneralElementsKindTransition(
5352830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            boilerplate_object->GetElementsKind(),
5353830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            transitioned_kind)) {
5354830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5355830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    }
5356830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    JSObject::TransitionElementsKind(object, transitioned_kind);
5357830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
53587d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
5359c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    HeapNumber* number = HeapNumber::cast(*value);
5360c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    double_array->set(store_index, number->Number());
5361c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
5362830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastSmiElementsKind(elements_kind) ||
5363830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org           IsFastDoubleElementsKind(elements_kind));
5364830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5365830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        ? FAST_HOLEY_ELEMENTS
5366830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        : FAST_ELEMENTS;
5367830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    JSObject::TransitionElementsKind(object, transitioned_kind);
5368830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (IsMoreGeneralElementsKindTransition(
5369830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            boilerplate_object->GetElementsKind(),
5370830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            transitioned_kind)) {
5371830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
53727d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    }
53737d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    FixedArray* object_array = FixedArray::cast(object->elements());
5374c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    object_array->set(store_index, *value);
5375c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5376c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return *object;
5377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5378c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
538088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// Check whether debugger and is about to step into the callback that is passed
538188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// to a built-in function such as Array.forEach.
538288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) {
538379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
538499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
538581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
538681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    return isolate->heap()->false_value();
538781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  }
538888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  CONVERT_ARG_CHECKED(Object, callback, 0);
538988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // We do not step into the callback if it's a builtin or not even a function.
539088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  if (!callback->IsJSFunction() || JSFunction::cast(callback)->IsBuiltin()) {
539188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org    return isolate->heap()->false_value();
539288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  }
539388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  return isolate->heap()->true_value();
539499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#else
539599aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  return isolate->heap()->false_value();
539699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#endif  // ENABLE_DEBUGGER_SUPPORT
539788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org}
539888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
539988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
540088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// Set one shot breakpoints for the callback function that is passed to a
540188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// built-in function such as Array.forEach to enable stepping into the callback.
540288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
540379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
540499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
540588d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  Debug* debug = isolate->debug();
540699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  if (!debug->IsStepping()) return isolate->heap()->undefined_value();
54075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
540888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  HandleScope scope(isolate);
540988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // When leaving the callback, step out has been activated, but not performed
541088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // if we do not leave the builtin.  To be able to step into the callback
541188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // again, we need to clear the step out at this point.
541288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  debug->ClearStepOut();
54135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  debug->FloodWithOneShot(callback);
541499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org#endif  // ENABLE_DEBUGGER_SUPPORT
541599aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  return isolate->heap()->undefined_value();
541688d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org}
541788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
541888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
541943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Set a local property, even if it is READ_ONLY.  If the property does not
542043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// exist, it will be added with attributes NONE.
5421c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
542279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
542341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
5424f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, object, 0);
5425750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_CHECKED(Name, name, 1);
542641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Compute attributes.
542741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  PropertyAttributes attributes = NONE;
542841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  if (args.length() == 4) {
5429f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
543041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    // Only attribute bits should be set.
543141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    RUNTIME_ASSERT(
543241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org        (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
543341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    attributes = static_cast<PropertyAttributes>(unchecked_value);
543441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  }
543543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
543641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  return object->
5437d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
543843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
543943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
544043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5441c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
5442ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  HandleScope scope(isolate);
544349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  ASSERT(args.length() == 3);
5444ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5445ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5446f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
5447ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode)
5448ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
5449ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode);
5450ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
5451ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
545243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
545343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
545443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5455169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgstatic MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
5456169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                                                   Handle<JSObject> object,
5457169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                                                   Handle<Name> key) {
5458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
54599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Handle hidden prototypes.  If there's a hidden prototype above this thing
54609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // then we have to check it for properties, because they are supposed to
54619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // look like they are on this object.
546209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> proto(object->GetPrototype(), isolate);
54639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  if (proto->IsJSObject() &&
54649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org      Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
5465ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return HasLocalPropertyImplementation(isolate,
5466ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          Handle<JSObject>::cast(proto),
5467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          key);
54689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  }
5469169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5470ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->false_value();
54719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}
54729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
54739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
5474c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
547579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
547643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
5477750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_CHECKED(Name, key, 1);
547843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  uint32_t index;
54807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  const bool key_is_array_index = key->AsArrayIndex(&index);
54817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
54829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  Object* obj = args[0];
548343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Only JS objects can have properties.
54849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  if (obj->IsJSObject()) {
54859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org    JSObject* object = JSObject::cast(obj);
54867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Fast case: either the key is a real named property or it is not
54877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // an array index and there are no interceptors or hidden
54887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // prototypes.
5489169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (object->HasRealNamedProperty(isolate, key)) {
5490169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      ASSERT(!isolate->has_scheduled_exception());
5491e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      return isolate->heap()->true_value();
5492169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
5493169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5494169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
54957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    Map* map = object->map();
54967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    if (!key_is_array_index &&
54977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        !map->has_named_interceptor() &&
54987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
54997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      return isolate->heap()->false_value();
55007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
55017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Slow case.
5502ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
5503ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return HasLocalPropertyImplementation(isolate,
5504ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          Handle<JSObject>(object),
5505750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                          Handle<Name>(key));
55067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  } else if (obj->IsString() && key_is_array_index) {
550743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Well, there is one exception:  Handle [] on strings.
55087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    String* string = String::cast(obj);
55097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    if (index < static_cast<uint32_t>(string->length())) {
55107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      return isolate->heap()->true_value();
551143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
551243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5513ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->false_value();
551443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
551543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
551643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5517c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
551879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
551943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
5520f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
5521750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_CHECKED(Name, key, 1);
552243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool result = receiver->HasProperty(key);
5524169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (isolate->has_pending_exception()) return Failure::Exception();
5526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return isolate->heap()->ToBoolean(result);
552743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
552843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
552943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5530c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
553179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
553243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
5533f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
5534f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 1);
553543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5536f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  bool result = receiver->HasElement(index);
5537169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (isolate->has_pending_exception()) return Failure::Exception();
5539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return isolate->heap()->ToBoolean(result);
554043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
554143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
554243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5543c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
554479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
554543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
554643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5547f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, object, 0);
5548750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_CHECKED(Name, key, 1);
554943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5550870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  PropertyAttributes att = object->GetLocalPropertyAttribute(key);
5551169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (att == ABSENT || (att & DONT_ENUM) != 0) {
5552169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5553169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return isolate->heap()->false_value();
5554169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
5555169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!isolate->has_scheduled_exception());
5556169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return isolate->heap()->true_value();
555743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
555843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
555943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5560c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
5561ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
556243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
5563f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5564394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bool threw = false;
5565394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<JSArray> result = GetKeysFor(object, &threw);
5566394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (threw) return Failure::Exception();
5567394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *result;
556843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
556943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
557043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
557143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns either a FixedArray as Runtime_GetPropertyNames,
557243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// or, if the given object has an enum cache that contains
557343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// all enumerable properties of the object and its prototypes
557443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// have none, the map of the object. This is used to speed up
557543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the check for deletions during a for-in.
5576c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
557779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
557843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
557943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5580f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
558143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
558243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (raw_object->IsSimpleEnum()) return raw_object->map();
558343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5584ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5585394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<JSReceiver> object(raw_object);
5586394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bool threw = false;
5587394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArray> content =
5588394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw);
5589394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (threw) return Failure::Exception();
559043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
559143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Test again, since cache may have been built by preceding call.
559243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsSimpleEnum()) return object->map();
559343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
559443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *content;
559543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
559643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
559743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5598b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Find the length of the prototype chain that is to to handled as one. If a
5599b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// prototype object is hidden it is to be viewed as part of the the object it
5600b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// is prototype for.
5601b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgstatic int LocalPrototypeChainLength(JSObject* obj) {
5602b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int count = 1;
5603b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Object* proto = obj->GetPrototype();
5604b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  while (proto->IsJSObject() &&
5605b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org         JSObject::cast(proto)->map()->is_hidden_prototype()) {
5606b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    count++;
5607b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    proto = JSObject::cast(proto)->GetPrototype();
5608b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5609b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return count;
5610b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5611b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5612b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5613b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return the names of the local named properties.
5614b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5615c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
5616ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5617f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 2);
5618b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (!args[0]->IsJSObject()) {
5619ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
5620b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5621f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5622f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(include_symbols, 1);
5623f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  PropertyAttributes filter = include_symbols ? NONE : SYMBOLIC;
5624b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5625b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Skip the global proxy as it has no properties and always delegates to the
5626b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // real global object.
5627b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->IsJSGlobalProxy()) {
5628b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Only collect names if access is permitted.
5629b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (obj->IsAccessCheckNeeded() &&
5630ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        !isolate->MayNamedAccess(*obj,
5631ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 isolate->heap()->undefined_value(),
5632ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 v8::ACCESS_KEYS)) {
5633ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS);
5634169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5635ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArray(0);
5636b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5637b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
5638b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5639b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5640b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Find the number of objects making up this.
5641b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int length = LocalPrototypeChainLength(*obj);
5642b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5643b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Find the number of local properties for each of the objects.
56444111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  ScopedVector<int> local_property_count(length);
5645b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int total_property_count = 0;
5646b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Handle<JSObject> jsproto = obj;
5647b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (int i = 0; i < length; i++) {
5648b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Only collect names if access is permitted.
5649b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (jsproto->IsAccessCheckNeeded() &&
5650ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        !isolate->MayNamedAccess(*jsproto,
5651ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 isolate->heap()->undefined_value(),
5652ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 v8::ACCESS_KEYS)) {
5653ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS);
5654169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5655ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArray(0);
5656b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5657b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    int n;
5658f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    n = jsproto->NumberOfLocalProperties(filter);
5659b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    local_property_count[i] = n;
5660b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    total_property_count += n;
5661b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (i < length - 1) {
5662b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5663b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5664b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5665b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5666b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Allocate an array with storage for all the property names.
5667ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> names =
5668ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFixedArray(total_property_count);
5669b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5670b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Get the property names.
5671b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  jsproto = obj;
5672b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int proto_with_hidden_properties = 0;
56737c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  int next_copy_index = 0;
5674b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (int i = 0; i < length; i++) {
5675f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    jsproto->GetLocalPropertyNames(*names, next_copy_index, filter);
56767c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    next_copy_index += local_property_count[i];
56777943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    if (jsproto->HasHiddenProperties()) {
5678b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      proto_with_hidden_properties++;
5679b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5680b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (i < length - 1) {
5681b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5682b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5683b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5684b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5685f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // Filter out name of hidden properties object.
5686b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (proto_with_hidden_properties > 0) {
5687b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    Handle<FixedArray> old_names = names;
5688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    names = isolate->factory()->NewFixedArray(
5689b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        names->length() - proto_with_hidden_properties);
5690b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    int dest_pos = 0;
5691b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    for (int i = 0; i < total_property_count; i++) {
5692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      Object* name = old_names->get(i);
56934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (name == isolate->heap()->hidden_string()) {
5694b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        continue;
5695b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      }
5696b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      names->set(dest_pos++, name);
5697b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5698b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5700ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(names);
5701b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5702b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5703b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5704b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return the names of the local indexed properties.
5705b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5706c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalElementNames) {
5707ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5708b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5709b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (!args[0]->IsJSObject()) {
5710ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
5711b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5712f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5713b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5714b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
5715ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
5716b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
5717ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(names);
5718b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5719b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5720b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5721b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return information on whether an object has a named or indexed interceptor.
5722b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5723c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetInterceptorInfo) {
5724ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5725b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5726b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (!args[0]->IsJSObject()) {
5727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Smi::FromInt(0);
5728b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5729f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5730b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5731b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int result = 0;
5732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasNamedInterceptor()) result |= 2;
5733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasIndexedInterceptor()) result |= 1;
5734b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5735b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return Smi::FromInt(result);
5736b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5737b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5738b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5739b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return property names from named interceptor.
5740b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5741c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
5742ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5743b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5744f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5745b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5746b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasNamedInterceptor()) {
5747b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
5748b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
5749b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5750ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
5751b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5752b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5753b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5754b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return element names from indexed interceptor.
5755b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5756c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetIndexedInterceptorElementNames) {
5757ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5758b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5759f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5760b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5761b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasIndexedInterceptor()) {
5762b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
5763b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
5764b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5765ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
5766b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5767b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5768b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5769c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
57706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
57712bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  ASSERT_EQ(args.length(), 1);
5772f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
57732bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Handle<JSObject> object(raw_object);
5774496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
5775496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  if (object->IsJSGlobalProxy()) {
57766500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org    // Do access checks before going to the global object.
57776500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org    if (object->IsAccessCheckNeeded() &&
5778ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
57796500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org                             v8::ACCESS_KEYS)) {
5780ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
5781169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5782ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArray(0);
57836500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org    }
57846500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org
578509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> proto(object->GetPrototype(), isolate);
5786496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // If proxy is detached we simply return an empty array.
5787ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
5788496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    object = Handle<JSObject>::cast(proto);
5789496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  }
5790496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
5791394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bool threw = false;
5792394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArray> contents =
5793394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
5794394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (threw) return Failure::Exception();
5795394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
57962bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // Some fast paths through GetKeysInFixedArrayFor reuse a cached
57972bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // property array and since the result is mutable we have to create
57982bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // a fresh clone on each invocation.
5799c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  int length = contents->length();
5800ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
5801c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  for (int i = 0; i < length; i++) {
5802c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    Object* entry = contents->get(i);
5803c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    if (entry->IsString()) {
5804c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      copy->set(i, entry);
5805c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    } else {
5806c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      ASSERT(entry->IsNumber());
5807ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      HandleScope scope(isolate);
5808ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<Object> entry_handle(entry, isolate);
5809ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<Object> entry_str =
5810ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->factory()->NumberToString(entry_handle);
5811c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      copy->set(i, *entry_str);
5812c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    }
5813c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
5814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(copy);
58152bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com}
58162bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
58172bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
5818c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
581979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
582043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
582143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
582243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the frame holding the arguments.
582374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate);
582443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  it.AdvanceToArgumentsFrame();
582543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JavaScriptFrame* frame = it.frame();
582643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
582743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the actual number of provided arguments.
58284d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  const uint32_t n = frame->ComputeParametersCount();
582943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
583043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Try to convert the key to an index. If successful and within
583143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // index return the the argument from the frame.
583243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
583330ce411529579186181838984710b0b0980857aaricow@chromium.org  if (args[0]->ToArrayIndex(&index) && index < n) {
583443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return frame->GetParameter(index);
583543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
583643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5837750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (args[0]->IsSymbol()) {
5838750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    // Lookup in the initial Object.prototype object.
5839750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return isolate->initial_object_prototype()->GetProperty(
5840750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        Symbol::cast(args[0]));
5841750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
5842750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
584343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert the key to a string.
5844ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
584543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool exception = false;
584643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> converted =
584743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Execution::ToString(args.at<Object>(0), &exception);
584843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (exception) return Failure::Exception();
584943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> key = Handle<String>::cast(converted);
585043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
585143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Try to convert the string key into an array index.
585243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (key->AsArrayIndex(&index)) {
585343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (index < n) {
585443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return frame->GetParameter(index);
585543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
5856ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->initial_object_prototype()->GetElement(index);
585743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
585843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
585943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
586043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle special arguments properties.
58614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n);
58624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (key->Equals(isolate->heap()->callee_string())) {
5863169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    JSFunction* function = frame->function();
5864169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (!function->shared()->is_classic_mode()) {
5865ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->Throw(*isolate->factory()->NewTypeError(
5866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
5867ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
5868ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return function;
5869ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
587043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
587143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Lookup in the initial Object.prototype object.
5872ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->initial_object_prototype()->GetProperty(*key);
587343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
587443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
587543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5876c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
587779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
5878061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  ASSERT(args.length() == 1);
5879f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Object* object = args[0];
5880f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  return (object->IsJSObject() && !object->IsGlobalObject())
5881f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      ? JSObject::cast(object)->TransformToFastProperties(0)
5882f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      : object;
5883061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org}
5884061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
5885061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
5886c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
588779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
588843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
588943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58909faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  return isolate->heap()->ToBoolean(args[0]->BooleanValue());
589143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
589243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
589343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
589443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
589543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Possible optimizations: put the type string into the oddballs.
5896c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
589779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
589843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
589943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* obj = args[0];
59004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (obj->IsNumber()) return isolate->heap()->number_string();
590143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* heap_obj = HeapObject::cast(obj);
590243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
590343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // typeof an undetectable object is 'undefined'
5904ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (heap_obj->map()->is_undetectable()) {
59054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->heap()->undefined_string();
5906ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
590743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
590843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  InstanceType instance_type = heap_obj->map()->instance_type();
590943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (instance_type < FIRST_NONSTRING_TYPE) {
59104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->heap()->string_string();
591143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
591243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
591343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (instance_type) {
591443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case ODDBALL_TYPE:
591543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
59164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        return isolate->heap()->boolean_string();
591743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
591843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (heap_obj->IsNull()) {
59194acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        return FLAG_harmony_typeof
59204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            ? isolate->heap()->null_string()
59214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            : isolate->heap()->object_string();
592243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
592343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(heap_obj->IsUndefined());
59244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->heap()->undefined_string();
5925f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    case SYMBOL_TYPE:
5926f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      return isolate->heap()->symbol_string();
5927c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org    case JS_FUNCTION_TYPE:
592834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    case JS_FUNCTION_PROXY_TYPE:
59294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->heap()->function_string();
593043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
593143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // For any kind of object not handled above, the spec rule for
593243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // host objects gives that it is okay to return "object"
59334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->heap()->object_string();
593443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
593543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
593643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
593743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
593859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgstatic bool AreDigits(const uint8_t*s, int from, int to) {
593925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  for (int i = from; i < to; i++) {
594025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (s[i] < '0' || s[i] > '9') return false;
594125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
594225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
594325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  return true;
594425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
594525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
594625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
594759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgstatic int ParseDecimalInteger(const uint8_t*s, int from, int to) {
594825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(to - from < 10);  // Overflow is not possible.
594925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(from < to);
595025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int d = s[from] - '0';
595125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
595225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  for (int i = from + 1; i < to; i++) {
595325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    d = 10 * d + (s[i] - '0');
595425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
595525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
595625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  return d;
595725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
595825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
595925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
5960c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
596179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
596243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
5963f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, subject, 0);
5964ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  subject->TryFlatten();
596525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
596625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  // Fast case: short integer or some sorts of junk values.
596725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int len = subject->length();
5968fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (subject->IsSeqOneByteString()) {
596925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (len == 0) return Smi::FromInt(0);
597025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
597159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    uint8_t const* data = SeqOneByteString::cast(subject)->GetChars();
597225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    bool minus = (data[0] == '-');
597325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int start_pos = (minus ? 1 : 0);
597425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
597525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (start_pos == len) {
5976ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->heap()->nan_value();
597725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    } else if (data[start_pos] > '9') {
597825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      // Fast check for a junk value. A valid string may start from a
597925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
598025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      // the 'I' character ('Infinity'). All of that have codes not greater than
59816bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org      // '9' except 'I' and &nbsp;.
59826bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org      if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
5983ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return isolate->heap()->nan_value();
598425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      }
598525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
598625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      // The maximal/minimal smi has 10 digits. If the string has less digits we
598725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      // know it will fit into the smi-data type.
598825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      int d = ParseDecimalInteger(data, start_pos, len);
598925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      if (minus) {
5990ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        if (d == 0) return isolate->heap()->minus_zero_value();
599125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org        d = -d;
5992d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org      } else if (!subject->HasHashCode() &&
5993d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                 len <= String::kMaxArrayIndexSize &&
5994d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                 (len == 1 || data[0] != '0')) {
5995d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        // String hash is not calculated yet but all the data are present.
5996d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        // Update the hash field to speed up sequential convertions.
59975b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org        uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
5998d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org#ifdef DEBUG
5999d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        subject->Hash();  // Force hash calculation.
6000d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        ASSERT_EQ(static_cast<int>(subject->hash_field()),
6001d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                  static_cast<int>(hash));
6002d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org#endif
6003d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        subject->set_hash_field(hash);
600425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      }
600525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      return Smi::FromInt(d);
600625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    }
600725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
600825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
600925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  // Slower case.
6010ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  int flags = ALLOW_HEX;
6011ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (FLAG_harmony_numeric_literals) {
6012ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // The current spec draft has not updated "ToNumber Applied to the String
6013ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
6014ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    flags |= ALLOW_OCTAL | ALLOW_BINARY;
6015ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
6016a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  return isolate->heap()->NumberFromDouble(
6017ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      StringToDouble(isolate->unicode_cache(), subject, flags));
601843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
601943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
602043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
602132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) {
602279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
602332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CONVERT_SMI_ARG_CHECKED(length, 0);
602432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
602532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  if (length == 0) return isolate->heap()->empty_string();
602632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  if (is_one_byte) {
602732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    return isolate->heap()->AllocateRawOneByteString(length);
602832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  } else {
602932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    return isolate->heap()->AllocateRawTwoByteString(length);
603043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
603132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
603243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
603343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
603432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TruncateString) {
6035f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
6036f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
603732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CONVERT_SMI_ARG_CHECKED(new_length, 1);
6038f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return *SeqString::Truncate(string, new_length);
603943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
604043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
604143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6042c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
60432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HandleScope scope(isolate);
60446e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
60452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
60462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Handle<String> string = FlattenGetString(source);
6047a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(string->IsFlat());
6048a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  Handle<String> result = string->IsOneByteRepresentationUnderneath()
6049a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      ? URIEscape::Escape<uint8_t>(isolate, source)
6050a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      : URIEscape::Escape<uc16>(isolate, source);
60512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (result.is_null()) return Failure::OutOfMemoryException(0x12);
60522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  return *result;
605343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
605443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
605543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6056c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
60572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HandleScope scope(isolate);
60586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
60592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
60602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Handle<String> string = FlattenGetString(source);
6061a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(string->IsFlat());
6062a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  return string->IsOneByteRepresentationUnderneath()
6063a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      ? *URIUnescape::Unescape<uint8_t>(isolate, source)
6064a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      : *URIUnescape::Unescape<uc16>(isolate, source);
606543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
606643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
606743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6068c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
6069f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
6070f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6071c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  ASSERT(args.length() == 1);
6072f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return BasicJsonStringifier::StringifyString(isolate, string);
6073c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org}
6074c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
6075c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
607672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
607772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  HandleScope scope(isolate);
60786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
607972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  BasicJsonStringifier stringifier(isolate);
608009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  return stringifier.Stringify(Handle<Object>(args[0], isolate));
608172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
608272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
608372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
6084c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
608579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
608643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6087f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, s, 0);
60886d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(radix, 1);
608943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6090ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  s->TryFlatten();
6091870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
609225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
6093a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  double value = StringToInt(isolate->unicode_cache(), s, radix);
6094ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(value);
609543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
609643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
609743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6098c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
609979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6100f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, str, 0);
610143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
610243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ECMA-262 section 15.1.2.3, empty string is NaN
6103a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  double value = StringToDouble(isolate->unicode_cache(),
6104a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                                str, ALLOW_TRAILING_JUNK, OS::nan_value());
610543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
610643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Create a number object from the value.
6107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(value);
610843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
610943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
611043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
611143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentemplate <class Converter>
6112303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
6113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
6114303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    String* s,
6115303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    int length,
6116303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    int input_string_length,
6117303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    unibrow::Mapping<Converter, 128>* mapping) {
6118bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // We try this twice, once with the assumption that the result is no longer
6119bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // than the input and, if that assumption breaks, again with the exact
6120bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // length.  This may not be pretty, but it is nicer than what was here before
6121bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // and I hereby claim my vaffel-is.
6122bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  //
612343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate the resulting string.
612443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
61252efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // NOTE: This assumes that the upper/lower case of an ASCII
61262efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // character is also ASCII.  This is currently the case, but it
612743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // might break in the future if we implement more context and locale
612843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // dependent upper/lower conversions.
6129303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* o;
61308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  { MaybeObject* maybe_o = s->IsOneByteRepresentation()
61318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        ? isolate->heap()->AllocateRawOneByteString(length)
6132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        : isolate->heap()->AllocateRawTwoByteString(length);
6133303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_o->ToObject(&o)) return maybe_o;
6134303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
613543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String* result = String::cast(o);
613643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool has_changed_character = false;
613743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
613843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert all characters to upper case, assuming that they will fit
613943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in the buffer
61404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  Access<ConsStringIteratorOp> op(
61414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      isolate->runtime_state()->string_iterator());
61424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(s, op.value());
6143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  unibrow::uchar chars[Converter::kMaxWidth];
614443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We can assume that the string is not empty
61454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  uc32 current = stream.GetNext();
6146bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  for (int i = 0; i < length;) {
61474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    bool has_next = stream.HasMore();
61484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uc32 next = has_next ? stream.GetNext() : 0;
614943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int char_length = mapping->get(current, next, chars);
615043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (char_length == 0) {
615143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // The case conversion of this character is the character itself.
6152bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      result->Set(i, current);
615343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      i++;
615443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else if (char_length == 1) {
615543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Common case: converting the letter resulted in one character.
615643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(static_cast<uc32>(chars[0]) != current);
6157bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      result->Set(i, chars[0]);
615843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      has_changed_character = true;
615943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      i++;
6160bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else if (length == input_string_length) {
616143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // We've assumed that the result would be as long as the
616243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // input but here is a character that converts to several
616343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // characters.  No matter, we calculate the exact length
616443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // of the result and try the whole thing again.
616543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      //
616643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Note that this leaves room for optimization.  We could just
616743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // memcpy what we already have to the result string.  Also,
616843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // the result string is the last object allocated we could
616943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // "realloc" it and probably, in the vast majority of cases,
617043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // extend the existing string to be able to hold the full
617143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // result.
61727c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      int next_length = 0;
61737c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      if (has_next) {
61747c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        next_length = mapping->get(next, 0, chars);
61757c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        if (next_length == 0) next_length = 1;
61767c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      }
61777c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      int current_length = i + char_length + next_length;
61784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      while (stream.HasMore()) {
61794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        current = stream.GetNext();
61807c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // NOTE: we use 0 as the next character here because, while
61817c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // the next character may affect what a character converts to,
61827c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // it does not in any case affect the length of what it convert
61837c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // to.
618443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        int char_length = mapping->get(current, 0, chars);
618543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (char_length == 0) char_length = 1;
61867c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        current_length += char_length;
6187bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (current_length > Smi::kMaxValue) {
6188ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->context()->mark_out_of_memory();
618959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          return Failure::OutOfMemoryException(0x13);
6190bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
619143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
6192bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      // Try again with the real length.
6193bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return Smi::FromInt(current_length);
619443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
619543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      for (int j = 0; j < char_length; j++) {
6196bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        result->Set(i, chars[j]);
619743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        i++;
619843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
619943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      has_changed_character = true;
620043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
620143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    current = next;
620243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
620343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (has_changed_character) {
620443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return result;
620543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
620643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we didn't actually change anything in doing the conversion
620743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // we simple return the result and let the converted string
620843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // become garbage; there is no reason to keep two identical strings
620943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // alive.
621043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return s;
621143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
621243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
621343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
621443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6215ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgnamespace {
6216ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6217303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
621846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic const uintptr_t kAsciiMask = kOneInEveryByte << 7;
6219303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6220303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// Given a word and two range boundaries returns a word with high bit
6221303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// set in every byte iff the corresponding input byte was strictly in
6222303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// the range (m, n). All the other bits in the result are cleared.
6223303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// This function is only useful when it can be inlined and the
6224303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// boundaries are statically known.
6225303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// Requires: all bytes in the input word and the boundaries must be
62262efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// ASCII (less than 0x7F).
6227303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
6228303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Use strict inequalities since in edge cases the function could be
6229303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // further simplified.
623046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(0 < m && m < n);
6231303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Has high bit set in every w byte less than n.
6232303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6233303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Has high bit set in every w byte greater than m.
6234303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6235303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6236303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org}
6237303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6238303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6239303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgenum AsciiCaseConversion {
6240303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  ASCII_TO_LOWER,
6241303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  ASCII_TO_UPPER
6242303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org};
6243ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6244303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6245303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgtemplate <AsciiCaseConversion dir>
6246303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstruct FastAsciiConverter {
624746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  static bool Convert(char* dst, char* src, int length, bool* changed_out) {
6248303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef DEBUG
6249303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    char* saved_dst = dst;
6250303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    char* saved_src = src;
6251303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
6252303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // We rely on the distance between upper and lower case letters
6253303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // being a known power of 2.
6254303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    ASSERT('a' - 'A' == (1 << 5));
6255303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // Boundaries for the range of input characters than require conversion.
6256303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1;
6257303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1;
6258ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    bool changed = false;
625946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    uintptr_t or_acc = 0;
6260303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    char* const limit = src + length;
6261303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef V8_HOST_CAN_READ_UNALIGNED
6262303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // Process the prefix of the input that requires no conversion one
6263303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // (machine) word at a time.
6264303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    while (src <= limit - sizeof(uintptr_t)) {
6265303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
626646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      or_acc |= w;
6267303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (AsciiRangeMask(w, lo, hi) != 0) {
6268ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org        changed = true;
6269303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        break;
6270ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      }
6271303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      *reinterpret_cast<uintptr_t*>(dst) = w;
6272303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      src += sizeof(uintptr_t);
6273303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      dst += sizeof(uintptr_t);
6274303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6275303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // Process the remainder of the input performing conversion when
6276303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // required one word at a time.
6277303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    while (src <= limit - sizeof(uintptr_t)) {
6278303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
627946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      or_acc |= w;
6280303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      uintptr_t m = AsciiRangeMask(w, lo, hi);
6281303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      // The mask has high (7th) bit set in every byte that needs
6282303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      // conversion and we know that the distance between cases is
6283303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      // 1 << 5.
6284303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6285303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      src += sizeof(uintptr_t);
6286303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      dst += sizeof(uintptr_t);
6287ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
6288303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
6289303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // Process the last few bytes of the input (or the whole input if
6290303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    // unaligned access is not supported).
6291303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    while (src < limit) {
6292303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      char c = *src;
629346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      or_acc |= c;
6294303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (lo < c && c < hi) {
6295303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        c ^= (1 << 5);
6296303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        changed = true;
6297303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
6298303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      *dst = c;
6299303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      ++src;
6300303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      ++dst;
6301303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
630246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    if ((or_acc & kAsciiMask) != 0) {
630346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      return false;
630446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    }
6305303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef DEBUG
6306303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    CheckConvert(saved_dst, saved_src, length, changed);
6307303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
630846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    *changed_out = changed;
630946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    return true;
6310ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6311303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6312303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef DEBUG
6313303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  static void CheckConvert(char* dst, char* src, int length, bool changed) {
6314303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    bool expected_changed = false;
6315303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    for (int i = 0; i < length; i++) {
6316303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (dst[i] == src[i]) continue;
6317303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      expected_changed = true;
6318303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (dir == ASCII_TO_LOWER) {
6319303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        ASSERT('A' <= src[i] && src[i] <= 'Z');
6320303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        ASSERT(dst[i] == src[i] + ('a' - 'A'));
6321303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      } else {
6322303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        ASSERT(dir == ASCII_TO_UPPER);
6323303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        ASSERT('a' <= src[i] && src[i] <= 'z');
6324303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        ASSERT(dst[i] == src[i] - ('a' - 'A'));
6325303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
6326303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6327303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    ASSERT(expected_changed == changed);
6328303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
6329303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
6330303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org};
6331303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6332303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6333303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstruct ToLowerTraits {
6334303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  typedef unibrow::ToLowercase UnibrowConverter;
6335303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6336303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter;
6337ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org};
6338ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6339ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6340ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgstruct ToUpperTraits {
6341ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  typedef unibrow::ToUppercase UnibrowConverter;
6342ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6343303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter;
6344ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org};
6345ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6346ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}  // namespace
6347bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6348ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6349ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgtemplate <typename ConvertTraits>
6350303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMUST_USE_RESULT static MaybeObject* ConvertCase(
6351ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Arguments args,
6352ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
6353ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
635479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6355f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, s, 0);
63565ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  s = s->TryFlattenGetString();
6357bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6358ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  const int length = s->length();
6359bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Assume that the string is not empty; we need this assumption later
6360ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (length == 0) return s;
6361ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
63622efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Simpler handling of ASCII strings.
6363ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  //
63642efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // NOTE: This assumes that the upper/lower case of an ASCII
63652efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // character is also ASCII.  This is currently the case, but it
6366ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // might break in the future if we implement more context and locale
6367ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // dependent upper/lower conversions.
6368fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (s->IsSeqOneByteString()) {
6369303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* o;
63708e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length);
6371303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_o->ToObject(&o)) return maybe_o;
6372303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6373fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    SeqOneByteString* result = SeqOneByteString::cast(o);
637446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    bool has_changed_character;
637546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    bool is_ascii = ConvertTraits::AsciiConverter::Convert(
637646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        reinterpret_cast<char*>(result->GetChars()),
637746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
637846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        length,
637946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        &has_changed_character);
638046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    // If not ASCII, we discard the result and take the 2 byte path.
638146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    if (is_ascii) {
638246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org      return has_changed_character ? result : s;
638346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    }
638446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  }
6385bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6386303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* answer;
6387ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_answer =
6388ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        ConvertCaseHelper(isolate, s, length, length, mapping);
6389303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6390303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
6391bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (answer->IsSmi()) {
6392bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Retry with correct length.
6393303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_answer =
6394ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          ConvertCaseHelper(isolate,
6395ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            s, Smi::cast(answer)->value(), length, mapping);
6396303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6397303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6398bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
6399303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  return answer;
6400bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
6401bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6402bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6403c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
6404ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return ConvertCase<ToLowerTraits>(
6405ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      args, isolate, isolate->runtime_state()->to_lower_mapping());
640643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
640743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
640843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6409c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
6410ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return ConvertCase<ToUpperTraits>(
6411ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      args, isolate, isolate->runtime_state()->to_upper_mapping());
641243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
641343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6414ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
64159d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comstatic inline bool IsTrimWhiteSpace(unibrow::uchar c) {
6416a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
64179d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
64189d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
6419ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6420c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
642179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
64229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(args.length() == 3);
64239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
6424f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, s, 0);
6425f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
6426f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
64279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
6428ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  s->TryFlatten();
64299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  int length = s->length();
64309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
64319d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  int left = 0;
64329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (trimLeft) {
64339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    while (left < length && IsTrimWhiteSpace(s->Get(left))) {
64349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      left++;
64359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
64369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
64379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
64389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  int right = length;
64399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (trimRight) {
64409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) {
64419d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      right--;
64429d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
64439d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
6444c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  return s->SubString(left, right);
64459d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
644643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6447ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6448c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
6449ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handle_scope(isolate);
64506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 3);
6451f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6452f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
6453086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
6454086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6455086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int subject_length = subject->length();
6456086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int pattern_length = pattern->length();
6457086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  RUNTIME_ASSERT(pattern_length > 0);
6458086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6459486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (limit == 0xffffffffu) {
646009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> cached_answer(
646109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        RegExpResultsCache::Lookup(isolate->heap(),
646209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                   *subject,
646309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                   *pattern,
646409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                   RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
646509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        isolate);
6466486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    if (*cached_answer != Smi::FromInt(0)) {
646778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // The cache FixedArray is a COW-array and can therefore be reused.
6468486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      Handle<JSArray> result =
6469486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          isolate->factory()->NewJSArrayWithElements(
6470486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org              Handle<FixedArray>::cast(cached_answer));
6471486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      return *result;
6472486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    }
6473486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
6474486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6475086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // The limit can be very large (0xffffffffu), but since the pattern
6476086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // isn't empty, we can never create more parts than ~half the length
6477086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // of the subject.
6478086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6479086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  if (!subject->IsFlat()) FlattenString(subject);
6480086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6481086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  static const int kMaxInitialListCapacity = 16;
6482086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6483c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
6484086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6485086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Find (up to limit) indices of separator and end-of-string in subject
6486086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
6487c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneList<int> indices(initial_capacity, zone_scope.zone());
6488d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  if (!pattern->IsFlat()) FlattenString(pattern);
6489d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
64901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  FindStringIndicesDispatch(isolate, *subject, *pattern,
6491c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                            &indices, limit, zone_scope.zone());
6492d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6493086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  if (static_cast<uint32_t>(indices.length()) < limit) {
6494c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    indices.Add(subject_length, zone_scope.zone());
6495086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
6496086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6497d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // The list indices now contains the end of each part to create.
6498086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6499086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Create JSArray of substrings separated by separator.
6500086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int part_count = indices.length();
6501086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6502ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
650364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements();
6504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (maybe_result->IsFailure()) return maybe_result;
6505086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  result->set_length(Smi::FromInt(part_count));
6506086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6507830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(result->HasFastObjectElements());
6508086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6509086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  if (part_count == 1 && indices.at(0) == subject_length) {
6510086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    FixedArray::cast(result->elements())->set(0, *subject);
6511086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    return *result;
6512086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
6513086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6514086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Handle<FixedArray> elements(FixedArray::cast(result->elements()));
6515086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int part_start = 0;
6516086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  for (int i = 0; i < part_count; i++) {
6517c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    HandleScope local_loop_handle(isolate);
6518086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    int part_end = indices.at(i);
6519086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    Handle<String> substring =
652004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        isolate->factory()->NewProperSubString(subject, part_start, part_end);
6521086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    elements->set(i, *substring);
6522086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    part_start = part_end + pattern_length;
6523086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
6524086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6525486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (limit == 0xffffffffu) {
6526830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (result->HasFastObjectElements()) {
652778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      RegExpResultsCache::Enter(isolate->heap(),
652878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                *subject,
652978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                *pattern,
653078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                *elements,
653178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
653255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
6533486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
6534486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6535086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  return *result;
6536086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
6537086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6538086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
65392efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copies ASCII characters to the given fixed array looking up
6540ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// one-char strings in the cache. Gives up on the first char that is
6541ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// not in the cache and fills the remainder with smi zeros. Returns
6542ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// the length of the successfully copied prefix.
6543ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic int CopyCachedAsciiCharsToArray(Heap* heap,
654459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                       const uint8_t* chars,
6545ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                       FixedArray* elements,
6546ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                       int length) {
654779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
6548ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  FixedArray* ascii_cache = heap->single_character_string_cache();
6549ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Object* undefined = heap->undefined_value();
6550ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int i;
6551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6552ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (i = 0; i < length; ++i) {
6553ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Object* value = ascii_cache->get(chars[i]);
6554ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (value == undefined) break;
6555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    elements->set(i, value, mode);
6556ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6557ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (i < length) {
6558ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(Smi::FromInt(0) == 0);
6559ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    memset(elements->data_start() + i, 0, kPointerSize * (length - i));
6560ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6561ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#ifdef DEBUG
6562ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int j = 0; j < length; ++j) {
6563ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Object* element = elements->get(j);
6564ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(element == Smi::FromInt(0) ||
6565ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org           (element->IsString() && String::cast(element)->LooksValid()));
6566ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6567ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#endif
6568ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return i;
6569ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
6570ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6571ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6572ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Converts a String to JSArray.
6573ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For example, "foo" => ["f", "o", "o"].
6574c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
6575ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
6576beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  ASSERT(args.length() == 2);
6577f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6578beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
6579ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6580ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  s = FlattenGetString(s);
6581beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
6582ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6583ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<FixedArray> elements;
6584ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  int position = 0;
65858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (s->IsFlat() && s->IsOneByteRepresentation()) {
6586ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    // Try using cached chars where possible.
6587303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* obj;
6588ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    { MaybeObject* maybe_obj =
6589ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->heap()->AllocateUninitializedFixedArray(length);
6590303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6591303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6592ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
659379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
6594ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    String::FlatContent content = s->GetFlatContent();
6595ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (content.IsAscii()) {
659659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> chars = content.ToOneByteVector();
6597ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      // Note, this will initialize all elements (not only the prefix)
6598ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      // to prevent GC from seeing partially initialized array.
6599ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      position = CopyCachedAsciiCharsToArray(isolate->heap(),
6600ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                             chars.start(),
6601ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                             *elements,
6602ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                             length);
6603ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    } else {
6604ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      MemsetPointer(elements->data_start(),
6605ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                    isolate->heap()->undefined_value(),
6606ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                    length);
6607ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
6608ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
6609ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    elements = isolate->factory()->NewFixedArray(length);
6610ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  }
6611ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  for (int i = position; i < length; ++i) {
661209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> str =
661309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        LookupSingleCharacterStringFromCode(isolate, s->Get(i));
6614ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    elements->set(i, *str);
6615ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6616ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6617ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#ifdef DEBUG
6618ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int i = 0; i < length; ++i) {
6619ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(String::cast(elements->get(i))->length() == 1);
6620ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6621ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#endif
6622ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6623ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(elements);
6624ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
6625ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6626ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6627c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
662879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6629d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  ASSERT(args.length() == 1);
6630f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, value, 0);
6631d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  return value->ToObject();
6632d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org}
6633d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6634d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6635ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgbool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
6636d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
6637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
6638d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  return char_length == 0;
6639d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org}
6640d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
6641d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
6642c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToString) {
664379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
664443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
664543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
664643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* number = args[0];
664743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(number->IsNumber());
664843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberToString(number);
665043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
665143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
665243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6653c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToStringSkipCache) {
665479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6655357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  ASSERT(args.length() == 1);
6656357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
6657357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  Object* number = args[0];
6658357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  RUNTIME_ASSERT(number->IsNumber());
6659357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
666057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  return isolate->heap()->NumberToString(
666157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      number, false, isolate->heap()->GetPretenureMode());
6662357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
6663357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
6664357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
6665c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
666679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
666743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
666843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6670ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6671ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // We do not include 0 so that we don't have to treat +0 / -0 cases.
6672ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (number > 0 && number <= Smi::kMaxValue) {
6673ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return Smi::FromInt(static_cast<int>(number));
6674ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6675ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
667643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
667743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
667843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6679f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// ES6 draft 9.1.11
6680f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPositiveInteger) {
668179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6682f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
6683f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6684f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6685f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6686f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // We do not include 0 so that we don't have to treat +0 / -0 cases.
6687f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (number > 0 && number <= Smi::kMaxValue) {
6688f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return Smi::FromInt(static_cast<int>(number));
6689f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
6690f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (number <= 0) {
6691f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return Smi::FromInt(0);
6692f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
6693f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
6694f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
6695f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6696f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6697c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
669879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
669930ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT(args.length() == 1);
670030ce411529579186181838984710b0b0980857aaricow@chromium.org
67016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
670230ce411529579186181838984710b0b0980857aaricow@chromium.org
670330ce411529579186181838984710b0b0980857aaricow@chromium.org  // We do not include 0 so that we don't have to treat +0 / -0 cases.
670430ce411529579186181838984710b0b0980857aaricow@chromium.org  if (number > 0 && number <= Smi::kMaxValue) {
670530ce411529579186181838984710b0b0980857aaricow@chromium.org    return Smi::FromInt(static_cast<int>(number));
670630ce411529579186181838984710b0b0980857aaricow@chromium.org  }
670730ce411529579186181838984710b0b0980857aaricow@chromium.org
670830ce411529579186181838984710b0b0980857aaricow@chromium.org  double double_value = DoubleToInteger(number);
670930ce411529579186181838984710b0b0980857aaricow@chromium.org  // Map both -0 and +0 to +0.
671030ce411529579186181838984710b0b0980857aaricow@chromium.org  if (double_value == 0) double_value = 0;
671130ce411529579186181838984710b0b0980857aaricow@chromium.org
6712ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(double_value);
671330ce411529579186181838984710b0b0980857aaricow@chromium.org}
671430ce411529579186181838984710b0b0980857aaricow@chromium.org
671530ce411529579186181838984710b0b0980857aaricow@chromium.org
6716c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) {
671779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
671843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
671943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6720ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
6721ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromUint32(number);
672243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
672343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
672443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6725c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
672679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
672743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
672843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6730ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6731ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // We do not include 0 so that we don't have to treat +0 / -0 cases.
6732ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (number > 0 && number <= Smi::kMaxValue) {
6733ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return Smi::FromInt(static_cast<int>(number));
6734ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6735ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromInt32(DoubleToInt32(number));
673643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
673743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
673843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6739870a0b67c822d289024711912e2512af01b66c3bager@chromium.org// Converts a Number to a Smi, if possible. Returns NaN if the number is not
6740870a0b67c822d289024711912e2512af01b66c3bager@chromium.org// a small integer.
6741c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToSmi) {
674279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6743870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT(args.length() == 1);
6744870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
6745870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  Object* obj = args[0];
6746870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  if (obj->IsSmi()) {
6747870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    return obj;
6748870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  }
6749870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  if (obj->IsHeapNumber()) {
6750870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    double value = HeapNumber::cast(obj)->value();
6751870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    int int_value = FastD2I(value);
6752870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
6753870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      return Smi::FromInt(int_value);
6754870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    }
6755870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  }
6756ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->nan_value();
6757870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
6758870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
675965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
6760c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateHeapNumber) {
676179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 0);
6763ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->AllocateHeapNumber(0);
6764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6767c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
676879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
676943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
677043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
67726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6773ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(x + y);
677443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
677543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
677643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6777c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
677879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
677943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
678043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
67826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6783ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(x - y);
678443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
678543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
678643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6787c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
678879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
678943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
679043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
67926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6793ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(x * y);
679443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
679543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
679643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6797c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
679879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
679943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
680043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6802ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(-x);
680343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
680443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
680543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6806c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) {
680779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
68086a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  ASSERT(args.length() == 0);
68096a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
6810ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(9876543210.0);
68116a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
68126a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
68136a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
6814c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
681579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
681643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
681743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
68196d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(x / y);
682143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
682243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
682343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6824c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
682579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
682643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
682743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
68296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
683043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  x = modulo(x, y);
68324111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // NumberFromDouble may return a Smi instead of a Number object
6833ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(x);
683443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
683543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
683643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6837ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberImul) {
683879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
6839ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(args.length() == 2);
6840ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
6841ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
6842ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
6843ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return isolate->heap()->NumberFromInt32(x * y);
6844ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
6845ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
6846ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
6847c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) {
684879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
684943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
6850f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, str1, 0);
6851f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, str2, 1);
6852ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->string_add_runtime()->Increment();
6853ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->AllocateConsString(str1, str2);
685443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
685543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
685643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6857c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgtemplate <typename sinkchar>
68585a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgstatic inline void StringBuilderConcatHelper(String* special,
68595a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                             sinkchar* sink,
68605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                             FixedArray* fixed_array,
68615a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                             int array_length) {
68625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int position = 0;
68635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  for (int i = 0; i < array_length; i++) {
68645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Object* element = fixed_array->get(i);
68655a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    if (element->IsSmi()) {
6866c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      // Smi encoding of position and length.
6867bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int encoded_slice = Smi::cast(element)->value();
6868c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int pos;
6869c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int len;
6870c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      if (encoded_slice > 0) {
6871c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in one smi.
6872c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        pos = StringBuilderSubstringPosition::decode(encoded_slice);
6873c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        len = StringBuilderSubstringLength::decode(encoded_slice);
6874c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      } else {
6875c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in two smis.
6876c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        Object* obj = fixed_array->get(++i);
6877c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        ASSERT(obj->IsSmi());
6878c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        pos = Smi::cast(obj)->value();
6879c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        len = -encoded_slice;
6880c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      }
6881870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      String::WriteToFlat(special,
6882870a0b67c822d289024711912e2512af01b66c3bager@chromium.org                          sink + position,
6883870a0b67c822d289024711912e2512af01b66c3bager@chromium.org                          pos,
6884870a0b67c822d289024711912e2512af01b66c3bager@chromium.org                          pos + len);
68855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      position += len;
68865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    } else {
68875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      String* string = String::cast(element);
6888bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int element_length = string->length();
6889bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      String::WriteToFlat(string, sink + position, 0, element_length);
68905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      position += element_length;
68915a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    }
68925a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
68935a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
68945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
68955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
6896c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
689779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
68980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  ASSERT(args.length() == 3);
6899f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, array, 0);
69000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  if (!args[1]->IsSmi()) {
6901ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->context()->mark_out_of_memory();
690259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x14);
69030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
69046d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int array_length = args.smi_at(1);
6905f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, special, 2);
6906c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
6907c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This assumption is used by the slice encoding in one or two smis.
6908c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ASSERT(Smi::kMaxValue >= String::kMaxLength);
6909c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
691064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements();
6911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (maybe_result->IsFailure()) return maybe_result;
6912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6913bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int special_length = special->length();
6914830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (!array->HasFastObjectElements()) {
69154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
691643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
691743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* fixed_array = FixedArray::cast(array->elements());
69189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (fixed_array->length() < array_length) {
691943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    array_length = fixed_array->length();
69209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
692143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
692243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (array_length == 0) {
6923ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->empty_string();
692443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (array_length == 1) {
692543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* first = fixed_array->get(0);
692643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (first->IsString()) return first;
692743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
692843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6929f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  bool one_byte = special->HasOnlyOneByteChars();
693043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int position = 0;
693143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < array_length; i++) {
6932c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    int increment = 0;
693343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* elt = fixed_array->get(i);
693443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (elt->IsSmi()) {
6935c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      // Smi encoding of position and length.
6936c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      int smi_value = Smi::cast(elt)->value();
6937c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      int pos;
6938c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      int len;
6939c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      if (smi_value > 0) {
6940c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in one smi.
6941c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        pos = StringBuilderSubstringPosition::decode(smi_value);
6942c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        len = StringBuilderSubstringLength::decode(smi_value);
6943c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      } else {
6944c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in two smis.
6945c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        len = -smi_value;
6946c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        // Get the position and check that it is a positive smi.
6947c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        i++;
6948c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        if (i >= array_length) {
69494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          return isolate->Throw(isolate->heap()->illegal_argument_string());
6950c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        }
6951c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        Object* next_smi = fixed_array->get(i);
6952c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        if (!next_smi->IsSmi()) {
69534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          return isolate->Throw(isolate->heap()->illegal_argument_string());
6954c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        }
6955c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        pos = Smi::cast(next_smi)->value();
6956c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        if (pos < 0) {
69574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          return isolate->Throw(isolate->heap()->illegal_argument_string());
6958c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        }
695943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
6960c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      ASSERT(pos >= 0);
6961c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      ASSERT(len >= 0);
6962c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      if (pos > special_length || len > special_length - pos) {
69634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        return isolate->Throw(isolate->heap()->illegal_argument_string());
6964c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      }
6965c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      increment = len;
696643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else if (elt->IsString()) {
696743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      String* element = String::cast(elt);
6968bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int element_length = element->length();
69690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      increment = element_length;
6970f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      if (one_byte && !element->HasOnlyOneByteChars()) {
697159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        one_byte = false;
69729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      }
697343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
69742c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org      ASSERT(!elt->IsTheHole());
69754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->Throw(isolate->heap()->illegal_argument_string());
697643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
69770c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if (increment > String::kMaxLength - position) {
6978ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->context()->mark_out_of_memory();
697959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      return Failure::OutOfMemoryException(0x15);
69809d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
69810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    position += increment;
698243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
698343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
698443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = position;
698543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* object;
69865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
698759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (one_byte) {
6988ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    { MaybeObject* maybe_object =
69898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          isolate->heap()->AllocateRawOneByteString(length);
6990303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_object->ToObject(&object)) return maybe_object;
6991303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6992fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    SeqOneByteString* answer = SeqOneByteString::cast(object);
69935a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    StringBuilderConcatHelper(special,
69945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              answer->GetChars(),
69955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              fixed_array,
69965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              array_length);
69975a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    return answer;
699843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
6999ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    { MaybeObject* maybe_object =
7000ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->heap()->AllocateRawTwoByteString(length);
7001303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_object->ToObject(&object)) return maybe_object;
7002303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
70035a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    SeqTwoByteString* answer = SeqTwoByteString::cast(object);
70045a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    StringBuilderConcatHelper(special,
70055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              answer->GetChars(),
70065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              fixed_array,
70075a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              array_length);
70085a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    return answer;
700943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
701043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
701143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
701243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7013c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
701479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
701549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  ASSERT(args.length() == 3);
7016f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, array, 0);
701749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (!args[1]->IsSmi()) {
7018ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->context()->mark_out_of_memory();
701959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return Failure::OutOfMemoryException(0x16);
702049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
70216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int array_length = args.smi_at(1);
7022f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, separator, 2);
702349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
7024830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (!array->HasFastObjectElements()) {
70254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
702649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
702749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  FixedArray* fixed_array = FixedArray::cast(array->elements());
702849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (fixed_array->length() < array_length) {
702949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    array_length = fixed_array->length();
703049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
703149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
703249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (array_length == 0) {
7033ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->empty_string();
703449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  } else if (array_length == 1) {
703549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    Object* first = fixed_array->get(0);
703649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    if (first->IsString()) return first;
703749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
703849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
703949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int separator_length = separator->length();
704049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int max_nof_separators =
704149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      (String::kMaxLength + separator_length - 1) / separator_length;
704249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (max_nof_separators < (array_length - 1)) {
7043ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->context()->mark_out_of_memory();
704459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      return Failure::OutOfMemoryException(0x17);
704549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
704649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int length = (array_length - 1) * separator_length;
704749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  for (int i = 0; i < array_length; i++) {
704849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    Object* element_obj = fixed_array->get(i);
704949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    if (!element_obj->IsString()) {
705049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      // TODO(1161): handle this case.
70514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->Throw(isolate->heap()->illegal_argument_string());
705249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    }
705349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String* element = String::cast(element_obj);
705449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    int increment = element->length();
705549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    if (increment > String::kMaxLength - length) {
7056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->context()->mark_out_of_memory();
705759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      return Failure::OutOfMemoryException(0x18);
705849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    }
705949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    length += increment;
706049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
706149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
706249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  Object* object;
7063ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_object =
7064ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->heap()->AllocateRawTwoByteString(length);
706549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    if (!maybe_object->ToObject(&object)) return maybe_object;
706649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
706749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  SeqTwoByteString* answer = SeqTwoByteString::cast(object);
706849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
706949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  uc16* sink = answer->GetChars();
707049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org#ifdef DEBUG
707149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  uc16* end = sink + length;
707249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org#endif
707349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
707449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  String* first = String::cast(fixed_array->get(0));
707549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int first_length = first->length();
707649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  String::WriteToFlat(first, sink, 0, first_length);
707749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  sink += first_length;
707849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
707949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  for (int i = 1; i < array_length; i++) {
708049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    ASSERT(sink + separator_length <= end);
708149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String::WriteToFlat(separator, sink, 0, separator_length);
708249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    sink += separator_length;
708349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
708449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String* element = String::cast(fixed_array->get(i));
708549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    int element_length = element->length();
708649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    ASSERT(sink + element_length <= end);
708749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String::WriteToFlat(element, sink, 0, element_length);
708849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    sink += element_length;
708949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
709049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  ASSERT(sink == end);
709149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
709259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Use %_FastAsciiArrayJoin instead.
709359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(!answer->IsOneByteRepresentation());
709449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  return answer;
709549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org}
709649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
70978e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgtemplate <typename Char>
70988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgstatic void JoinSparseArrayWithSeparator(FixedArray* elements,
70998e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         int elements_length,
71008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         uint32_t array_length,
71018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         String* separator,
71028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         Vector<Char> buffer) {
71038e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int previous_separator_position = 0;
71048e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int separator_length = separator->length();
71058e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int cursor = 0;
71068e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  for (int i = 0; i < elements_length; i += 2) {
71078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int position = NumberToInt32(elements->get(i));
71088e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    String* string = String::cast(elements->get(i + 1));
71098e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int string_length = string->length();
71108e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (string->length() > 0) {
71118e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      while (previous_separator_position < position) {
71128e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        String::WriteToFlat<Char>(separator, &buffer[cursor],
71138e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                  0, separator_length);
71148e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        cursor += separator_length;
71158e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        previous_separator_position++;
71168e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      }
71178e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      String::WriteToFlat<Char>(string, &buffer[cursor],
71188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                0, string_length);
71198e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      cursor += string->length();
71208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
71218e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
71228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (separator_length > 0) {
71238e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Array length must be representable as a signed 32-bit number,
71248e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // otherwise the total string length would have been too large.
71258e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
71268e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int last_array_index = static_cast<int>(array_length - 1);
71278e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    while (previous_separator_position < last_array_index) {
71288e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      String::WriteToFlat<Char>(separator, &buffer[cursor],
71298e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                0, separator_length);
71308e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      cursor += separator_length;
71318e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      previous_separator_position++;
71328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
71338e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
71348e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ASSERT(cursor <= buffer.length());
71358e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
71368e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
71378e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
71388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
713979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
71408e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ASSERT(args.length() == 3);
7141f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
7142830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
71438e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
7144f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, separator, 2);
71458e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // elements_array is fast-mode JSarray of alternating positions
71468e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // (increasing order) and strings.
71478e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // array_length is length of original array (used to add separators);
71488e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // separator is string to put between elements. Assumed to be non-empty.
71498e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
71508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Find total length of join result.
71518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int string_length = 0;
71528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  bool is_ascii = separator->IsOneByteRepresentation();
715304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  int max_string_length;
715404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  if (is_ascii) {
7155fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    max_string_length = SeqOneByteString::kMaxLength;
715604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  } else {
715704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    max_string_length = SeqTwoByteString::kMaxLength;
715804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  }
71598e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  bool overflow = false;
71608e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  CONVERT_NUMBER_CHECKED(int, elements_length,
71618e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                         Int32, elements_array->length());
71628e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
71638e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  FixedArray* elements = FixedArray::cast(elements_array->elements());
71648e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  for (int i = 0; i < elements_length; i += 2) {
71658e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    RUNTIME_ASSERT(elements->get(i)->IsNumber());
7166f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    RUNTIME_ASSERT(elements->get(i + 1)->IsString());
7167f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    String* string = String::cast(elements->get(i + 1));
71688e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int length = string->length();
71698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (is_ascii && !string->IsOneByteRepresentation()) {
71708e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      is_ascii = false;
71718e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      max_string_length = SeqTwoByteString::kMaxLength;
71728e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
71738e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (length > max_string_length ||
71748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        max_string_length - length < string_length) {
71758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      overflow = true;
71768e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      break;
71778e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
71788e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    string_length += length;
71798e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
71808e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int separator_length = separator->length();
71818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (!overflow && separator_length > 0) {
71828e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (array_length <= 0x7fffffffu) {
71838e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      int separator_count = static_cast<int>(array_length) - 1;
71848e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      int remaining_length = max_string_length - string_length;
71858e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      if ((remaining_length / separator_length) >= separator_count) {
71868e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        string_length += separator_length * (array_length - 1);
71878e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      } else {
71888e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        // Not room for the separators within the maximal string length.
71898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        overflow = true;
71908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      }
71918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    } else {
71928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      // Nonempty separator and at least 2^31-1 separators necessary
71938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      // means that the string is too large to create.
71948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
71958e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      overflow = true;
71968e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
71978e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
71988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (overflow) {
71998e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Throw OutOfMemory exception for creating too large a string.
72008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    V8::FatalProcessOutOfMemory("Array join result too large.");
72018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
72028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
72038e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (is_ascii) {
72048e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    MaybeObject* result_allocation =
72058e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        isolate->heap()->AllocateRawOneByteString(string_length);
72068e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (result_allocation->IsFailure()) return result_allocation;
7207fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    SeqOneByteString* result_string =
7208fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        SeqOneByteString::cast(result_allocation->ToObjectUnchecked());
720959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    JoinSparseArrayWithSeparator<uint8_t>(elements,
721059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                          elements_length,
721159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                          array_length,
721259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                          separator,
721359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                          Vector<uint8_t>(
721459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                              result_string->GetChars(),
721559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                              string_length));
72168e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    return result_string;
72178e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  } else {
72188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    MaybeObject* result_allocation =
72198e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        isolate->heap()->AllocateRawTwoByteString(string_length);
72208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (result_allocation->IsFailure()) return result_allocation;
72218e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    SeqTwoByteString* result_string =
72228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        SeqTwoByteString::cast(result_allocation->ToObjectUnchecked());
72238e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    JoinSparseArrayWithSeparator<uc16>(elements,
72248e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                       elements_length,
72258e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                       array_length,
72268e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                       separator,
72278e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                       Vector<uc16>(result_string->GetChars(),
72288e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                                    string_length));
72298e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    return result_string;
72308e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
72318e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
72328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
723349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
7234c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberOr) {
723579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
723643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
723743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
723843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
723943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromInt32(x | y);
724143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
724243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
724343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7244c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAnd) {
724579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
724643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
724743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
724843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
724943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7250ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromInt32(x & y);
725143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
725243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
725343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7254c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) {
725579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
725643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
725743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
725843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
725943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7260ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromInt32(x ^ y);
726143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
726243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
726343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7264c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) {
726579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
726643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
726743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
726843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
726943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7270ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromInt32(x << (y & 0x1f));
727143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
727243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
727343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7274c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShr) {
727579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
727643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
727743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
727843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
727943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7280ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromUint32(x >> (y & 0x1f));
728143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
728243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
728343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7284c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSar) {
728579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
728643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
728743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
728843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
728943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7290ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
729143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
729243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
729343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7294c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
729579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
729643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
729743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
72996d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
730077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
730177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
730243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (x == y) return Smi::FromInt(EQUAL);
730343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* result;
730443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
730543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = Smi::FromInt(EQUAL);
730643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
730743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = Smi::FromInt(NOT_EQUAL);
730843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
730943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
731043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
731143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
731243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7313c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
731479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
731543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
731643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7317f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, x, 0);
7318f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, y, 1);
731943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73205a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  bool not_equal = !x->Equals(y);
73215a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // This is slightly convoluted because the value that signifies
73225a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // equality is 0 and inequality is 1 so we have to negate the result
73235a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // from String::Equals.
73245a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  ASSERT(not_equal == 0 || not_equal == 1);
73255a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  STATIC_CHECK(EQUAL == 0);
73265a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  STATIC_CHECK(NOT_EQUAL == 1);
73275a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return Smi::FromInt(not_equal);
732843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
732943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
733043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7331c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
733279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
733343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
733443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
73366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
733777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(x) || std::isnan(y)) return args[2];
733843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (x == y) return Smi::FromInt(EQUAL);
733943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (isless(x, y)) return Smi::FromInt(LESS);
734043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(GREATER);
734143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
734243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
734343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73449258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Compare two Smis as if they were converted to strings and then
73459258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// compared lexicographically.
7346c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
734779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
73489258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  ASSERT(args.length() == 2);
7349f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(x_value, 0);
7350f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(y_value, 1);
73519258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
73529258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // If the integers are equal so are the string representations.
73539258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (x_value == y_value) return Smi::FromInt(EQUAL);
73549258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
73553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // If one of the integers is zero the normal integer order is the
73569258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // same as the lexicographic order of the string representations.
73573cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_value == 0 || y_value == 0)
73583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    return Smi::FromInt(x_value < y_value ? LESS : GREATER);
73599258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
73603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // If only one of the integers is negative the negative number is
73619258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // smallest because the char code of '-' is less than the char code
73629258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // of any digit.  Otherwise, we make both values positive.
73633cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
73643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
73653cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // architectures using 32-bit Smis.
73663cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  uint32_t x_scaled = x_value;
73673cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  uint32_t y_scaled = y_value;
73689258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (x_value < 0 || y_value < 0) {
73699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    if (y_value >= 0) return Smi::FromInt(LESS);
73709258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    if (x_value >= 0) return Smi::FromInt(GREATER);
73713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    x_scaled = -x_value;
73723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    y_scaled = -y_value;
73739258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
73749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
73753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  static const uint32_t kPowersOf10[] = {
73763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    1, 10, 100, 1000, 10*1000, 100*1000,
73773cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    1000*1000, 10*1000*1000, 100*1000*1000,
73783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    1000*1000*1000
73793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  };
73803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
73813cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // If the integers have the same number of decimal digits they can be
73823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // compared directly as the numeric order is the same as the
73833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // lexicographic order.  If one integer has fewer digits, it is scaled
73843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // by some power of 10 to have the same number of digits as the longer
73853cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // integer.  If the scaled integers are equal it means the shorter
73863cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // integer comes first in the lexicographic order.
7387ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
73883cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
73893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int x_log2 = IntegerLog2(x_scaled);
73903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int x_log10 = ((x_log2 + 1) * 1233) >> 12;
73913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  x_log10 -= x_scaled < kPowersOf10[x_log10];
7392ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
73933cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int y_log2 = IntegerLog2(y_scaled);
73943cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int y_log10 = ((y_log2 + 1) * 1233) >> 12;
73953cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  y_log10 -= y_scaled < kPowersOf10[y_log10];
73969258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
73973cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int tie = EQUAL;
73983cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
73993cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_log10 < y_log10) {
74003cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // X has fewer digits.  We would like to simply scale up X but that
74013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
74023cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // be scaled up to 9_000_000_000. So we scale up by the next
74033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // smallest power and scale down Y to drop one digit. It is OK to
74043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // drop one digit from the longer integer since the final digit is
74053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // past the length of the shorter integer.
74063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
74073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    y_scaled /= 10;
74083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    tie = LESS;
74093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  } else if (y_log10 < x_log10) {
74103cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
74113cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    x_scaled /= 10;
74123cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    tie = GREATER;
74139258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
74149258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
74153cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
74163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
74173cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  return Smi::FromInt(tie);
74189258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
74199258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
74209258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
74214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgstatic Object* StringCharacterStreamCompare(RuntimeState* state,
7422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        String* x,
7423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        String* y) {
74244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream_x(x, state->string_iterator_compare_x());
74254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream_y(y, state->string_iterator_compare_y());
74264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  while (stream_x.HasMore() && stream_y.HasMore()) {
74274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    int d = stream_x.GetNext() - stream_y.GetNext();
7428ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (d < 0) return Smi::FromInt(LESS);
7429ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    else if (d > 0) return Smi::FromInt(GREATER);
7430ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7431ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7432ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // x is (non-trivial) prefix of y:
74334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  if (stream_y.HasMore()) return Smi::FromInt(LESS);
7434ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // y is prefix of x:
74354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL);
7436ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7437ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7438ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7439ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgstatic Object* FlatStringCompare(String* x, String* y) {
7440ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(x->IsFlat());
7441ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(y->IsFlat());
7442ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Object* equal_prefix_result = Smi::FromInt(EQUAL);
7443ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int prefix_length = x->length();
7444ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (y->length() < prefix_length) {
7445ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    prefix_length = y->length();
7446ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    equal_prefix_result = Smi::FromInt(GREATER);
7447ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else if (y->length() > prefix_length) {
7448ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    equal_prefix_result = Smi::FromInt(LESS);
7449ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7450ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int r;
745179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
7452ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent x_content = x->GetFlatContent();
7453ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent y_content = y->GetFlatContent();
7454ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (x_content.IsAscii()) {
745559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
7456ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (y_content.IsAscii()) {
745759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7458086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7459ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    } else {
7460ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      Vector<const uc16> y_chars = y_content.ToUC16Vector();
7461ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7462ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
7463ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7464ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    Vector<const uc16> x_chars = x_content.ToUC16Vector();
7465ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (y_content.IsAscii()) {
746659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7467ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7468ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    } else {
7469ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      Vector<const uc16> y_chars = y_content.ToUC16Vector();
7470ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7471ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
7472ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7473ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Object* result;
7474ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (r == 0) {
7475ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    result = equal_prefix_result;
7476ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7477ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7478ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7479ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(result ==
74804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      StringCharacterStreamCompare(Isolate::Current()->runtime_state(), x, y));
7481ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return result;
7482ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7483ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7484ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7485c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) {
748679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
748743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
748843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7489f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, x, 0);
7490f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, y, 1);
749143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7492ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->string_compare_runtime()->Increment();
74930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
749443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // A few fast case tests before we flatten.
749543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (x == y) return Smi::FromInt(EQUAL);
7496bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (y->length() == 0) {
7497bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (x->length() == 0) return Smi::FromInt(EQUAL);
749843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Smi::FromInt(GREATER);
7499bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else if (x->length() == 0) {
750043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Smi::FromInt(LESS);
750143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
75029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
7503bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int d = x->Get(0) - y->Get(0);
75049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (d < 0) return Smi::FromInt(LESS);
75059a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  else if (d > 0) return Smi::FromInt(GREATER);
750643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7507303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
7508ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
7509303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7510303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
7511ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
7512303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7513303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
751443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7515ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
75164cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      : StringCharacterStreamCompare(isolate->runtime_state(), x, y);
751743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
751843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7520c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
752179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
752243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7523ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_acos()->Increment();
752443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7526ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
752743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
752843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7530c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
753179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
753243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7533ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_asin()->Increment();
753443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7536ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
753743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
753843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
753943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7540c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
754179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
754243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7543ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_atan()->Increment();
754443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75456d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7546ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
754743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
754843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
754943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7550ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const double kPiDividedBy4 = 0.78539816339744830962;
7551ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
7552ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
7553c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
755479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
755543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
7556ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_atan2()->Increment();
755743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
75596d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
756043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  double result;
756177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isinf(x) && std::isinf(y)) {
756243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Make sure that the result in case of two infinite arguments
756343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is a multiple of Pi / 4. The sign of the result is determined
756443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // by the first argument (x) and the sign of the second argument
756543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // determines the multiplier: one or three.
756643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int multiplier = (x < 0) ? -1 : 1;
756743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (y < 0) multiplier *= 3;
756843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = multiplier * kPiDividedBy4;
756943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
757043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = atan2(x, y);
757143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
7572ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->AllocateHeapNumber(result);
757343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
757443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
757543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7576c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
757779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
757843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7579ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_ceil()->Increment();
758043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7582ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(ceiling(x));
758343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
758443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
758543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7586c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
758779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
758843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7589ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_cos()->Increment();
759043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7592ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
759343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
759443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
759543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7596c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
759779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
759843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7599ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_exp()->Increment();
760043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
76016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
76021f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  lazily_initialize_fast_exp();
76031f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  return isolate->heap()->NumberFromDouble(fast_exp(x));
760443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
760543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
760643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7607c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
760879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
760943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7610ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_floor()->Increment();
761143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
76126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7613ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(floor(x));
761443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
761543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
761643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7617c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
761879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
761943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7620ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_log()->Increment();
762143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
76226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7623ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
762443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
762543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7626e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
762764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// Slow version of Math.pow.  We check for fast paths for special cases.
762864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// Used if SSE2/VFP3 is not available.
7629c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
763079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
763143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
7632ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_pow()->Increment();
763343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
76346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
76355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
76365aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // If the second argument is a smi, it is much faster to call the
76375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // custom powi() function than the generic pow().
76385aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (args[1]->IsSmi()) {
76396d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int y = args.smi_at(1);
7640ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->NumberFromDouble(power_double_int(x, y));
76415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
76425aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
76436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
76442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  double result = power_helper(x, y);
764577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(result)) return isolate->heap()->nan_value();
764664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  return isolate->heap()->AllocateHeapNumber(result);
764743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
764843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7649e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
765064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// Fast version of Math.pow if we know that y is not an integer and y is not
76512efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// -0.5 or 0.5.  Used as slow case from full codegen.
7652c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
765379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
7654ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
765564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  isolate->counters()->math_pow()->Increment();
765664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
76576d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
76586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7659ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (y == 0) {
76605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    return Smi::FromInt(1);
7661ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
766264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    double result = power_double_double(x, y);
766377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    if (std::isnan(result)) return isolate->heap()->nan_value();
766464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    return isolate->heap()->AllocateHeapNumber(result);
7665ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7666ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7667ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
766843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7669c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RoundNumber) {
767079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
767143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7672ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_round()->Increment();
767343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7674cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  if (!args[0]->IsHeapNumber()) {
7675cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    // Must be smi. Return the argument unchanged for all the other types
7676cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    // to make fuzz-natives test happy.
7677cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    return args[0];
7678cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
7679cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7680cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
7681cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7682cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  double value = number->value();
7683cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  int exponent = number->get_exponent();
7684cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  int sign = number->get_sign();
7685cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7686160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (exponent < -1) {
7687160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    // Number in range ]-0.5..0.5[. These always round to +/-zero.
7688160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (sign) return isolate->heap()->minus_zero_value();
7689160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    return Smi::FromInt(0);
7690160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  }
7691160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
7692160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
7693160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
76942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // argument holds for 32-bit smis).
7695160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (!sign && exponent < kSmiValueSize - 2) {
7696cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    return Smi::FromInt(static_cast<int>(value + 0.5));
7697cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
7698cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7699cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  // If the magnitude is big enough, there's no place for fraction part. If we
7700cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  // try to add 0.5 to this number, 1.0 will be added instead.
7701cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  if (exponent >= 52) {
7702cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    return number;
7703cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
7704cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7705ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
7706cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
77074111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // Do not call NumberFromDouble() to avoid extra checks.
7708ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->AllocateHeapNumber(floor(value + 0.5));
770943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
771043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
771143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7712c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
771379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
771443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7715ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_sin()->Increment();
771643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77176d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7718ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
771943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
772043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
772143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7722c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
772379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
772443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7725ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_sqrt()->Increment();
772643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7728154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  return isolate->heap()->AllocateHeapNumber(fast_sqrt(x));
772943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
773043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
773143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7732c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
773379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
773443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7735ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_tan()->Increment();
773643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7738ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
773943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
774043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
774143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7742c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
774379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
7744c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(args.length() == 2);
7745f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
77466d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(year, 0);
77476d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(month, 1);
7748f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
77494efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
7750f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
7751f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
7752f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
77534efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
77544efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  HandleScope scope(isolate);
77554efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  ASSERT(args.length() == 3);
7756f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
77574efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
77584efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(time, 1);
77594efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(is_utc, 2);
77604efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
77614efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  DateCache* date_cache = isolate->date_cache();
77624efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
77634efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  Object* value = NULL;
77644efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  bool is_value_nan = false;
776577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(time)) {
77664efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    value = isolate->heap()->nan_value();
77674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    is_value_nan = true;
77684efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  } else if (!is_utc &&
77694efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org             (time < -DateCache::kMaxTimeBeforeUTCInMs ||
77704efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org              time > DateCache::kMaxTimeBeforeUTCInMs)) {
77714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    value = isolate->heap()->nan_value();
77724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    is_value_nan = true;
7773f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  } else {
77744efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
77754efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    if (time < -DateCache::kMaxTimeInMs ||
77764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org        time > DateCache::kMaxTimeInMs) {
77774efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      value = isolate->heap()->nan_value();
77784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      is_value_nan = true;
77794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    } else  {
77804efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      MaybeObject* maybe_result =
77814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org          isolate->heap()->AllocateHeapNumber(DoubleToInteger(time));
77824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      if (!maybe_result->ToObject(&value)) return maybe_result;
77834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    }
7784f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  }
77854efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  date->SetValue(value, is_value_nan);
77861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  return value;
7787ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7788ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7789ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7790c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
77917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  HandleScope scope(isolate);
77927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(args.length() == 3);
77937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
77947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Handle<JSFunction> callee = args.at<JSFunction>(0);
77957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Object** parameters = reinterpret_cast<Object**>(args[1]);
77967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  const int argument_count = Smi::cast(args[2])->value();
77977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
77987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Handle<JSObject> result =
77997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      isolate->factory()->NewArgumentsObject(callee, argument_count);
78007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Allocate the elements if needed.
78017b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int parameter_count = callee->shared()->formal_parameter_count();
78027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (argument_count > 0) {
78037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (parameter_count > 0) {
78047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      int mapped_count = Min(argument_count, parameter_count);
78057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<FixedArray> parameter_map =
78067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
78077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      parameter_map->set_map(
78087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->heap()->non_strict_arguments_elements_map());
78097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<Map> old_map(result->map());
7811753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      Handle<Map> new_map = isolate->factory()->CopyMap(old_map);
781283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
78137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      result->set_map(*new_map);
78157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      result->set_elements(*parameter_map);
78167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78177b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Store the context and the arguments array at the beginning of the
78187b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // parameter map.
78197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<Context> context(isolate->context());
78207b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<FixedArray> arguments =
78217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
78227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      parameter_map->set(0, *context);
78237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      parameter_map->set(1, *arguments);
78247b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Loop over the actual parameters backwards.
78267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      int index = argument_count - 1;
78277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      while (index >= mapped_count) {
78287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // These go directly in the arguments array and have no
78297b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // corresponding slot in the parameter map.
78307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        arguments->set(index, *(parameters - index - 1));
78317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        --index;
78327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
78337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
7834c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
78357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      while (index >= 0) {
78367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // Detect duplicate names to the right in the parameter list.
7837c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        Handle<String> name(scope_info->ParameterName(index));
7838c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int context_local_count = scope_info->ContextLocalCount();
78397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        bool duplicate = false;
78407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        for (int j = index + 1; j < parameter_count; ++j) {
7841c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (scope_info->ParameterName(j) == *name) {
78427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            duplicate = true;
78437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            break;
78447b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
78457b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
78467b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        if (duplicate) {
78487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // This goes directly in the arguments array with a hole in the
78497b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // parameter map.
78507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          arguments->set(index, *(parameters - index - 1));
78517b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          parameter_map->set_the_hole(index + 2);
78527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        } else {
78537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // The context index goes in the parameter map with a hole in the
78547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // arguments array.
78557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          int context_index = -1;
7856c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          for (int j = 0; j < context_local_count; ++j) {
7857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            if (scope_info->ContextLocalName(j) == *name) {
78587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org              context_index = j;
78597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org              break;
78607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            }
78617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
78627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          ASSERT(context_index >= 0);
78637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          arguments->set_the_hole(index);
7864c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          parameter_map->set(index + 2, Smi::FromInt(
7865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              Context::MIN_CONTEXT_SLOTS + context_index));
78667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
78677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        --index;
78697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
78707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
78717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // If there is no aliasing, the arguments object elements are not
78727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // special in any way.
78737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<FixedArray> elements =
78747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
78757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      result->set_elements(*elements);
78767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      for (int i = 0; i < argument_count; ++i) {
78777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        elements->set(i, *(parameters - i - 1));
78787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
78797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
78807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
78817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return *result;
78827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
78837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
78857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
788679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
788741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  ASSERT(args.length() == 3);
788841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
788941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  JSFunction* callee = JSFunction::cast(args[0]);
789041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  Object** parameters = reinterpret_cast<Object**>(args[1]);
78916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  const int length = args.smi_at(2);
789241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
7893303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
7894ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result =
7895ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->heap()->AllocateArgumentsObject(callee, length);
7896303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
7897303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
78989fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // Allocate the elements if needed.
78999fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (length > 0) {
79009fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    // Allocate the fixed array.
7901303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* obj;
7902ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    { MaybeObject* maybe_obj = isolate->heap()->AllocateRawFixedArray(length);
7903303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7904303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
7905b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
790679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
790730ce411529579186181838984710b0b0980857aaricow@chromium.org    FixedArray* array = reinterpret_cast<FixedArray*>(obj);
790864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    array->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
79099fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    array->set_length(length);
7910b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
7911b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
79129fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    for (int i = 0; i < length; i++) {
79139fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org      array->set(i, *--parameters, mode);
79149fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    }
7915c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    JSObject::cast(result)->set_elements(FixedArray::cast(obj));
791641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  }
791741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  return result;
791841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org}
791941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
792041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
7921c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
7922ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
792321b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  ASSERT(args.length() == 3);
7924f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
7925f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
7926f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
792743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // The caller ensures that we pretenure closures that are assigned
792921b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  // directly to properties.
793021b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
793143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<JSFunction> result =
7932ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
7933ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                            context,
7934ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                            pretenure_flag);
793543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
793643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
793743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7938c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7939394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Find the arguments of the JavaScript function invocation that called
7940394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// into C++ code. Collect these in a newly allocated array of handles (possibly
7941394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// prefixed by a number of empty handles).
7942394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic SmartArrayPointer<Handle<Object> > GetCallerArguments(
7943c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    Isolate* isolate,
7944394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int prefix_argc,
7945a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    int* total_argc) {
7946c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // Find frame containing arguments passed to the caller.
7947c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  JavaScriptFrameIterator it(isolate);
7948c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  JavaScriptFrame* frame = it.frame();
7949c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  List<JSFunction*> functions(2);
7950c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  frame->GetFunctions(&functions);
7951c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (functions.length() > 1) {
7952659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int inlined_jsframe_index = functions.length() - 1;
7953659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JSFunction* inlined_function = functions[inlined_jsframe_index];
7954659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Vector<SlotRef> args_slots =
7955659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        SlotRef::ComputeSlotMappingForArguments(
7956659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org            frame,
7957659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org            inlined_jsframe_index,
7958659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org            inlined_function->shared()->formal_parameter_count());
7959659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
7960659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int args_count = args_slots.length();
7961c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7962394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *total_argc = prefix_argc + args_count;
7963a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    SmartArrayPointer<Handle<Object> > param_data(
7964a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        NewArray<Handle<Object> >(*total_argc));
7965c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    for (int i = 0; i < args_count; i++) {
796609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      Handle<Object> val = args_slots[i].GetValue(isolate);
7967394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      param_data[prefix_argc + i] = val;
7968c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
7969659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
7970659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    args_slots.Dispose();
7971659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
7972c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return param_data;
7973c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  } else {
7974c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    it.AdvanceToArgumentsFrame();
7975c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    frame = it.frame();
7976c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    int args_count = frame->ComputeParametersCount();
7977c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7978394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *total_argc = prefix_argc + args_count;
7979a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    SmartArrayPointer<Handle<Object> > param_data(
7980a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        NewArray<Handle<Object> >(*total_argc));
7981c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    for (int i = 0; i < args_count; i++) {
798209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
7983394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      param_data[prefix_argc + i] = val;
7984c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
7985c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return param_data;
7986c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
7987c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
7988c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7989c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7990394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
7991394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
7992394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 4);
7993f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
7994394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  RUNTIME_ASSERT(args[3]->IsNumber());
7995394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Object> bindee = args.at<Object>(1);
7996394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
7997394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // TODO(lrn): Create bound function in C++ code from premade shared info.
7998394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bound_function->shared()->set_bound(true);
7999394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Get all arguments of calling function (Function.prototype.bind).
8000394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int argc = 0;
8001c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  SmartArrayPointer<Handle<Object> > arguments =
8002c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      GetCallerArguments(isolate, 0, &argc);
8003394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Don't count the this-arg.
8004394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (argc > 0) {
8005394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ASSERT(*arguments[0] == args[2]);
8006394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    argc--;
8007394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
8008394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ASSERT(args[2]->IsUndefined());
8009394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8010394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Initialize array of bindings (function, this, and any existing arguments
8011394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // if the function was already bound).
8012394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArray> new_bindings;
8013394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int i;
8014394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
8015394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<FixedArray> old_bindings(
8016394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        JSFunction::cast(*bindee)->function_bindings());
8017394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings =
8018394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        isolate->factory()->NewFixedArray(old_bindings->length() + argc);
801909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
802009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                            isolate);
8021394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    i = 0;
8022394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    for (int n = old_bindings->length(); i < n; i++) {
8023394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      new_bindings->set(i, old_bindings->get(i));
8024394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
8025394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
8026394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
8027394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings = isolate->factory()->NewFixedArray(array_size);
8028394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
8029394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings->set(JSFunction::kBoundThisIndex, args[2]);
8030394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    i = 2;
8031394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8032394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Copy arguments, skipping the first which is "this_arg".
8033394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (int j = 0; j < argc; j++, i++) {
8034394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings->set(i, *arguments[j + 1]);
8035394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
803664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  new_bindings->set_map_no_write_barrier(
803764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      isolate->heap()->fixed_cow_array_map());
8038394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bound_function->set_function_bindings(*new_bindings);
8039394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8040394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Update length.
80414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> length_string = isolate->factory()->length_string();
8042394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Object> new_length(args.at<Object>(3));
8043394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PropertyAttributes attr =
8044394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
80454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  ForceSetProperty(bound_function, length_string, new_length, attr);
8046394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *bound_function;
8047394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
8048394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8049394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8050394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
8051394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope handles(isolate);
8052394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
8053f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
8054394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (callable->IsJSFunction()) {
8055394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
8056394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (function->shared()->bound()) {
8057394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> bindings(function->function_bindings());
8058394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
8059394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      return *isolate->factory()->NewJSArrayWithElements(bindings);
8060394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
8061394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8062394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return isolate->heap()->undefined_value();
8063394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
8064394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8065394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8066c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
8067ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8068394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
8069d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // First argument is a function to use as a constructor.
8070f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8071394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  RUNTIME_ASSERT(function->shared()->bound());
8072394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8073394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // The argument is a bound function. Extract its bound arguments
8074394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // and callable.
8075394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArray> bound_args =
8076394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
8077394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
8078394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Object> bound_function(
807909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
808009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      isolate);
8081394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(!bound_function->IsJSFunction() ||
8082394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com         !Handle<JSFunction>::cast(bound_function)->shared()->bound());
8083ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
8084c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  int total_argc = 0;
8085a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  SmartArrayPointer<Handle<Object> > param_data =
8086c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      GetCallerArguments(isolate, bound_argc, &total_argc);
8087d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  for (int i = 0; i < bound_argc; i++) {
8088394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    param_data[i] = Handle<Object>(bound_args->get(
808909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        JSFunction::kBoundArgumentsStartIndex + i), isolate);
8090ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  }
8091ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
8092394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (!bound_function->IsJSFunction()) {
8093394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bool exception_thrown;
8094394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bound_function = Execution::TryGetConstructorDelegate(bound_function,
8095394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                                          &exception_thrown);
8096394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (exception_thrown) return Failure::Exception();
8097394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8098394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(bound_function->IsJSFunction());
8099394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8100e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  bool exception = false;
8101d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  Handle<Object> result =
8102394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Execution::New(Handle<JSFunction>::cast(bound_function),
8103394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                     total_argc, *param_data, &exception);
8104e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  if (exception) {
8105394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return Failure::Exception();
8106e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  }
8107e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  ASSERT(!result.is_null());
8108ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  return *result;
8109ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
8110ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
811143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8112c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
8113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
811443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
811543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81165aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  Handle<Object> constructor = args.at<Object>(0);
81175aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
81185aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // If the constructor isn't a proper function we throw a type error.
81195aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (!constructor->IsJSFunction()) {
81205aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
81215aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org    Handle<Object> type_error =
8122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("not_constructor", arguments);
8123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*type_error);
81245aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
812543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81265aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
81274111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
81284111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // If function should not have prototype, construction is not allowed. In this
81294111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // case generated code bailouts here, since function has no initial_map.
81307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (!function->should_have_prototype() && !function->shared()->bound()) {
81314111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
81324111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Handle<Object> type_error =
8133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("not_constructor", arguments);
8134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*type_error);
81354111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
81364111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
813765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
8138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Debug* debug = isolate->debug();
81395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Handle stepping into constructors if step into is active.
8140ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (debug->StepInActive()) {
8141ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
81425aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
814365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif
814443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81455aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (function->has_initial_map()) {
81465aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org    if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
814743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // The 'Function' function ignores the receiver object when
814843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // called using 'new' and creates a new JSFunction object that
814943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // is returned.  The receiver object is only used for error
815043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // reporting if an error occurs when constructing the new
8151d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      // JSFunction. Factory::NewJSObject() should not be used to
81525aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // allocate JSFunctions since it does not properly initialize
81535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // the shared part of the function. Since the receiver is
81545aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // ignored anyway, we use the global object as the receiver
81555aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // instead of a new JSFunction object. This way, errors are
81565aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // reported the same way whether or not 'Function' is called
81575aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // using 'new'.
815846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return isolate->context()->global_object();
815943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
816043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
816143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The function should be compiled for the optimization hints to be
81635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // available.
81645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION);
816518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
8166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<SharedFunctionInfo> shared(function->shared(), isolate);
81674a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (!function->has_initial_map() &&
81684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org      shared->IsInobjectSlackTrackingInProgress()) {
81694a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    // The tracking is already in progress for another function. We can only
81704a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    // track one initial_map at a time, so we force the completion before the
81714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    // function is called as a constructor for the first time.
81724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    shared->CompleteInobjectSlackTracking();
81734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
81744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSObject> result = isolate->factory()->NewJSObject(function);
8176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
817718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
8178ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->constructed_objects()->Increment();
8179ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->constructed_objects_runtime()->Increment();
818018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
81815aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  return *result;
818243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
818343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
818443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8185c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) {
8186ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
81874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  ASSERT(args.length() == 1);
81884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8189f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
81904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  function->shared()->CompleteInobjectSlackTracking();
81914a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8192ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
81934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
81944a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
81954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8196c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
8197ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
819843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
819943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
820043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<JSFunction> function = args.at<JSFunction>(0);
820143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
820226c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
820343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("[lazy: ");
8204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    function->PrintName();
820543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("]\n");
820643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
820743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
820843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
820934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Compile the target function.
821043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!function->is_compiled());
8211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) {
821243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Failure::Exception();
821343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
821443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // All done. Return the compiled code.
8216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(function->is_compiled());
821743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return function->code();
821843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
821943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
822043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8221750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgbool AllowOptimization(Isolate* isolate, Handle<JSFunction> function) {
822234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If the function is not compiled ignore the lazy
822334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // recompilation. This can happen if the debugger is activated and
822434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // the function is returned to the not compiled state.
8225750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (!function->shared()->is_compiled()) return false;
822634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
8227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // If the function is not optimizable or debugger is active continue using the
8228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // code from the full compiler.
822956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  if (!FLAG_crankshaft ||
8230750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      function->shared()->optimization_disabled() ||
82313847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      isolate->DebuggerHasBreakPoints()) {
8232c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (FLAG_trace_opt) {
8233c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      PrintF("[failed to optimize ");
8234c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      function->PrintName();
8235c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
8236750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org          function->shared()->optimization_disabled() ? "F" : "T",
82373847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          isolate->DebuggerHasBreakPoints() ? "T" : "F");
8238c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    }
8239750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return false;
8240750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
8241750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return true;
8242750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
8243750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
8244750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
8245750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
8246750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  HandleScope scope(isolate);
8247750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(args.length() == 1);
8248750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<JSFunction> function = args.at<JSFunction>(0);
8249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
8250750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (!AllowOptimization(isolate, function)) {
8251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    function->ReplaceCode(function->shared()->code());
8252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return function->code();
8253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
82541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  function->shared()->code()->set_profiler_ticks(0);
8255394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (JSFunction::CompileOptimized(function,
8256471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                   BailoutId::None(),
8257394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                   CLEAR_EXCEPTION)) {
8258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return function->code();
8259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8260c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  if (FLAG_trace_opt) {
8261c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    PrintF("[failed to optimize ");
8262c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    function->PrintName();
8263c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    PrintF(": optimized compilation failed]\n");
8264c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
8265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  function->ReplaceCode(function->shared()->code());
82665d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return function->code();
8267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8270304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ParallelRecompile) {
8271304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  HandleScope handle_scope(isolate);
82726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
82736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8274750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (!AllowOptimization(isolate, function)) {
8275750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    function->ReplaceCode(function->shared()->code());
82762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    return isolate->heap()->undefined_value();
8277750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
8278750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  function->shared()->code()->set_profiler_ticks(0);
8279304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  ASSERT(FLAG_parallel_recompilation);
8280750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Compiler::RecompileParallel(function);
8281fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  return isolate->heap()->undefined_value();
8282fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
8283fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
8284fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
8285fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) {
8286fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  HandleScope handle_scope(isolate);
82876e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
82886e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
82892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation);
82901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
82916e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  return function->code();
8292304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}
8293304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
8294304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
8295b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgclass ActivationsFinder : public ThreadVisitor {
8296b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org public:
829721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  Code* code_;
829821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  bool has_code_activations_;
829921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org
830021af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  explicit ActivationsFinder(Code* code)
830121af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    : code_(code),
830221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      has_code_activations_(false) { }
8303b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
8304b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
830521af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    JavaScriptFrameIterator it(isolate, top);
830621af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    VisitFrames(&it);
830721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  }
8308b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
830921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  void VisitFrames(JavaScriptFrameIterator* it) {
831021af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    for (; !it->done(); it->Advance()) {
831121af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      JavaScriptFrame* frame = it->frame();
831221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      if (code_->contains(frame->pc())) has_code_activations_ = true;
8313b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
8314b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
8315b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org};
8316b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
8317b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
831859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) {
8319a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HandleScope scope(isolate);
8320a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(args.length() == 0);
8321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
832279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(AllowHeapAllocation::IsAllowed());
8323a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  delete deoptimizer;
8324a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return isolate->heap()->undefined_value();
8325a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
8326a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
8327a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
8328c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
8329ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
8331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RUNTIME_ASSERT(args[0]->IsSmi());
8332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Deoptimizer::BailoutType type =
83336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
8334ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
833579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(AllowHeapAllocation::IsAllowed());
8336a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
833721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  Handle<JSFunction> function = deoptimizer->function();
833821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  Handle<Code> optimized_code = deoptimizer->compiled_code();
833921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org
834021af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
834121af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  ASSERT(type == deoptimizer->bailout_type());
8342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
834356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  // Make sure to materialize objects before causing any allocation.
8344a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  JavaScriptFrameIterator it(isolate);
834556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  deoptimizer->MaterializeHeapObjects(&it);
834644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  delete deoptimizer;
834744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
8348154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  JavaScriptFrame* frame = it.frame();
8349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RUNTIME_ASSERT(frame->function()->IsJSFunction());
8350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Avoid doing too much work when running with --always-opt and keep
8352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // the optimized code around.
8353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8354ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
8355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
835721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  // Search for other activations of the same function and code.
835821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  ActivationsFinder activations_finder(*optimized_code);
835921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  activations_finder.VisitFrames(&it);
836021af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
8361b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
836221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  if (!activations_finder.has_code_activations_) {
836321af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    if (function->code() == *optimized_code) {
836421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      if (FLAG_trace_deopt) {
836521af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org        PrintF("[removing optimized code for: ");
836621af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org        function->PrintName();
836721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org        PrintF("]\n");
836821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      }
836921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org      function->ReplaceCode(function->shared()->code());
8370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
837134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  } else {
837221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
837321af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    // unconditionally if the code is not already marked for deoptimization.
837421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org    // If there is an index by shared function info, all the better.
837534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    Deoptimizer::DeoptimizeFunction(*function);
8376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8377906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // Evict optimized code for this function from the cache so that it doesn't
8378906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // get used for new closures.
8379906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
8380906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org                                                "notify deoptimized");
83815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
8382ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
8383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8386c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyOSR) {
838779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
8388ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  delete deoptimizer;
8390ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
8391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8394c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
8395ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
8397f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8398ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
8399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8400a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Deoptimizer::DeoptimizeFunction(*function);
8401a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
8403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8406212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ClearFunctionTypeFeedback) {
8407212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  HandleScope scope(isolate);
8408212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  ASSERT(args.length() == 1);
8409212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8410212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  Code* unoptimized = function->shared()->code();
8411212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  if (unoptimized->kind() == Code::FUNCTION) {
8412212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    unoptimized->ClearInlineCaches();
8413212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    unoptimized->ClearTypeFeedbackCells(isolate->heap());
8414212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  }
8415212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  return isolate->heap()->undefined_value();
8416212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org}
8417212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
8418212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
84196d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
842079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
84216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#if defined(USE_SIMULATOR)
84226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return isolate->heap()->true_value();
84236d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#else
84246d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return isolate->heap()->false_value();
84256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#endif
84266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
84276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
84286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
8429b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsParallelRecompilationSupported) {
8430b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HandleScope scope(isolate);
8431b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  return FLAG_parallel_recompilation
8432b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      ? isolate->heap()->true_value() : isolate->heap()->false_value();
8433b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
8434b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
8435b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
8436a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
8437a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  HandleScope scope(isolate);
8438be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8439f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8440be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
8441a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
8442a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  function->MarkForLazyRecompilation();
8443be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
8444be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Code* unoptimized = function->shared()->code();
8445be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  if (args.length() == 2 &&
8446be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      unoptimized->kind() == Code::FUNCTION) {
8447be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8448750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
8449e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      for (int i = 0; i <= Code::kMaxLoopNestingMarker; i++) {
8450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        unoptimized->set_allow_osr_at_loop_nesting_level(i);
8451e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
8452e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      }
8453750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) {
8454750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      function->MarkForParallelRecompilation();
8455750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
8456be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
8457be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
8458a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  return isolate->heap()->undefined_value();
8459a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org}
8460a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org
8461a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org
8462ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimizeFunction) {
84636e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
84646e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
8465ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, function, 0);
8466ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(!function->IsOptimized());
8467ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  function->shared()->set_optimization_disabled(true);
84686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  return isolate->heap()->undefined_value();
84696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
84706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
84716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
84721c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
84731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  HandleScope scope(isolate);
8474ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
84751c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  if (!V8::UseCrankshaft()) {
84761c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    return Smi::FromInt(4);  // 4 == "never".
84771c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
8478ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  bool sync_with_compiler_thread = true;
8479ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (args.length() == 2) {
8480ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
8481ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
8482ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      sync_with_compiler_thread = false;
8483ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    }
8484ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
84851044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8486ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (FLAG_parallel_recompilation && sync_with_compiler_thread) {
8487594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    while (function->IsInRecompileQueue() ||
8488ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org           function->IsMarkedForInstallingRecompiledCode()) {
8489ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8490ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      OS::Sleep(50);
8491304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
8492304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
84931c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  if (FLAG_always_opt) {
84941044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    // We may have always opt, but that is more best-effort than a real
84951044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    // promise, so we still say "no" if it is not optimized.
84961044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
84971044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org                                   : Smi::FromInt(2);  // 2 == "no".
84981c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
849910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  if (FLAG_deopt_every_n_times) {
850010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    return Smi::FromInt(6);  // 6 == "maybe deopted".
850110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  }
85021c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
85031c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                 : Smi::FromInt(2);  // 2 == "no".
85041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
85051c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
85061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
85071c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
85081c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  HandleScope scope(isolate);
85091c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  ASSERT(args.length() == 1);
8510f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
85111c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  return Smi::FromInt(function->shared()->opt_count());
85121c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
85131c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
85141c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
8515c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
8516ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
8518f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // We're not prepared to handle a function with arguments object.
85217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(!function->shared()->uses_arguments());
8522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8523a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // We have hit a back edge in an unoptimized frame for a function that was
8524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // selected for on-stack replacement.  Find the unoptimized code object.
8525ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Code> unoptimized(function->shared()->code(), isolate);
8526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Keep track of whether we've succeeded in optimizing.
8527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool succeeded = unoptimized->optimizable();
8528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (succeeded) {
8529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // If we are trying to do OSR when there are already optimized
8530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // activations of the function, it means (a) the function is directly or
8531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // indirectly recursive and (b) an optimized invocation has been
8532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // deoptimized so that we are currently in an unoptimized activation.
8533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check for optimized activations of this function.
853474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    JavaScriptFrameIterator it(isolate);
8535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    while (succeeded && !it.done()) {
8536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      JavaScriptFrame* frame = it.frame();
8537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      succeeded = !frame->is_optimized() || frame->function() != *function;
8538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      it.Advance();
8539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8542471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId ast_id = BailoutId::None();
8543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (succeeded) {
8544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // The top JS function is this one, the PC is somewhere in the
8545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // unoptimized code.
854674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    JavaScriptFrameIterator it(isolate);
8547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    JavaScriptFrame* frame = it.frame();
8548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(frame->function() == *function);
854974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    ASSERT(frame->LookupCode() == *unoptimized);
8550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(unoptimized->contains(frame->pc()));
8551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Use linear search of the unoptimized code's back edge table to find
8553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // the AST id matching the PC.
8554594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uint32_t target_pc_offset =
8555594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
8556ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    uint32_t loop_depth = 0;
8557594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
8558594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    for (FullCodeGenerator::BackEdgeTableIterator back_edges(*unoptimized);
8559594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org         !back_edges.Done();
8560594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org         back_edges.Next()) {
8561594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (back_edges.pc_offset() == target_pc_offset) {
8562594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        ast_id = back_edges.ast_id();
8563594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        loop_depth = back_edges.loop_depth();
8564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
8565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
8566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8567471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    ASSERT(!ast_id.IsNone());
8568594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
8569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (FLAG_trace_osr) {
8570e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
8571e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org              ast_id.ToInt(), loop_depth);
8572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      function->PrintName();
8573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintF("]\n");
8574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Try to compile the optimized code.  A true return value from
8577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // CompileOptimized means that compilation succeeded, not necessarily
8578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // that optimization succeeded.
8579394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
85805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        function->IsOptimized()) {
8581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizationInputData* data = DeoptimizationInputData::cast(
8582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          function->code()->deoptimization_data());
85835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      if (data->OsrPcOffset()->value() >= 0) {
85845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        if (FLAG_trace_osr) {
85855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          PrintF("[on-stack replacement offset %d in optimized code]\n",
8586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               data->OsrPcOffset()->value());
85875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        }
8588471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
85895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      } else {
85905f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        // We may never generate the desired OSR entry if we emit an
85915f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        // early deoptimize.
85925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        succeeded = false;
8593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
8594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
8595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      succeeded = false;
8596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Revert to the original interrupt calls in the original unoptimized code.
8600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_trace_osr) {
8601e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    PrintF("[restoring original interrupt calls in ");
8602a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    function->PrintName();
8603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintF("]\n");
8604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8605cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org  InterruptStub interrupt_stub;
8606e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate);
86077979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
8608e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Deoptimizer::RevertInterruptCode(*unoptimized,
8609e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                   *interrupt_code,
8610e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                   *replacement_code);
8611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // If the optimization attempt succeeded, return the AST id tagged as a
8613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // smi. This tells the builtin that we need to translate the unoptimized
8614a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // frame to an optimized one.
8615a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (succeeded) {
8616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
8617471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    return Smi::FromInt(ast_id.ToInt());
8618a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
86195d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (function->IsMarkedForLazyRecompilation()) {
86205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      function->ReplaceCode(function->shared()->code());
86215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
8622a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Smi::FromInt(-1);
8623a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
862721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
862821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  SealHandleScope shs(isolate);
862921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  ASSERT(args.length() == 2);
863021af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org#ifdef DEBUG
863121af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(interval, 0);
863221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(timeout, 1);
863321af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  isolate->heap()->set_allocation_timeout(timeout);
863421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  FLAG_gc_interval = interval;
863521af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org#endif
863621af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  return isolate->heap()->undefined_value();
863721af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org}
863821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org
863921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org
86401805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
864179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
86421805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
86431805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  return isolate->heap()->undefined_value();
86441805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
86451805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
86461805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
864788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
864879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
864988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
865088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  return isolate->heap()->nan_value();
865188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org}
865288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
865388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
8654c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
8655c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  HandleScope scope(isolate);
8656c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ASSERT(args.length() >= 2);
8657c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int argc = args.length() - 2;
8658f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
8659f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Object* receiver = args[0];
8660c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8661c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // If there are too many arguments, allocate argv via malloc.
8662c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  const int argv_small_size = 10;
8663c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<Object> argv_small_buffer[argv_small_size];
8664c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  SmartArrayPointer<Handle<Object> > argv_large_buffer;
8665c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<Object>* argv = argv_small_buffer;
8666c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  if (argc > argv_small_size) {
8667c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    argv = new Handle<Object>[argc];
8668c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    if (argv == NULL) return isolate->StackOverflow();
8669c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8670c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
8671c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8672c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  for (int i = 0; i < argc; ++i) {
8673c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org     MaybeObject* maybe = args[1 + i];
8674c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org     Object* object;
8675c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org     if (!maybe->To<Object>(&object)) return maybe;
867609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org     argv[i] = Handle<Object>(object, isolate);
8677c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
8678c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8679c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  bool threw;
8680c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<JSReceiver> hfun(fun);
868109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> hreceiver(receiver, isolate);
8682c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<Object> result =
8683c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      Execution::Call(hfun, hreceiver, argc, argv, &threw, true);
8684c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8685c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  if (threw) return Failure::Exception();
8686c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  return *result;
8687c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
8688c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8689c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
869034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
869134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  HandleScope scope(isolate);
869234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 5);
8693f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
8694fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  Handle<Object> receiver = args.at<Object>(1);
8695f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
8696fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  CONVERT_SMI_ARG_CHECKED(offset, 3);
8697fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  CONVERT_SMI_ARG_CHECKED(argc, 4);
8698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  RUNTIME_ASSERT(offset >= 0);
8699594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  RUNTIME_ASSERT(argc >= 0);
870034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
870134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If there are too many arguments, allocate argv via malloc.
870234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  const int argv_small_size = 10;
870334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Handle<Object> argv_small_buffer[argv_small_size];
870434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  SmartArrayPointer<Handle<Object> > argv_large_buffer;
870534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Handle<Object>* argv = argv_small_buffer;
870634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (argc > argv_small_size) {
870734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    argv = new Handle<Object>[argc];
870834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (argv == NULL) return isolate->StackOverflow();
870934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
871034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
871134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
871234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  for (int i = 0; i < argc; ++i) {
8713fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    argv[i] = Object::GetElement(arguments, offset + i);
871434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
871534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
8716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool threw;
8717a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> result =
8718fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org      Execution::Call(fun, receiver, argc, argv, &threw, true);
871934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
872034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (threw) return Failure::Exception();
872134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return *result;
872234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
872334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
872434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
8725c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
8726ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
872743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
872843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(!args[0]->IsJSFunction());
872943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *Execution::GetFunctionDelegate(args.at<Object>(0));
873043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
873143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
873243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8733c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
8734ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
873505521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  ASSERT(args.length() == 1);
873605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  RUNTIME_ASSERT(!args[0]->IsJSFunction());
873705521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  return *Execution::GetConstructorDelegate(args.at<Object>(0));
873805521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org}
873905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
874005521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
874146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewGlobalContext) {
874279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
874346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(args.length() == 2);
874446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
874546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  CONVERT_ARG_CHECKED(JSFunction, function, 0);
874646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 1);
874746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* result;
874846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  MaybeObject* maybe_result =
874946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->heap()->AllocateGlobalContext(function, scope_info);
875046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (!maybe_result->To(&result)) return maybe_result;
875146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
8752355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT(function->context() == isolate->context());
8753355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT(function->context()->global_object() == result->global_object());
875446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  isolate->set_context(result);
8755355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  result->global_object()->set_global_context(result);
875646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
875746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return result;  // non-failure
875846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
875946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
876046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
87616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
876279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
87637276f14ca716596e0a0d17539516370c1f453847kasper.lund  ASSERT(args.length() == 1);
876443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8765f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, function, 0);
8766c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int length = function->shared()->scope_info()->ContextLength();
876746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* result;
876846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  MaybeObject* maybe_result =
876946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->heap()->AllocateFunctionContext(length, function);
877046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (!maybe_result->To(&result)) return maybe_result;
877143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
877246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  isolate->set_context(result);
877343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87747276f14ca716596e0a0d17539516370c1f453847kasper.lund  return result;  // non-failure
877543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
877643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8777303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
87786d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
877979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
87803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  ASSERT(args.length() == 2);
8781ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  JSReceiver* extension_object;
8782ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (args[0]->IsJSReceiver()) {
8783ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    extension_object = JSReceiver::cast(args[0]);
87846d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  } else {
87856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    // Convert the object to a proper JavaScript object.
87866d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    MaybeObject* maybe_js_object = args[0]->ToObject();
87876d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (!maybe_js_object->To(&extension_object)) {
87886d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      if (Failure::cast(maybe_js_object)->IsInternalError()) {
87896d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        HandleScope scope(isolate);
87906d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        Handle<Object> handle = args.at<Object>(0);
87916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        Handle<Object> result =
87926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org            isolate->factory()->NewTypeError("with_expression",
87936d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                             HandleVector(&handle, 1));
87946d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        return isolate->Throw(*result);
87956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      } else {
8796303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        return maybe_js_object;
8797303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
879843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
879943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
880043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  JSFunction* function;
88023cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (args[1]->IsSmi()) {
88033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // A smi sentinel indicates a context nested inside global code rather
88043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // than some function.  There is a canonical empty function that can be
880546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // gotten from the native context.
880646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    function = isolate->context()->native_context()->closure();
88073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  } else {
88083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    function = JSFunction::cast(args[1]);
88093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  }
88103cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
88116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Context* context;
88126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  MaybeObject* maybe_context =
88133cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org      isolate->heap()->AllocateWithContext(function,
88143cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                                           isolate->context(),
88156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                           extension_object);
88166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (!maybe_context->To(&context)) return maybe_context;
8817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->set_context(context);
88186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return context;
881937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
882037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
882137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
8822c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
882379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
88243cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  ASSERT(args.length() == 3);
88256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  String* name = String::cast(args[0]);
88266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Object* thrown_object = args[1];
88273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  JSFunction* function;
88283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (args[2]->IsSmi()) {
88293cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // A smi sentinel indicates a context nested inside global code rather
88303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // than some function.  There is a canonical empty function that can be
883146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // gotten from the native context.
883246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    function = isolate->context()->native_context()->closure();
88333cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  } else {
88343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    function = JSFunction::cast(args[2]);
88353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  }
88366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Context* context;
88376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  MaybeObject* maybe_context =
88383cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org      isolate->heap()->AllocateCatchContext(function,
88393cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                                            isolate->context(),
88406d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                            name,
88416d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                            thrown_object);
88426d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (!maybe_context->To(&context)) return maybe_context;
88436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  isolate->set_context(context);
88446d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return context;
884537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
884637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
884737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
88484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
884979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
88504acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  ASSERT(args.length() == 2);
8851c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
88524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  JSFunction* function;
88534acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (args[1]->IsSmi()) {
88544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // A smi sentinel indicates a context nested inside global code rather
88554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // than some function.  There is a canonical empty function that can be
885646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // gotten from the native context.
885746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    function = isolate->context()->native_context()->closure();
88584acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  } else {
88594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    function = JSFunction::cast(args[1]);
88604acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
88614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Context* context;
88624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  MaybeObject* maybe_context =
88634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      isolate->heap()->AllocateBlockContext(function,
88644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org                                            isolate->context(),
88654acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org                                            scope_info);
88664acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (!maybe_context->To(&context)) return maybe_context;
88674acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  isolate->set_context(context);
88684acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return context;
88694acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
88704acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
88714acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
887281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSModule) {
887379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
887481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  ASSERT(args.length() == 1);
887581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  Object* obj = args[0];
887681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSModule());
887781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org}
887881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
887981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
8880ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comRUNTIME_FUNCTION(MaybeObject*, Runtime_PushModuleContext) {
888179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
88828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ASSERT(args.length() == 2);
88838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 0);
88848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
88858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (!args[1]->IsScopeInfo()) {
88868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // Module already initialized. Find hosting context and retrieve context.
88878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Context* host = Context::cast(isolate->context())->global_context();
88888e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Context* context = Context::cast(host->get(index));
88898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    ASSERT(context->previous() == isolate->context());
88908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    isolate->set_context(context);
88918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return context;
88928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
88938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
88948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
889581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
88968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Allocate module context.
88978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  HandleScope scope(isolate);
88988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Factory* factory = isolate->factory();
88998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<Context> context = factory->NewModuleContext(scope_info);
89008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<JSModule> module = factory->NewJSModule(context, scope_info);
89018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  context->set_module(*module);
890281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  Context* previous = isolate->context();
890381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  context->set_previous(previous);
890481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  context->set_closure(previous->closure());
890546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_global_object(previous->global_object());
89068e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  isolate->set_context(*context);
8907ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
89088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Find hosting scope and initialize internal variable holding module there.
89098e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  previous->global_context()->set(index, *context);
89108e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89118e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return *context;
89128e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
89138e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareModules) {
89168e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  HandleScope scope(isolate);
89178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ASSERT(args.length() == 1);
89188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
89198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Context* host_context = isolate->context();
89208e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89218e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (int i = 0; i < descriptions->length(); ++i) {
89228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
89238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    int host_index = description->host_index();
89248e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Handle<Context> context(Context::cast(host_context->get(host_index)));
89258e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Handle<JSModule> module(context->module());
89268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89278e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    for (int j = 0; j < description->length(); ++j) {
89288e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      Handle<String> name(description->name(j));
89298e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      VariableMode mode = description->mode(j);
89308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      int index = description->index(j);
89318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      switch (mode) {
89328e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case VAR:
89338e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case LET:
89348e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case CONST:
89358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case CONST_HARMONY: {
89368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          PropertyAttributes attr =
89378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org              IsImmutableVariableMode(mode) ? FROZEN : SEALED;
89388e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Handle<AccessorInfo> info =
89398e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org              Accessors::MakeModuleExport(name, index, attr);
89408e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Handle<Object> result = SetAccessor(module, info);
89418e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          ASSERT(!(result.is_null() || result->IsUndefined()));
89428e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          USE(result);
89438e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          break;
89448e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        }
89458e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case MODULE: {
89468e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Object* referenced_context = Context::cast(host_context)->get(index);
89478e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Handle<JSModule> value(Context::cast(referenced_context)->module());
89488e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          JSReceiver::SetProperty(module, name, value, FROZEN, kStrictMode);
89498e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          break;
89508e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        }
89518e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case INTERNAL:
89528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case TEMPORARY:
89538e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case DYNAMIC:
89548e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case DYNAMIC_GLOBAL:
89558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case DYNAMIC_LOCAL:
89568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          UNREACHABLE();
89578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      }
89588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
89598e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    JSObject::PreventExtensions(module);
89618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
89628e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
89638e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ASSERT(!isolate->has_pending_exception());
89648e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return isolate->heap()->undefined_value();
8965ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
8966ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
8967ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
8968c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
8969ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
897043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
897143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8972f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
8973f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
897443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
897543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
897643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
897743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = FOLLOW_CHAINS;
897880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
897980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Handle<Object> holder = context->Lookup(name,
898080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          flags,
898180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &index,
898280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &attributes,
898380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &binding_flags);
898443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // If the slot was not found the result is true.
89860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (holder.is_null()) {
8987ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->true_value();
898843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
898943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // If the slot was found in a context, it should be DONT_DELETE.
89910ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (holder->IsContext()) {
8992ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->false_value();
89930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  }
89940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
89950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // The slot was found in a JSObject, either a context extension object,
8996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the global object, or the subject of a with.  Try to delete it
8997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // (respecting DONT_DELETE).
89980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  Handle<JSObject> object = Handle<JSObject>::cast(holder);
8999ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Object> result = JSReceiver::DeleteProperty(object, name);
9000ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
9001ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
900243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
900343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
900443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9005a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// A mechanism to return a pair of Object pointers in registers (if possible).
9006a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// How this is achieved is calling convention-dependent.
9007a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// All currently supported x86 compiles uses calling conventions that are cdecl
9008a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// variants where a 64-bit value is returned in two 32-bit registers
9009a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// (edx:eax on ia32, r1:r0 on ARM).
9010a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
9011a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// In Win64 calling convention, a struct of two pointers is returned in memory,
9012a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// allocated by the caller, and passed as a pointer in a hidden first parameter.
90132abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org#ifdef V8_HOST_ARCH_64_BIT
90142abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgstruct ObjectPair {
9015303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* x;
9016303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* y;
90172abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org};
9018a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
9019e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
9020303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
90212abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ObjectPair result = {x, y};
9022a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
9023a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // In Win64 they are assigned to a hidden first argument.
9024a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  return result;
90252abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
9026b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org#else
90272abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgtypedef uint64_t ObjectPair;
9028303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
902943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return reinterpret_cast<uint32_t>(x) |
90309fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org      (reinterpret_cast<ObjectPair>(y) << 32);
903143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
90322abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org#endif
90332abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
90342abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
9035ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic inline MaybeObject* Unhole(Heap* heap,
9036ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                  MaybeObject* x,
9037303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                  PropertyAttributes attributes) {
903843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
903943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  USE(attributes);
9040ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return x->IsTheHole() ? heap->undefined_value() : x;
904143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
904243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
904343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
904440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgstatic Object* ComputeReceiverForNonGlobal(Isolate* isolate,
904540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                           JSObject* holder) {
90469fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  ASSERT(!holder->IsGlobalObject());
9047ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Context* top = isolate->context();
90489fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // Get the context extension function.
90495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  JSFunction* context_extension_function =
905046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      top->native_context()->context_extension_function();
90519fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // If the holder isn't a context extension object, we just return it
90529fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // as the receiver. This allows arguments objects to be used as
90539fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // receivers, but only if they are put in the context scope chain
90549fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // explicitly via a with-statement.
90559fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  Object* constructor = holder->map()->constructor();
90569fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (constructor != context_extension_function) return holder;
905740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Fall back to using the global object as the implicit receiver if
905840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // the property turns out to be a local variable allocated in a
905940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // context extension object - introduced via eval. Implicit global
906040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // receivers are indicated with the hole value.
906140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  return isolate->heap()->the_hole_value();
90625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
90635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
90645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
9065ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic ObjectPair LoadContextSlotHelper(Arguments args,
9066ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        Isolate* isolate,
9067ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        bool throw_error) {
9068ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
9069a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  ASSERT_EQ(2, args.length());
907043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90719fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (!args[0]->IsContext() || !args[1]->IsString()) {
9072ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakePair(isolate->ThrowIllegalOperation(), NULL);
90739fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
907443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Context> context = args.at<Context>(0);
90759fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  Handle<String> name = args.at<String>(1);
907643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
907743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
907843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
907943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = FOLLOW_CHAINS;
908080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
908180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Handle<Object> holder = context->Lookup(name,
908280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          flags,
908380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &index,
908480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &attributes,
908580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &binding_flags);
9086ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (isolate->has_pending_exception()) {
9087ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return MakePair(Failure::Exception(), NULL);
9088ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
908943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If the index is non-negative, the slot has been found in a context.
909143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= 0) {
9092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(holder->IsContext());
9093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the "property" we were looking for is a local variable, the
9094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
909540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    //
9096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Use the hole as the receiver to signal that the receiver is implicit
9097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // and that the global receiver should be used (as distinguished from an
9098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // explicit receiver that happens to be a global object).
909940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    Handle<Object> receiver = isolate->factory()->the_hole_value();
9100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* value = Context::cast(*holder)->get(index);
910180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    // Check for uninitialized bindings.
9102394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    switch (binding_flags) {
9103394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case MUTABLE_CHECK_INITIALIZED:
9104394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
9105394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (value->IsTheHole()) {
9106394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<Object> reference_error =
9107394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              isolate->factory()->NewReferenceError("not_defined",
9108394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                                    HandleVector(&name, 1));
9109394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          return MakePair(isolate->Throw(*reference_error), NULL);
9110394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        }
9111394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // FALLTHROUGH
9112394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case MUTABLE_IS_INITIALIZED:
9113394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_IS_INITIALIZED:
9114394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_IS_INITIALIZED_HARMONY:
9115394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ASSERT(!value->IsTheHole());
9116394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return MakePair(value, *receiver);
9117394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_CHECK_INITIALIZED:
9118394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
9119394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case MISSING_BINDING:
9120394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        UNREACHABLE();
9121394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return MakePair(NULL, NULL);
912280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    }
91239fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
91249fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
9125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Otherwise, if the slot was found the holder is a context extension
9126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object, subject of a with, or a global object.  We read the named
9127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // property from it.
9128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!holder.is_null()) {
9129ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9130ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ASSERT(object->IsJSProxy() || object->HasProperty(*name));
91317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // GetProperty below can cause GC.
913209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> receiver_handle(
913309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        object->IsGlobalObject()
913409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org            ? GlobalObject::cast(*object)->global_receiver()
9135ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            : object->IsJSProxy() ? static_cast<Object*>(*object)
9136ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
913709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        isolate);
91387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
9139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // No need to unhole the value here.  This is taken care of by the
91409fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    // GetProperty function.
9141303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    MaybeObject* value = object->GetProperty(*name);
91427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    return MakePair(value, *receiver_handle);
914343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
914443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
914543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (throw_error) {
914643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // The property doesn't exist - throw exception.
914743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> reference_error =
9148ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewReferenceError("not_defined",
9149ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                              HandleVector(&name, 1));
9150ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakePair(isolate->Throw(*reference_error), NULL);
915143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
915240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // The property doesn't exist - return undefined.
9153ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakePair(isolate->heap()->undefined_value(),
9154ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                    isolate->heap()->undefined_value());
915543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
915643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
915743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
915843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9159c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) {
9160ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return LoadContextSlotHelper(args, isolate, true);
916143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
916243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
916343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9164c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlotNoReferenceError) {
9165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return LoadContextSlotHelper(args, isolate, false);
916643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
916743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
916843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9169c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
9170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
91719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  ASSERT(args.length() == 4);
917243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> value(args[0], isolate);
9174f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
9175f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
91761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
91771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  StrictModeFlag strict_mode = (language_mode == CLASSIC_MODE)
91781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      ? kNonStrictMode : kStrictMode;
917943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
918043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
918143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
918243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = FOLLOW_CHAINS;
918380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
918480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Handle<Object> holder = context->Lookup(name,
918580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          flags,
918680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &index,
918780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &attributes,
918880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &binding_flags);
9189ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (isolate->has_pending_exception()) return Failure::Exception();
919043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
919143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= 0) {
9192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The property was found in a context slot.
9193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<Context> context = Handle<Context>::cast(holder);
9194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
9195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        context->get(index)->IsTheHole()) {
9196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Object> error =
9197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate->factory()->NewReferenceError("not_defined",
9198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                HandleVector(&name, 1));
9199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return isolate->Throw(*error);
9200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
9201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Ignore if read_only variable.
9202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((attributes & READ_ONLY) == 0) {
9203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Context is a fixed array and set cannot fail.
9204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      context->set(index, *value);
9205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else if (strict_mode == kStrictMode) {
9206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Setting read only property in strict mode.
9207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Object> error =
9208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate->factory()->NewTypeError("strict_cannot_assign",
9209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                           HandleVector(&name, 1));
9210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return isolate->Throw(*error);
921143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
921243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
921343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
921443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Slow case: The property is not in a context slot.  It is either in a
9216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // context extension object, a property of the subject of a with, or a
9217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // property of the global object.
9218ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSReceiver> object;
921943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92209fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (!holder.is_null()) {
9221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The property exists on the holder.
9222ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    object = Handle<JSReceiver>::cast(holder);
922343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
922444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    // The property was not found.
922543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(attributes == ABSENT);
922644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
922744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    if (strict_mode == kStrictMode) {
922844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      // Throw in strict mode (assignment to undefined variable).
922944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      Handle<Object> error =
9230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate->factory()->NewReferenceError(
9231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com              "not_defined", HandleVector(&name, 1));
923244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      return isolate->Throw(*error);
923344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
9234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // In non-strict mode, the property is added to the global object.
923543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    attributes = NONE;
9236ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    object = Handle<JSReceiver>(isolate->context()->global_object());
923743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
923843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Set the property if it's not read only or doesn't yet exist.
9240bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if ((attributes & READ_ONLY) == 0 ||
9241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      (object->GetLocalPropertyAttribute(*name) == ABSENT)) {
92428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    RETURN_IF_EMPTY_HANDLE(
9243ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
9244f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
92458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
92469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Setting read only property in strict mode.
92479ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    Handle<Object> error =
9248ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewTypeError(
9249ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          "strict_cannot_assign", HandleVector(&name, 1));
9250ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*error);
925143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
925243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
925343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
925443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
925543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9256c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Throw) {
9257ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
925843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
925943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9260ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->Throw(args[0]);
926143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
926243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
926343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9264c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ReThrow) {
9265ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
926643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
926743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9268ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->ReThrow(args[0]);
926943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
927043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
927143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9272c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PromoteScheduledException) {
927379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
9274c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ASSERT_EQ(0, args.length());
9275ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->PromoteScheduledException();
9276c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
9277c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
9278c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
9279c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowReferenceError) {
9280ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
928143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
928243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9283ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> name(args[0], isolate);
928443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> reference_error =
9285ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->factory()->NewReferenceError("not_defined",
9286ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          HandleVector(&name, 1));
9287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->Throw(*reference_error);
928843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
928943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
929043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9291de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowNotDateError) {
9292de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  HandleScope scope(isolate);
9293de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  ASSERT(args.length() == 0);
9294de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  return isolate->Throw(*isolate->factory()->NewTypeError(
9295de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      "not_date_object", HandleVector<Object>(NULL, 0)));
9296de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org}
9297de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
9298de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
9299de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
9300c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
930179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
93024a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  ASSERT(args.length() == 0);
930343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
930443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First check if this is a real stack overflow.
9305ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate->stack_guard()->IsStackOverflow()) {
930679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    SealHandleScope shs(isolate);
9307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->StackOverflow();
9308ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
930943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9310812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return Execution::HandleStackGuardInterrupt(isolate);
931143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
931243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
931343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
931456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Interrupt) {
931579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
931656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  ASSERT(args.length() == 0);
9317812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  return Execution::HandleStackGuardInterrupt(isolate);
931856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org}
931956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
932056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
9321c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgstatic int StackSize(Isolate* isolate) {
932243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n = 0;
9323c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
932443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return n;
932543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
932643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
932743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9328c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgstatic void PrintTransition(Isolate* isolate, Object* result) {
932943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // indentation
933043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  { const int nmax = 80;
9331c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    int n = StackSize(isolate);
933243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (n <= nmax)
933343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("%4d:%*s", n, n, "");
933443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    else
933543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("%4d:%*s", n, nmax, "...");
933643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
933743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
933843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (result == NULL) {
9339c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    JavaScriptFrame::PrintTop(isolate, stdout, true, false);
9340394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    PrintF(" {\n");
934143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
934243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // function result
934343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("} -> ");
9344394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    result->ShortPrint();
934543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("\n");
934643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
934743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
934843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
934943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9350c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
935179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
93526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 0);
9353c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  PrintTransition(isolate, NULL);
9354ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
935543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
935643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
935743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9358c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) {
935979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
9360c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  PrintTransition(isolate, args[0]);
936143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return args[0];  // return TOS
936243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
936343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
936443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9365c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrint) {
936679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
936743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
936843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
936943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
937043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (args[0]->IsString()) {
937143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we have a string, assume it's a code "marker"
937243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // and print some interesting cpu debugging info.
937374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    JavaScriptFrameIterator it(isolate);
937443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    JavaScriptFrame* frame = it.frame();
9375eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    PrintF("fp = %p, sp = %p, caller_sp = %p: ",
9376eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org           frame->fp(), frame->sp(), frame->caller_sp());
937743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
937843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("DebugPrint: ");
937943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
938043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  args[0]->Print();
9381ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  if (args[0]->IsHeapObject()) {
9382ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    PrintF("\n");
9383ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    HeapObject::cast(args[0])->map()->Print();
9384ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  }
938543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else
93869258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // ShortPrint is available in release mode. Print is not.
93879258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  args[0]->ShortPrint();
938843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
938943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("\n");
9390236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  Flush();
939143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
939243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return args[0];  // return TOS
939343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
939443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
939543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9396c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugTrace) {
939779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
93986e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 0);
9399bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  isolate->PrintStack(stdout);
9400ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
940143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
940243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
940343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9404c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
940579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
940631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
940743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
940843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // According to ECMA-262, section 15.9.1, page 117, the precision of
940943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the number in a Date object representing a particular instant in
941043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // time is milliseconds. Therefore, we floor the result of getting
941143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the OS time.
941243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  double millis = floor(OS::TimeCurrentMillis());
9413ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->NumberFromDouble(millis);
941443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
941543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
941643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9417c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
9418ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
9419bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(args.length() == 2);
9420bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
9421f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
9422bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  FlattenString(str);
9423bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
9424f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
9425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
9426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MaybeObject* maybe_result_array =
942764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      output->EnsureCanContainHeapObjectElements();
9428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (maybe_result_array->IsFailure()) return maybe_result_array;
9429830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(output->HasFastObjectElements());
943043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
943179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
943243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94330b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  FixedArray* output_array = FixedArray::cast(output->elements());
9434bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9435bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  bool result;
9436ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent str_content = str->GetFlatContent();
9437ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (str_content.IsAscii()) {
943859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    result = DateParser::Parse(str_content.ToOneByteVector(),
9439a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                               output_array,
9440a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                               isolate->unicode_cache());
944143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
9442ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    ASSERT(str_content.IsTwoByte());
9443ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    result = DateParser::Parse(str_content.ToUC16Vector(),
9444a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                               output_array,
9445a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                               isolate->unicode_cache());
9446bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
9447bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
9448bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (result) {
9449bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return *output;
9450bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else {
9451ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->null_value();
945243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
945343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
945443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
945543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9456c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
945779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
945843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
945943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
94614efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x));
94624efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  const char* zone = OS::LocalTimezone(static_cast<double>(time));
9463ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
946443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
946543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
946643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DateToUTC) {
946879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
946943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
947043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
94724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
94734efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
94744efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  return isolate->heap()->NumberFromDouble(static_cast<double>(time));
947543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
947643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
947743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9478c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
947979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
94805a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  ASSERT(args.length() == 1);
94815a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Object* global = args[0];
9482ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
94835a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return JSGlobalObject::cast(global)->global_receiver();
94845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
94855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
94865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
9487c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
9488ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
9489e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  ASSERT_EQ(1, args.length());
9490f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9491e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
9492594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  source = Handle<String>(FlattenGetString(source));
94932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Optimized fast case where we only have ASCII characters.
9494e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  Handle<Object> result;
9495fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (source->IsSeqOneByteString()) {
94961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = JsonParser<true>::Parse(source);
9497e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  } else {
94981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    result = JsonParser<false>::Parse(source);
9499e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
9500e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  if (result.is_null()) {
9501e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Syntax error or stack overflow in scanner.
9502ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ASSERT(isolate->has_pending_exception());
9503e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    return Failure::Exception();
9504e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
9505e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  return *result;
9506e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org}
9507e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
9508e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
9509fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgbool CodeGenerationFromStringsAllowed(Isolate* isolate,
9510fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                                      Handle<Context> context) {
9511f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(context->allow_code_gen_from_strings()->IsFalse());
9512f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Check with callback if set.
9513f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  AllowCodeGenerationFromStringsCallback callback =
9514f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate->allow_code_gen_callback();
9515f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (callback == NULL) {
9516f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // No callback set and code generation disallowed.
9517f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return false;
9518f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  } else {
9519f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // Callback set. Let it decide if code generation is allowed.
9520ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    VMState<EXTERNAL> state(isolate);
9521f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return callback(v8::Utils::ToLocal(context));
9522fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
9523fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org}
9524fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
9525fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
9526c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
9527ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
95289faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  ASSERT_EQ(2, args.length());
9529f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
95309faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
95319258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
953246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Extract native context.
953346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> context(isolate->context()->native_context());
9534fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
953546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check if native context allows code generation from
9536fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // strings. Throw an exception if it doesn't.
9537f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (context->allow_code_gen_from_strings()->IsFalse() &&
9538f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      !CodeGenerationFromStringsAllowed(isolate, context)) {
953956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Handle<Object> error_message =
954056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        context->ErrorMessageForCodeGenerationFromStrings();
954156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    return isolate->Throw(*isolate->factory()->NewEvalError(
954256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9543fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
9544fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
954546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Compile source string in the native context.
95469faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  ParseRestriction restriction = function_literal_only
95479faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
954804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
95499faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      source, context, true, CLASSIC_MODE, restriction, RelocInfo::kNoPosition);
9550e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, shared);
955143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<JSFunction> fun =
9552ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
9553ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                            context,
9554ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                            NOT_TENURED);
955543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *fun;
955643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
955743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
955843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9559ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic ObjectPair CompileGlobalEval(Isolate* isolate,
9560ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                    Handle<String> source,
956183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                                    Handle<Object> receiver,
95621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                    LanguageMode language_mode,
956304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                                    int scope_position) {
9564fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  Handle<Context> context = Handle<Context>(isolate->context());
956546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> native_context = Handle<Context>(context->native_context());
9566fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
956746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check if native context allows code generation from
9568fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // strings. Throw an exception if it doesn't.
956946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (native_context->allow_code_gen_from_strings()->IsFalse() &&
957046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      !CodeGenerationFromStringsAllowed(isolate, native_context)) {
957156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Handle<Object> error_message =
9572c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org        native_context->ErrorMessageForCodeGenerationFromStrings();
957356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    isolate->Throw(*isolate->factory()->NewEvalError(
957456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9575fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org    return MakePair(Failure::Exception(), NULL);
9576fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
9577fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
95781af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Deal with a normal eval call with a string argument. Compile it
95791af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // and return the compiled function bound in the local context.
95801af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
95811af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org      source,
9582c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      context,
958346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      context->IsNativeContext(),
95841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      language_mode,
95859faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      NO_PARSE_RESTRICTION,
958604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      scope_position);
9587e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, shared,
9588e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org                               MakePair(Failure::Exception(), NULL));
9589ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSFunction> compiled =
9590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFunctionFromSharedFunctionInfo(
9591fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org          shared, context, NOT_TENURED);
95921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  return MakePair(*compiled, *receiver);
95931af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org}
95941af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
95951af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
9596c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
95976e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
959804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ASSERT(args.length() == 5);
9599a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
96009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  Handle<Object> callee = args.at<Object>(0);
96011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
9602c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If "eval" didn't refer to the original GlobalEval, it's not a
9603c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // direct call to eval.
9604c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // (And even if it is, but the first argument isn't a string, just let
9605c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // execution default to an indirect call to eval, which will also return
9606c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the first argument without doing anything).
960746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (*callee != isolate->native_context()->global_eval_fun() ||
96081af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org      !args[1]->IsString()) {
960940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    return MakePair(*callee, isolate->heap()->the_hole_value());
96101af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
96111af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
96121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
961304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ASSERT(args[4]->IsSmi());
9614ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return CompileGlobalEval(isolate,
9615ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           args.at<String>(1),
961683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                           args.at<Object>(2),
96171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                           language_mode,
961804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                           args.smi_at(4));
9619a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
9620a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
9621a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
9622c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgstatic MaybeObject* Allocate(Isolate* isolate,
9623c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                             int size,
9624c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                             AllocationSpace space) {
9625c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // Allocate a block of memory in the given space (filled with a filler).
9626c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // Use as fallback for allocation in generated code when the space
9627c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  // is full.
962879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
9629c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9630c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  RUNTIME_ASSERT(size > 0);
9631ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
9632c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize());
9633303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* allocation;
9634c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  { MaybeObject* maybe_allocation;
9635c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    if (space == NEW_SPACE) {
9636c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      maybe_allocation = heap->new_space()->AllocateRaw(size);
9637c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    } else {
9638c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      ASSERT(space == OLD_POINTER_SPACE || space == OLD_DATA_SPACE);
9639c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      maybe_allocation = heap->paged_space(space)->AllocateRaw(size);
9640c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    }
9641303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (maybe_allocation->ToObject(&allocation)) {
9642ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size);
9643303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
9644303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    return maybe_allocation;
9645c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  }
9646c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org}
9647c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org
9648c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org
9649c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) {
965079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
9651c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  ASSERT(args.length() == 1);
9652c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
9653c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  return Allocate(isolate, size_smi->value(), NEW_SPACE);
9654c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
9655c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
9656c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
96572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldPointerSpace) {
965879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
96592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ASSERT(args.length() == 1);
96602bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
9661c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  return Allocate(isolate, size_smi->value(), OLD_POINTER_SPACE);
9662c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
9663c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
9664c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
9665c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldDataSpace) {
966679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
9667c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  ASSERT(args.length() == 1);
9668c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
9669c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  return Allocate(isolate, size_smi->value(), OLD_DATA_SPACE);
96702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
96712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
96722bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
96735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Push an object unto an array of objects if it is not already in the
96749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// array.  Returns true if the element was pushed on the stack and
96759258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// false otherwise.
9676c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
967779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
96789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  ASSERT(args.length() == 2);
9679f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, array, 0);
9680e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, element, 1);
9681830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
96829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  int length = Smi::cast(array->length())->value();
96839258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  FixedArray* elements = FixedArray::cast(array->elements());
96849258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  for (int i = 0; i < length; i++) {
9685ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (elements->get(i) == element) return isolate->heap()->false_value();
96869258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
9687303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
96888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Strict not needed. Used for cycle detection in Array join implementation.
96897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  { MaybeObject* maybe_obj =
96907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        array->SetFastElement(length, element, kNonStrictMode, true);
9691303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9692303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
9693ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->true_value();
96949258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
96959258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
96969258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
96979bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org/**
96989bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * A simple visitor visits every element of Array's.
96999bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * The backend storage can be a fixed array for fast elements case,
97009bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * or a dictionary for sparse array. Since Dictionary is a subtype
97019bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * of FixedArray, the class can be used by both fast and slow cases.
97029bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * The second parameter of the constructor, fast_elements, specifies
97039bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * whether the storage is a FixedArray or Dictionary.
97049bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org *
97059bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * An index limit is used to deal with the situation that a result array
97069bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * length overflows 32-bit non-negative integer.
97079bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org */
97089bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.orgclass ArrayConcatVisitor {
97099bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org public:
9710ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ArrayConcatVisitor(Isolate* isolate,
9711ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                     Handle<FixedArray> storage,
97129bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org                     bool fast_elements) :
9713ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_(isolate),
9714ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      storage_(Handle<FixedArray>::cast(
9715ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->global_handles()->Create(*storage))),
97165d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      index_offset_(0u),
9717e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      fast_elements_(fast_elements),
9718e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      exceeds_array_limit_(false) { }
97199bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
97209ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  ~ArrayConcatVisitor() {
97219ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    clear_storage();
97229ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
97239ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
97249bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  void visit(uint32_t i, Handle<Object> elm) {
9725e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (i > JSObject::kMaxElementCount - index_offset_) {
9726e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      exceeds_array_limit_ = true;
9727e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      return;
9728e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
97290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    uint32_t index = index_offset_ + i;
97309bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
97319bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    if (fast_elements_) {
97325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (index < static_cast<uint32_t>(storage_->length())) {
97335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        storage_->set(index, *elm);
97345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        return;
97355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
97365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Our initial estimate of length was foiled, possibly by
97375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // getters on the arrays increasing the length of later arrays
97385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // during iteration.
97395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // This shouldn't happen in anything but pathological cases.
97405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      SetDictionaryMode(index);
97415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Fall-through to dictionary mode.
97429bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
97435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    ASSERT(!fast_elements_);
9744f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> dict(
9745f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        SeededNumberDictionary::cast(*storage_));
9746f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> result =
9747ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
97485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (!result.is_identical_to(dict)) {
97499ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      // Dictionary needed to grow.
97509ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      clear_storage();
97519ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      set_storage(*result);
97525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
9753fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
97549bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
97559bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  void increase_index_offset(uint32_t delta) {
97565d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (JSObject::kMaxElementCount - index_offset_ < delta) {
97575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      index_offset_ = JSObject::kMaxElementCount;
97580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    } else {
97590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      index_offset_ += delta;
97600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
97619bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
97629bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
9763e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool exceeds_array_limit() {
9764e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return exceeds_array_limit_;
9765e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
9766e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
97675d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  Handle<JSArray> ToArray() {
9768ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
97695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    Handle<Object> length =
9770ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
97715d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    Handle<Map> map;
97725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (fast_elements_) {
9773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      map = isolate_->factory()->GetElementsTransitionMap(array,
9774830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                                                          FAST_HOLEY_ELEMENTS);
97755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    } else {
9776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      map = isolate_->factory()->GetElementsTransitionMap(array,
9777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                          DICTIONARY_ELEMENTS);
97785d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
97795d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    array->set_map(*map);
97805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    array->set_length(*length);
97815d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    array->set_elements(*storage_);
97825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    return array;
97835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
9784edf0cd1f0a597ded80ff7c8ab0e5ffdbcb7a5391kasperl@chromium.org
97859bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org private:
97865d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // Convert storage to dictionary mode.
97875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  void SetDictionaryMode(uint32_t index) {
97885d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    ASSERT(fast_elements_);
97899ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    Handle<FixedArray> current_storage(*storage_);
9790f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> slow_storage(
9791f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        isolate_->factory()->NewSeededNumberDictionary(
9792f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com            current_storage->length()));
97935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    uint32_t current_length = static_cast<uint32_t>(current_storage->length());
97945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    for (uint32_t i = 0; i < current_length; i++) {
9795c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      HandleScope loop_scope(isolate_);
979609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      Handle<Object> element(current_storage->get(i), isolate_);
97975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (!element->IsTheHole()) {
9798f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        Handle<SeededNumberDictionary> new_storage =
9799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
98009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        if (!new_storage.is_identical_to(slow_storage)) {
98019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org          slow_storage = loop_scope.CloseAndEscape(new_storage);
98029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        }
98035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
98045d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
98059ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    clear_storage();
98069ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    set_storage(*slow_storage);
98075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    fast_elements_ = false;
98085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
98095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
98109ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  inline void clear_storage() {
9811ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate_->global_handles()->Destroy(
9812ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        Handle<Object>::cast(storage_).location());
98139ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
98149ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
98159ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  inline void set_storage(FixedArray* storage) {
9816ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    storage_ = Handle<FixedArray>::cast(
9817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->global_handles()->Create(storage));
98189ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
98199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
9820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
98219ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  Handle<FixedArray> storage_;  // Always a global handle.
98225d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // Index after last seen index. Always less than or equal to
98235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // JSObject::kMaxElementCount.
98249bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  uint32_t index_offset_;
9825e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool fast_elements_ : 1;
9826e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool exceeds_array_limit_ : 1;
98279bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org};
98289bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
98299bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
98305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgstatic uint32_t EstimateElementCount(Handle<JSArray> array) {
98315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t length = static_cast<uint32_t>(array->length()->Number());
98325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  int element_count = 0;
98335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  switch (array->GetElementsKind()) {
9834830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
9835830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
9836830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
9837830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
98385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Fast elements can't have lengths that are not representable by
98395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // a 32-bit signed integer.
98405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
98415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int fast_length = static_cast<int>(length);
98425d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      Handle<FixedArray> elements(FixedArray::cast(array->elements()));
98435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (int i = 0; i < fast_length; i++) {
98445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (!elements->get(i)->IsTheHole()) element_count++;
98455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
98465d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
98475d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
9848c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case FAST_DOUBLE_ELEMENTS:
9849fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS: {
9850fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // Fast elements can't have lengths that are not representable by
9851fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // a 32-bit signed integer.
9852fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
9853fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int fast_length = static_cast<int>(length);
9854fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (array->elements()->IsFixedArray()) {
9855fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ASSERT(FixedArray::cast(array->elements())->length() == 0);
9856fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        break;
9857fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
9858fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<FixedDoubleArray> elements(
9859fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          FixedDoubleArray::cast(array->elements()));
9860fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      for (int i = 0; i < fast_length; i++) {
9861fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (!elements->is_the_hole(i)) element_count++;
9862fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
9863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
9864fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
986583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case DICTIONARY_ELEMENTS: {
9866f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Handle<SeededNumberDictionary> dictionary(
9867f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          SeededNumberDictionary::cast(array->elements()));
98685d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int capacity = dictionary->Capacity();
98695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (int i = 0; i < capacity; i++) {
987009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
98715d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (dictionary->IsKey(*key)) {
98725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          element_count++;
98735d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
98745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
98755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
98765d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
9877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case NON_STRICT_ARGUMENTS_ELEMENTS:
9878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_BYTE_ELEMENTS:
9879c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
9880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_SHORT_ELEMENTS:
9881c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9882c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_INT_ELEMENTS:
9883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9884c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_FLOAT_ELEMENTS:
9885c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_DOUBLE_ELEMENTS:
9886c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case EXTERNAL_PIXEL_ELEMENTS:
98875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // External arrays are always dense.
98885d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      return length;
98895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
98905d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // As an estimate, we assume that the prototype doesn't contain any
98915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // inherited elements.
98925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return element_count;
98935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
98945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
98955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
98965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
98973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgtemplate<class ExternalArrayClass, class ElementType>
9898ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic void IterateExternalArrayElements(Isolate* isolate,
9899ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         Handle<JSObject> receiver,
99005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                         bool elements_are_ints,
99015d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                         bool elements_are_guaranteed_smis,
99025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                         ArrayConcatVisitor* visitor) {
99033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  Handle<ExternalArrayClass> array(
99043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      ExternalArrayClass::cast(receiver->elements()));
99055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t len = static_cast<uint32_t>(array->length());
99063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
99075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  ASSERT(visitor != NULL);
99085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  if (elements_are_ints) {
99095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (elements_are_guaranteed_smis) {
99105d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < len; j++) {
9911c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        HandleScope loop_scope(isolate);
991209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
991309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                      isolate);
99145d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        visitor->visit(j, e);
99155d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
99165d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    } else {
99175d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < len; j++) {
9918c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        HandleScope loop_scope(isolate);
99197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        int64_t val = static_cast<int64_t>(array->get_scalar(j));
99205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (Smi::IsValid(static_cast<intptr_t>(val))) {
992109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org          Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
99225d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          visitor->visit(j, e);
99235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        } else {
99245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          Handle<Object> e =
9925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org              isolate->factory()->NewNumber(static_cast<ElementType>(val));
99263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org          visitor->visit(j, e);
99273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        }
99285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
99295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
99305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  } else {
99315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    for (uint32_t j = 0; j < len; j++) {
9932ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      HandleScope loop_scope(isolate);
99337c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
99345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      visitor->visit(j, e);
99355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
99365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
99375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
99385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
99395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
99405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org// Used for sorting indices in a List<uint32_t>.
99415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgstatic int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
99425d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t a = *ap;
99435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t b = *bp;
99445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return (a == b) ? 0 : (a < b) ? -1 : 1;
99455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
99465d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
99475d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
99485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgstatic void CollectElementIndices(Handle<JSObject> object,
99495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                  uint32_t range,
99505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                  List<uint32_t>* indices) {
995109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Isolate* isolate = object->GetIsolate();
995283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ElementsKind kind = object->GetElementsKind();
99535d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  switch (kind) {
9954830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
9955830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
9956830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
9957830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
99585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      Handle<FixedArray> elements(FixedArray::cast(object->elements()));
99595d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      uint32_t length = static_cast<uint32_t>(elements->length());
99605d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (range < length) length = range;
99615d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t i = 0; i < length; i++) {
99625d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (!elements->get(i)->IsTheHole()) {
99635d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          indices->Add(i);
99645d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
99655d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
99665d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
99675d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
9968830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
9969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case FAST_DOUBLE_ELEMENTS: {
9970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // TODO(1810): Decide if it's worthwhile to implement this.
9971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      UNREACHABLE();
9972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
9973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
997483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case DICTIONARY_ELEMENTS: {
9975f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Handle<SeededNumberDictionary> dict(
9976f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          SeededNumberDictionary::cast(object->elements()));
99775d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      uint32_t capacity = dict->Capacity();
99785d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < capacity; j++) {
997909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        HandleScope loop_scope(isolate);
998009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> k(dict->KeyAt(j), isolate);
99815d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (dict->IsKey(*k)) {
99825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          ASSERT(k->IsNumber());
99835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          uint32_t index = static_cast<uint32_t>(k->Number());
99845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          if (index < range) {
99855d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org            indices->Add(index);
99863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org          }
99873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        }
99883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      }
99895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
99905d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
99915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    default: {
99925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int dense_elements_length;
99935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      switch (kind) {
999483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_PIXEL_ELEMENTS: {
99953847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
99963847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalPixelArray::cast(object->elements())->length();
99975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
99985d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
999983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_BYTE_ELEMENTS: {
100003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100013847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalByteArray::cast(object->elements())->length();
100025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
1000483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
100053847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100063847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalUnsignedByteArray::cast(object->elements())->length();
100075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
1000983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_SHORT_ELEMENTS: {
100103847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100113847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalShortArray::cast(object->elements())->length();
100125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100135d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
1001483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
100153847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100163847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalUnsignedShortArray::cast(object->elements())->length();
100175d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100185d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
1001983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_INT_ELEMENTS: {
100203847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100213847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalIntArray::cast(object->elements())->length();
100225d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
1002483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
100253847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100263847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalUnsignedIntArray::cast(object->elements())->length();
100275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
1002983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_FLOAT_ELEMENTS: {
100303847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100313847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalFloatArray::cast(object->elements())->length();
100323847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          break;
100333847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        }
1003483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        case EXTERNAL_DOUBLE_ELEMENTS: {
100353847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          dense_elements_length =
100363847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com              ExternalDoubleArray::cast(object->elements())->length();
100375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
100395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        default:
100405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          UNREACHABLE();
100415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          dense_elements_length = 0;
100425d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
100435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
100445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      uint32_t length = static_cast<uint32_t>(dense_elements_length);
100455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (range <= length) {
100465d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        length = range;
100475d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        // We will add all indices, so we might as well clear it first
100485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        // and avoid duplicates.
100495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        indices->Clear();
100505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
100515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t i = 0; i < length; i++) {
100525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        indices->Add(i);
100533811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      }
100545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (length == range) return;  // All indices accounted for already.
100555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
100563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
100573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
100583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
1005909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> prototype(object->GetPrototype(), isolate);
100605d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  if (prototype->IsJSObject()) {
100615d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // The prototype will usually have no inherited element indices,
100625d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // but we have to check.
100635d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
100645d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
100653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
100663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
100675d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
100689bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org/**
100695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * A helper function that visits elements of a JSArray in numerical
100705d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * order.
100719bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org *
100725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * The visitor argument called for each existing element in the array
100735d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * with the element index and the element's value.
100745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * Afterwards it increments the base-index of the visitor by the array
100755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * length.
100768f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org * Returns false if any access threw an exception, otherwise true.
100779bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org */
10078ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic bool IterateElements(Isolate* isolate,
10079ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            Handle<JSArray> receiver,
100805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                            ArrayConcatVisitor* visitor) {
100815d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
100820b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  switch (receiver->GetElementsKind()) {
10083830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
10084830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
10085830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
10086830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
100875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Run through the elements FixedArray and use HasElement and GetElement
100885d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // to check the prototype for missing elements.
100890b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
100905d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int fast_length = static_cast<int>(length);
100915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      ASSERT(fast_length <= elements->length());
100925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (int j = 0; j < fast_length; j++) {
10093ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        HandleScope loop_scope(isolate);
10094ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        Handle<Object> element_value(elements->get(j), isolate);
100955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (!element_value->IsTheHole()) {
100965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          visitor->visit(j, element_value);
100975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        } else if (receiver->HasElement(j)) {
100985d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          // Call GetElement on receiver, not its prototype, or getters won't
100995d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          // have the correct receiver.
10100394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          element_value = Object::GetElement(receiver, j);
10101394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
101025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          visitor->visit(j, element_value);
101030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        }
101040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
101050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
101060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
10107830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
10108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case FAST_DOUBLE_ELEMENTS: {
10109fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // Run through the elements FixedArray and use HasElement and GetElement
10110fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // to check the prototype for missing elements.
10111fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<FixedDoubleArray> elements(
10112fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          FixedDoubleArray::cast(receiver->elements()));
10113fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int fast_length = static_cast<int>(length);
10114fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ASSERT(fast_length <= elements->length());
10115fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      for (int j = 0; j < fast_length; j++) {
10116fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        HandleScope loop_scope(isolate);
10117fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (!elements->is_the_hole(j)) {
10118fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          double double_value = elements->get_scalar(j);
10119fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          Handle<Object> element_value =
10120fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              isolate->factory()->NewNumber(double_value);
10121fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          visitor->visit(j, element_value);
10122fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else if (receiver->HasElement(j)) {
10123fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          // Call GetElement on receiver, not its prototype, or getters won't
10124fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          // have the correct receiver.
10125fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          Handle<Object> element_value = Object::GetElement(receiver, j);
10126fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
10127fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          visitor->visit(j, element_value);
10128fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
10129fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
10130c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
10131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1013283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case DICTIONARY_ELEMENTS: {
10133f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
101345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      List<uint32_t> indices(dict->Capacity() / 2);
101355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Collect all indices in the object and the prototypes less
101365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // than length. This might introduce duplicates in the indices list.
101375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      CollectElementIndices(receiver, length, &indices);
101385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      indices.Sort(&compareUInt32);
101395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int j = 0;
101405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int n = indices.length();
101415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      while (j < n) {
10142c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        HandleScope loop_scope(isolate);
101435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        uint32_t index = indices[j];
10144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Handle<Object> element = Object::GetElement(receiver, index);
10145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
101465d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        visitor->visit(index, element);
101475d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        // Skip to next different index (i.e., omit duplicates).
101485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        do {
101495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          j++;
101505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        } while (j < n && indices[j] == index);
101515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
101525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
101535d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
1015483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_PIXEL_ELEMENTS: {
101554d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
101564d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org          receiver->elements()));
101575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < length; j++) {
1015809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
101595d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        visitor->visit(j, e);
101609bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org      }
101610b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
101629bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
1016383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_BYTE_ELEMENTS: {
101645d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalByteArray, int8_t>(
10165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
101663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
101673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
1016883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
101695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>(
10170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
101713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
101723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
1017383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_SHORT_ELEMENTS: {
101745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalShortArray, int16_t>(
10175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
101763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
101773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
1017883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
101795d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>(
10180ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
101813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
101823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
1018383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_INT_ELEMENTS: {
101845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalIntArray, int32_t>(
10185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, false, visitor);
101863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
101873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
1018883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
101895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>(
10190ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, false, visitor);
101913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
101923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
1019383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_FLOAT_ELEMENTS: {
101945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      IterateExternalArrayElements<ExternalFloatArray, float>(
10195ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, false, false, visitor);
101960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
101979bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
1019883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case EXTERNAL_DOUBLE_ELEMENTS: {
101993847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      IterateExternalArrayElements<ExternalDoubleArray, double>(
102003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          isolate, receiver, false, false, visitor);
102013847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      break;
102023847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
102030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    default:
102040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      UNREACHABLE();
102050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
102069bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
102075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  visitor->increase_index_offset(length);
102088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  return true;
102099bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org}
102109bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
102119bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
102129bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org/**
102139bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * Array::concat implementation.
102149bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * See ECMAScript 262, 15.4.4.4.
102155d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * TODO(581): Fix non-compliance for very large concatenations and update to
102160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * following the ECMAScript 5 specification.
102179bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org */
10218c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
10219ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handle_scope(isolate);
102206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
102219bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10222f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
102235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  int argument_count = static_cast<int>(arguments->length()->Number());
10224830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(arguments->HasFastObjectElements());
102255d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
102265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
102275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // Pass 1: estimate the length and number of elements of the result.
102285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // The actual length can be larger if any of the arguments have getters
102295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // that mutate other arguments (but will otherwise be precise).
102305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // The number of elements is precise if there are no inherited elements.
102315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
10232fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsKind kind = FAST_SMI_ELEMENTS;
10233fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
102345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t estimate_result_length = 0;
102355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t estimate_nof_elements = 0;
10236fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  for (int i = 0; i < argument_count; i++) {
10237c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    HandleScope loop_scope(isolate);
1023809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> obj(elements->get(i), isolate);
10239fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    uint32_t length_estimate;
10240fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    uint32_t element_estimate;
10241fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (obj->IsJSArray()) {
10242fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<JSArray> array(Handle<JSArray>::cast(obj));
10243fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      length_estimate = static_cast<uint32_t>(array->length()->Number());
10244fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (length_estimate != 0) {
10245fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ElementsKind array_kind =
10246fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            GetPackedElementsKind(array->map()->elements_kind());
10247fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
10248fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          kind = array_kind;
10249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
102505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
10251fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      element_estimate = EstimateElementCount(array);
10252fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
10253fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (obj->IsHeapObject()) {
10254fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (obj->IsNumber()) {
10255fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
10256fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            kind = FAST_DOUBLE_ELEMENTS;
10257fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          }
10258fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
10259fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          kind = FAST_ELEMENTS;
10260fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
102619bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org      }
10262fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      length_estimate = 1;
10263fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      element_estimate = 1;
10264fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
10265fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Avoid overflows by capping at kMaxElementCount.
10266fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (JSObject::kMaxElementCount - estimate_result_length <
10267fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        length_estimate) {
10268fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_result_length = JSObject::kMaxElementCount;
10269fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
10270fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_result_length += length_estimate;
10271fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
10272fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (JSObject::kMaxElementCount - estimate_nof_elements <
10273fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        element_estimate) {
10274fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_nof_elements = JSObject::kMaxElementCount;
10275fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
10276fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_nof_elements += element_estimate;
102779bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
102789bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
102799bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
102809bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // If estimated number of elements is more than half of length, a
102819bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // fixed array (fast case) is more time and space-efficient than a
102829bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // dictionary.
102835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
102849bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
102859bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  Handle<FixedArray> storage;
102869bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  if (fast_case) {
10287fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (kind == FAST_DOUBLE_ELEMENTS) {
10288fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<FixedDoubleArray> double_storage =
10289fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          isolate->factory()->NewFixedDoubleArray(estimate_result_length);
10290fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int j = 0;
10291fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      bool failure = false;
10292fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      for (int i = 0; i < argument_count; i++) {
1029309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> obj(elements->get(i), isolate);
10294fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (obj->IsSmi()) {
10295fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          double_storage->set(j, Smi::cast(*obj)->value());
10296fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          j++;
10297fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else if (obj->IsNumber()) {
10298fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          double_storage->set(j, obj->Number());
10299fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          j++;
10300fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else {
10301fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          JSArray* array = JSArray::cast(*obj);
10302fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          uint32_t length = static_cast<uint32_t>(array->length()->Number());
10303fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          switch (array->map()->elements_kind()) {
10304fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_HOLEY_DOUBLE_ELEMENTS:
10305fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_DOUBLE_ELEMENTS: {
10306fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              // Empty fixed array indicates that there are no elements.
10307fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              if (array->elements()->IsFixedArray()) break;
10308fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              FixedDoubleArray* elements =
10309fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  FixedDoubleArray::cast(array->elements());
10310fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              for (uint32_t i = 0; i < length; i++) {
10311fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                if (elements->is_the_hole(i)) {
10312fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  failure = true;
10313fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  break;
10314fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                }
10315fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                double double_value = elements->get_scalar(i);
10316fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                double_storage->set(j, double_value);
10317fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                j++;
10318fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              }
10319fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              break;
10320fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            }
10321fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_HOLEY_SMI_ELEMENTS:
10322fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_SMI_ELEMENTS: {
10323fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              FixedArray* elements(
10324fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  FixedArray::cast(array->elements()));
10325fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              for (uint32_t i = 0; i < length; i++) {
10326fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                Object* element = elements->get(i);
10327fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                if (element->IsTheHole()) {
10328fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  failure = true;
10329fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  break;
10330fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                }
10331fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                int32_t int_value = Smi::cast(element)->value();
10332fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                double_storage->set(j, int_value);
10333fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                j++;
10334fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              }
10335fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              break;
10336fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            }
10337fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_HOLEY_ELEMENTS:
10338fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              ASSERT_EQ(0, length);
10339fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              break;
10340fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            default:
10341fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              UNREACHABLE();
10342fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          }
10343fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
10344fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (failure) break;
10345fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
10346fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<JSArray> array = isolate->factory()->NewJSArray(0);
10347fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Smi* length = Smi::FromInt(j);
10348fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<Map> map;
10349fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      map = isolate->factory()->GetElementsTransitionMap(array, kind);
10350fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      array->set_map(*map);
10351fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      array->set_length(length);
10352fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      array->set_elements(*double_storage);
10353fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      return *array;
10354fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
10355fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // The backing storage array must have non-existing elements to preserve
10356fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // holes across concat operations.
10357ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    storage = isolate->factory()->NewFixedArrayWithHoles(
10358ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        estimate_result_length);
103599bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  } else {
103609bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
103619bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    uint32_t at_least_space_for = estimate_nof_elements +
103629bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org                                  (estimate_nof_elements >> 2);
103639bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    storage = Handle<FixedArray>::cast(
10364f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        isolate->factory()->NewSeededNumberDictionary(at_least_space_for));
103659bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
103669bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10367ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ArrayConcatVisitor visitor(isolate, storage, fast_case);
103689bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
103695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  for (int i = 0; i < argument_count; i++) {
1037009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> obj(elements->get(i), isolate);
103715d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (obj->IsJSArray()) {
103725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      Handle<JSArray> array = Handle<JSArray>::cast(obj);
10373ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (!IterateElements(isolate, array, &visitor)) {
103748f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        return Failure::Exception();
103758f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      }
103765d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    } else {
103775d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      visitor.visit(0, obj);
103785d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      visitor.increase_index_offset(1);
103795d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
103805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
103819bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (visitor.exceeds_array_limit()) {
10383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return isolate->Throw(
10384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        *isolate->factory()->NewRangeError("invalid_array_length",
10385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                           HandleVector<Object>(NULL, 0)));
10386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
103875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return *visitor.ToArray();
103889bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org}
103899bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
103909bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
1039143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This will not allocate (flatten the string), but it may run
1039243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// very slowly for very deeply nested ConsStrings.  For debugging use only.
10393c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
1039479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1039543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1039643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10397f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, string, 0);
103984cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ConsStringIteratorOp op;
103994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(string, &op);
104004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  while (stream.HasMore()) {
104014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t character = stream.GetNext();
1040243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("%c", character);
1040343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1040443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return string;
1040543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1040643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10407e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
104085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Moves all own elements of an object, that are below a limit, to positions
104095ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// starting at zero. All undefined values are placed after non-undefined values,
104105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// and are followed by non-existing element. Does not change the length
104115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// property.
104125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Returns the number of non-undefined elements collected.
10413c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
1041479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
104155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  ASSERT(args.length() == 2);
10416f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, object, 0);
104175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
104185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  return object->PrepareElementsForSort(limit);
1041943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1042043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1042143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1042243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Move contents of argument 0 (an array) to argument 1 (an array)
10423c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
1042479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1042543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
10426f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, from, 0);
10427f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, to, 1);
10428830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  from->ValidateElements();
10429830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  to->ValidateElements();
104304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  FixedArrayBase* new_elements = from->elements();
10431830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ElementsKind from_kind = from->GetElementsKind();
10432303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_new_map;
10433830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind);
10434303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* new_map;
10435303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
10436830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  to->set_map_and_elements(Map::cast(new_map), new_elements);
1043743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  to->set_length(from->length());
10438303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* obj;
10439303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  { MaybeObject* maybe_obj = from->ResetElements();
10440303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10441303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
10442b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  from->set_length(Smi::FromInt(0));
10443830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  to->ValidateElements();
1044443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return to;
1044543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1044643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1044743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104482ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org// How many elements does this object/array have?
10449c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
1045079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1045143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
10452f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, object, 0);
104532ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  HeapObject* elements = object->elements();
1045443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (elements->IsDictionary()) {
10455f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
10456f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return Smi::FromInt(result);
104572ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  } else if (object->IsJSArray()) {
104582ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    return JSArray::cast(object)->length();
1045943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
104602ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    return Smi::FromInt(FixedArray::cast(elements)->length());
1046143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1046243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1046343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1046443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1046543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns an array that tells you where in the [0, length) interval an array
10466f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// might have elements.  Can either return an array of keys (positive integers
10467f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// or undefined) or a number representing the positive length of an interval
10468f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// starting at index 0.
104692ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org// Intervals can span over some keys that are not in the object.
10470c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
10471ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
104726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 2);
10473f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
1047443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
104759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (array->elements()->IsDictionary()) {
10476f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10477f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    for (Handle<Object> p = array;
10478f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org         !p->IsNull();
10479f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org         p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
10480f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
10481f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        // Bail out if we find a proxy or interceptor, likely not worth
10482f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        // collecting keys in that case.
10483f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        return *isolate->factory()->NewNumberFromUint(length);
1048443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
10485f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      Handle<JSObject> current = Handle<JSObject>::cast(p);
10486f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      Handle<FixedArray> current_keys =
10487f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          isolate->factory()->NewFixedArray(
10488f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org              current->NumberOfLocalElements(NONE));
10489f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      current->GetLocalElementKeys(*current_keys, NONE);
10490f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      keys = UnionOfKeys(keys, current_keys);
10491f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
10492f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Erase any keys >= length.
10493f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10494f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // is changed to let this happen on the JS side.
10495f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    for (int i = 0; i < keys->length(); i++) {
10496f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
1049743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
10498ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return *isolate->factory()->NewJSArrayWithElements(keys);
1049943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
10500830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(array->HasFastSmiOrObjectElements() ||
10501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           array->HasFastDoubleElements());
10502f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10503f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
1050443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1050543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1050643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1050743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10508c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
1050979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1051043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
10511657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
10512750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_CHECKED(Name, name, 1);
10513f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(flag, 2);
105149a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10515657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
10516657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return JSObject::cast(receiver)->LookupAccessor(name, component);
1051743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1051843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1051943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1052065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
10521c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
1052279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1052365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  ASSERT(args.length() == 0);
1052465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  return Execution::DebugBreakHelper();
1052565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
1052665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
1052765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
1052843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper functions for wrapping and unwrapping stack frame ids.
1052943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic Smi* WrapFrameId(StackFrame::Id id) {
1053071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
1053143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(id >> 2);
1053243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1053343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1053443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10535f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic StackFrame::Id UnwrapFrameId(int wrapped) {
10536f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return static_cast<StackFrame::Id>(wrapped << 2);
1053743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1053843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1053943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1054043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Adds a JavaScript function as a debug event listener.
10541245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// args[0]: debug event listener function to set or null or undefined for
10542245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org//          clearing the event listener function
1054343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: object supplied during callback
10544c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetDebugEventListener) {
1054579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1054643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
10547245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  RUNTIME_ASSERT(args[0]->IsJSFunction() ||
10548245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                 args[0]->IsUndefined() ||
10549245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                 args[0]->IsNull());
10550245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  Handle<Object> callback = args.at<Object>(0);
10551245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  Handle<Object> data = args.at<Object>(1);
10552ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debugger()->SetEventListener(callback, data);
1055343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10554ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1055543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1055643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1055743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10558c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
1055979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1056031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
10561ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->stack_guard()->DebugBreak();
10562ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1056343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1056443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1056543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10566ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic MaybeObject* DebugLookupResultValue(Heap* heap,
10567ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Object* receiver,
10568750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                           Name* name,
10569303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                           LookupResult* result,
10570303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                           bool* caught_exception) {
10571715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org  Object* value;
1057243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (result->type()) {
105732abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    case NORMAL:
105742abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      value = result->holder()->GetNormalizedProperty(result);
10575715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      if (value->IsTheHole()) {
10576ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return heap->undefined_value();
10577715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      }
10578715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      return value;
1057957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    case FIELD: {
1058057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      Object* value;
1058157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      MaybeObject* maybe_value =
10582eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org          JSObject::cast(result->holder())->FastPropertyAt(
1058357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org              result->representation(),
10584eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org              result->GetFieldIndex().field_index());
1058557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      if (!maybe_value->To(&value)) return maybe_value;
10586715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      if (value->IsTheHole()) {
10587ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return heap->undefined_value();
10588715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      }
10589715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      return value;
1059057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
10591fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    case CONSTANT:
10592fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      return result->GetConstant();
105933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    case CALLBACKS: {
10594715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      Object* structure = result->GetCallbackObject();
10595ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      if (structure->IsForeign() || structure->IsAccessorInfo()) {
10596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
10597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            receiver, structure, name);
10598303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        if (!maybe_value->ToObject(&value)) {
10599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          if (maybe_value->IsRetryAfterGC()) return maybe_value;
10600303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org          ASSERT(maybe_value->IsException());
10601ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          maybe_value = heap->isolate()->pending_exception();
10602ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          heap->isolate()->clear_pending_exception();
10603715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org          if (caught_exception != NULL) {
10604715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org            *caught_exception = true;
10605715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org          }
10606303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org          return maybe_value;
106073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        }
10608715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org        return value;
10609715915b45e7c5370526276e83ffc62e42124218dsgjesse@chromium.org      } else {
10610ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return heap->undefined_value();
1061143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
106123291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    }
1061343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case INTERCEPTOR:
1061499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org    case TRANSITION:
10615ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return heap->undefined_value();
10616c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    case HANDLER:
106177a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    case NONEXISTENT:
1061843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
10619c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      return heap->undefined_value();
1062043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10621c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  UNREACHABLE();  // keep the compiler happy
10622ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return heap->undefined_value();
1062343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1062443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1062543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// Get debugger related details for an object property.
106273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// args[0]: object holding property
106283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// args[1]: name of the property
106293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org//
106303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// The array returned contains the following information:
106313291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 0: Property value
106323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 1: Property details
106333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 2: Property value is exception
106343291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 3: Getter function if defined
106353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 4: Setter function if defined
106363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// Items 2-4 are only filled if the property has either a getter or a setter
106373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// defined through __defineGetter__ and/or __defineSetter__.
10638c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
10639ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1064043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1064143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1064243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10643f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10644750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1064543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10646755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Make sure to set the current context to the context before the debugger was
10647755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // entered (if the debugger is entered). The reason for switching context here
10648755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // is that for some property lookups (accessors and interceptors) callbacks
10649755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // into the embedding application can occour, and the embedding application
1065046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // could have the assumption that its own native context is the current
10651755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // context and not some internal debugger context.
10652ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SaveContext save(isolate);
10653ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate->debug()->InDebugger()) {
10654ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
10655755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  }
10656755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
10657ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Skip the global proxy as it has no properties and always delegates to the
10658ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // real global object.
10659ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  if (obj->IsJSGlobalProxy()) {
10660ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
10661ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
10662ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10663ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1066443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the name is trivially convertible to an index and get the element
1066543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // if so.
1066643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
1066743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
10668ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
10669303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    Object* element_or_char;
10670303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    { MaybeObject* maybe_element_or_char =
10671ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          Runtime::GetElementOrCharAt(isolate, obj, index);
10672303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_element_or_char->ToObject(&element_or_char)) {
10673303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        return maybe_element_or_char;
10674303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
10675303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
106764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    details->set(0, element_or_char);
10677f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    details->set(
10678f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
10679ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return *isolate->factory()->NewJSArrayWithElements(details);
1068043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1068143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10682ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Find the number of objects making up this.
10683ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  int length = LocalPrototypeChainLength(*obj);
10684ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10685ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Try local lookup on each of the objects.
10686ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  Handle<JSObject> jsproto = obj;
10687ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  for (int i = 0; i < length; i++) {
10688394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    LookupResult result(isolate);
10689ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    jsproto->LocalLookup(*name, &result);
10690753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    if (result.IsFound()) {
106912bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // LookupResult is not GC safe as it holds raw object pointers.
106922bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // GC can happen later in this code so put the required fields into
106932bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // local variables using handles when required for later use.
106942bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      Handle<Object> result_callback_obj;
1069599aa490225c81012235659d9a183226b286178c8yangguo@chromium.org      if (result.IsPropertyCallbacks()) {
10696ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        result_callback_obj = Handle<Object>(result.GetCallbackObject(),
10697ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             isolate);
106982bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      }
106992bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      Smi* property_details = result.GetPropertyDetails().AsSmi();
107002bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // DebugLookupResultValue can cause GC so details from LookupResult needs
107012bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // to be copied to handles before this.
107022bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      bool caught_exception = false;
10703303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      Object* raw_value;
10704303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      { MaybeObject* maybe_raw_value =
10705ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            DebugLookupResultValue(isolate->heap(), *obj, *name,
10706ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                   &result, &caught_exception);
10707303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value;
10708303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
10709ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<Object> value(raw_value, isolate);
107102bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
107112bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // If the callback object is a fixed array then it contains JavaScript
107122bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // getter and/or setter.
1071399aa490225c81012235659d9a183226b286178c8yangguo@chromium.org      bool hasJavaScriptAccessors = result.IsPropertyCallbacks() &&
10714f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                    result_callback_obj->IsAccessorPair();
107152bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      Handle<FixedArray> details =
10716ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
107172bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      details->set(0, *value);
107182bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      details->set(1, property_details);
107192bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      if (hasJavaScriptAccessors) {
10720bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
107217c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        details->set(2, isolate->heap()->ToBoolean(caught_exception));
1072288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org        details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
1072388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org        details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
107242bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      }
107252bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
10726ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArrayWithElements(details);
10727ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
10728ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    if (i < length - 1) {
10729ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
10730ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
10731ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
10732ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10733ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1073443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1073543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1073643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10737c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
10738ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1073943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1074043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1074143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10742f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10743750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1074443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10745394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult result(isolate);
1074643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  obj->Lookup(*name, &result);
10747753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (result.IsFound()) {
10748ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
1074943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10750ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1075143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1075243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1075343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1075443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the property type calculated from the property details.
1075543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: smi with property details.
10756c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
1075779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1075843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
10759f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
10760f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return Smi::FromInt(static_cast<int>(details.type()));
1076143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1076243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1076343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1076443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the property attribute calculated from the property details.
1076543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: smi with property details.
10766c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
1076779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1076843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
10769f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
10770f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return Smi::FromInt(static_cast<int>(details.attributes()));
1077143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1077243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1077343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1077443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the property insertion index calculated from the property details.
1077543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: smi with property details.
10776c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
1077779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1077843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
10779f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
1078046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // TODO(verwaest): Depends on the type of details.
1078146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return Smi::FromInt(details.dictionary_index());
1078243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1078343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1078443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1078543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return property value from named interceptor.
1078643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: object
1078743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: property name
10788c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
10789ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1079043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
10791f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1079243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(obj->HasNamedInterceptor());
10793750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1079443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1079543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
107969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
1079743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1079843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1079943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1080043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return element value from indexed interceptor.
1080143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: object
1080243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: index
10803c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
10804ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1080543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
10806f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1080743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(obj->HasIndexedInterceptor());
1080843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
1080943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return obj->GetElementWithInterceptor(*obj, index);
1081143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1081243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1081343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10814c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CheckExecutionState) {
1081579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1081643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() >= 1);
1081743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
108188bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // Check that the break id is valid.
10819ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate->debug()->break_id() == 0 ||
10820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      break_id != isolate->debug()->break_id()) {
10821ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(
108224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        isolate->heap()->illegal_execution_state_string());
1082343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1082443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10825ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->true_value();
1082643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1082743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1082843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10829c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
10830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1083143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1083243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1083343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check arguments.
10834303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
10835c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_result = Runtime_CheckExecutionState(
10836c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
10837303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
10838303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1083943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1084043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Count all frames which are relevant to debugging stack trace.
1084143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n = 0;
10842ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  StackFrame::Id id = isolate->debug()->break_frame_id();
108438bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  if (id == StackFrame::NO_ID) {
108448bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    // If there is no JavaScript stack frame count is 0.
108458bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    return Smi::FromInt(0);
108468bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
108474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
108484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
108494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    n += it.frame()->GetInlineCount();
108504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
1085143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(n);
1085243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1085343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1085443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1085584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.orgclass FrameInspector {
1085684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org public:
1085784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  FrameInspector(JavaScriptFrame* frame,
10858659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                 int inlined_jsframe_index,
1085984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                 Isolate* isolate)
1086084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
1086184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    // Calculate the deoptimized frame.
1086284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (frame->is_optimized()) {
1086384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
10864659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          frame, inlined_jsframe_index, isolate);
1086584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    }
1086684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    has_adapted_arguments_ = frame_->has_adapted_arguments();
10867967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    is_bottommost_ = inlined_jsframe_index == 0;
1086884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    is_optimized_ = frame_->is_optimized();
1086984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1087084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1087184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ~FrameInspector() {
1087284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    // Get rid of the calculated deoptimized frame if any.
1087384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (deoptimized_frame_ != NULL) {
1087484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
1087584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                                                  isolate_);
1087684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    }
1087784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1087884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1087984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  int GetParametersCount() {
1088084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1088184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->parameters_count()
1088284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->ComputeParametersCount();
1088384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1088484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  int expression_count() { return deoptimized_frame_->expression_count(); }
1088584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Object* GetFunction() {
1088684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1088784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->GetFunction()
1088884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->function();
1088984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1089084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Object* GetParameter(int index) {
1089184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1089284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->GetParameter(index)
1089384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->GetParameter(index);
1089484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1089584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Object* GetExpression(int index) {
1089684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1089784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->GetExpression(index)
1089884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->GetExpression(index);
1089984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
10900fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  int GetSourcePosition() {
10901fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    return is_optimized_
10902fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org        ? deoptimized_frame_->GetSourcePosition()
10903fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org        : frame_->LookupCode()->SourcePosition(frame_->pc());
10904fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
10905967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool IsConstructor() {
10906967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    return is_optimized_ && !is_bottommost_
10907967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        ? deoptimized_frame_->HasConstructStub()
10908967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        : frame_->IsConstructor();
10909967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  }
1091084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1091184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  // To inspect all the provided arguments the frame might need to be
1091284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  // replaced with the arguments frame.
1091384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  void SetArgumentsFrame(JavaScriptFrame* frame) {
1091484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    ASSERT(has_adapted_arguments_);
1091584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    frame_ = frame;
1091684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    is_optimized_ = frame_->is_optimized();
1091784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    ASSERT(!is_optimized_);
1091884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1091984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1092084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org private:
1092184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  JavaScriptFrame* frame_;
1092284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  DeoptimizedFrameInfo* deoptimized_frame_;
1092384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Isolate* isolate_;
1092484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  bool is_optimized_;
10925967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool is_bottommost_;
1092684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  bool has_adapted_arguments_;
1092784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1092884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  DISALLOW_COPY_AND_ASSIGN(FrameInspector);
1092984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org};
1093084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1093184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1093243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsFrameIdIndex = 0;
1093343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsReceiverIndex = 1;
1093443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsFunctionIndex = 2;
1093543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsArgumentCountIndex = 3;
1093643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsLocalCountIndex = 4;
1093743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsSourcePositionIndex = 5;
1093843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsConstructCallIndex = 6;
109392cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgstatic const int kFrameDetailsAtReturnIndex = 7;
109404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic const int kFrameDetailsFlagsIndex = 8;
109412cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgstatic const int kFrameDetailsFirstDynamicIndex = 9;
1094243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10943c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
10944c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic SaveContext* FindSavedContextForFrame(Isolate* isolate,
10945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                             JavaScriptFrame* frame) {
10946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SaveContext* save = isolate->save_context();
10947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  while (save != NULL && !save->IsBelowFrame(frame)) {
10948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    save = save->prev();
10949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
10950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(save != NULL);
10951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return save;
10952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
10953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
10954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1095543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return an array with frame details
1095643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: number: break id
1095743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: number: frame index
1095843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1095943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The array returned contains the following information:
1096043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 0: Frame id
1096143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1: Receiver
1096243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2: Function
1096343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3: Argument count
1096443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 4: Local count
1096543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 5: Source position
1096643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 6: Constructor call
109672cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org// 7: Is at return
109684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org// 8: Flags
1096943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Arguments name, value
1097043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Locals name, value
109712cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org// Return value if any
10972c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
10973ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1097443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1097543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1097643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check arguments.
10977303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check;
10978c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
10979c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
10980303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
10981303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1098243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
10983ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
1098443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1098543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the relevant frame with the requested index.
10986ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  StackFrame::Id id = isolate->debug()->break_frame_id();
109878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  if (id == StackFrame::NO_ID) {
109888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    // If there are no JavaScript stack frames return undefined.
10989ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return heap->undefined_value();
109908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
109914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1099243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
1099374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate, id);
1099443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (; !it.done(); it.Advance()) {
109954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (index < count + it.frame()->GetInlineCount()) break;
109964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    count += it.frame()->GetInlineCount();
1099743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10998ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (it.done()) return heap->undefined_value();
1099943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11000659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  bool is_optimized = it.frame()->is_optimized();
11001659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11002659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
11003659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (is_optimized) {
11004659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    inlined_jsframe_index =
110054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        it.frame()->GetInlineCount() - (index - count) - 1;
110064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
11007659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
11008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the saved contexts chain to find the active context for the
1101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // selected frame.
11011c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
1101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the frame id.
11014ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
1101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11016fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Find source position in unoptimized code.
11017fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  int position = frame_inspector.GetSourcePosition();
1101843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11019967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  // Check for constructor frame.
11020967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool constructor = frame_inspector.IsConstructor();
1102143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110226a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Get scope info and read from it for local variable information.
11023659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11024717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11025c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
110268432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  ASSERT(*scope_info != ScopeInfo::Empty(isolate));
1102743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1102843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the locals names and values into a temporary array.
1102943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
1103043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1240907): Hide compiler-introduced stack variables
1103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // (e.g. .result)?  For users of the debugger, they will probably be
1103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // confusing.
11033ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> locals =
11034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      isolate->factory()->NewFixedArray(scope_info->LocalCount() * 2);
11035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Fill in the values of the locals.
110374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int i = 0;
11038c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (; i < scope_info->StackLocalCount(); ++i) {
110394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // Use the value from the stack.
11040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    locals->set(i * 2, scope_info->LocalName(i));
1104184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
110424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
11043c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (i < scope_info->LocalCount()) {
110443cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // Get the context containing declarations.
110453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    Handle<Context> context(
110463cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org        Context::cast(it.frame()->context())->declaration_context());
11047c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    for (; i < scope_info->LocalCount(); ++i) {
11048c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<String> name(scope_info->LocalName(i));
11049c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      VariableMode mode;
11050c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      InitializationFlag init_flag;
110513cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org      locals->set(i * 2, *name);
11052c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      locals->set(i * 2 + 1, context->get(
11053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          scope_info->ContextSlotIndex(*name, &mode, &init_flag)));
1105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check whether this frame is positioned at return. If not top
11058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // frame or if the frame is optimized it cannot be at a return.
11059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool at_return = false;
11060659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (!is_optimized && index == 0) {
11061ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    at_return = isolate->debug()->IsBreakAtReturn(it.frame());
11062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
110632cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
110642cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // If positioned just before return find the value to be returned and add it
110652cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // to the frame information.
11066ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> return_value = isolate->factory()->undefined_value();
110672cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  if (at_return) {
1106874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    StackFrameIterator it2(isolate);
110692cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    Address internal_frame_sp = NULL;
110702cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    while (!it2.done()) {
110712cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      if (it2.frame()->is_internal()) {
110722cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        internal_frame_sp = it2.frame()->sp();
110732cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      } else {
110742cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        if (it2.frame()->is_java_script()) {
110752cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org          if (it2.frame()->id() == it.frame()->id()) {
110762cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // The internal frame just before the JavaScript frame contains the
110772cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // value to return on top. A debug break at return will create an
110782cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // internal frame to store the return value (eax/rax/r0) before
110792cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // entering the debug break exit frame.
110802cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            if (internal_frame_sp != NULL) {
110812cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org              return_value =
11082ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                  Handle<Object>(Memory::Object_at(internal_frame_sp),
11083ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 isolate);
110842cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org              break;
110852cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            }
110862cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org          }
110872cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        }
110882cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
110892cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        // Indicate that the previous frame was not an internal frame.
110902cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        internal_frame_sp = NULL;
110912cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      }
110922cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      it2.Advance();
110932cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    }
110942cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  }
1109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Now advance to the arguments adapter frame (if any). It contains all
1109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the provided parameters whereas the function frame always have the number
1109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of arguments matching the functions parameters. The rest of the
1109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // information (except for what is collected above) is the same.
11100659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
1110184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    it.AdvanceToArgumentsFrame();
1110284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    frame_inspector.SetArgumentsFrame(it.frame());
1110384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1110543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the number of arguments to fill. At least fill the number of
1110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parameters for the function and fill more if more parameters are provided.
11107c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int argument_count = scope_info->ParameterCount();
1110884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  if (argument_count < frame_inspector.GetParametersCount()) {
1110984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    argument_count = frame_inspector.GetParametersCount();
1111084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Calculate the size of the result.
1111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int details_size = kFrameDetailsFirstDynamicIndex +
11114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                     2 * (argument_count + scope_info->LocalCount()) +
111152cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org                     (at_return ? 1 : 0);
11116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
1111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the frame id.
1111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsFrameIdIndex, *frame_id);
1112043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the function (same as in function frame).
1112284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
1112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the arguments count.
1112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
1112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the locals count
1112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsLocalCountIndex,
11129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org               Smi::FromInt(scope_info->LocalCount()));
1113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the source position.
11132236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  if (position != RelocInfo::kNoPosition) {
1113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
1113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
11135ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
1113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the constructor information.
11139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
1114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111412cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Add the at return information.
11142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
111432cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
111444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Add flags to indicate information on whether this frame is
111454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //   bit 0: invoked in the debugger context.
111464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //   bit 1: optimized frame.
111474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //   bit 2: inlined in optimized frame
111484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int flags = 0;
111494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (*save->context() == *isolate->debug()->debug_context()) {
111504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    flags |= 1 << 0;
111514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
11152659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (is_optimized) {
111534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    flags |= 1 << 1;
11154659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    flags |= inlined_jsframe_index << 2;
111554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
111564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
1115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the dynamic part.
1115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int details_index = kFrameDetailsFirstDynamicIndex;
1116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1116143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add arguments name and value.
1116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < argument_count; i++) {
1116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Name of the argument.
11164c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (i < scope_info->ParameterCount()) {
11165c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      details->set(details_index++, scope_info->ParameterName(i));
1116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
11167ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      details->set(details_index++, heap->undefined_value());
1116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111706db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    // Parameter value.
11171659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (i < frame_inspector.GetParametersCount()) {
1117284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      // Get the value from the stack.
1117384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      details->set(details_index++, frame_inspector.GetParameter(i));
1117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
1117584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      details->set(details_index++, heap->undefined_value());
1117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add locals name and value from the temporary copy from the function frame.
11180c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < scope_info->LocalCount() * 2; i++) {
1118143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    details->set(details_index++, locals->get(i));
1118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111842cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Add the value being returned.
111852cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  if (at_return) {
111862cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    details->set(details_index++, *return_value);
111872cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  }
111882cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
1118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the receiver (same as in function frame).
1119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
1119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // THE FRAME ITERATOR TO WRAP THE RECEIVER.
11192ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> receiver(it.frame()->receiver(), isolate);
111931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (!receiver->IsJSObject() &&
111941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      shared->is_classic_mode() &&
11195bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      !function->IsBuiltin()) {
11196717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // If the receiver is not a JSObject and the function is not a
11197717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // builtin or strict-mode we have hit an optimization where a
11198717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // value object is not converted into a wrapped JS objects. To
11199717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // hide this optimization from the debugger, we wrap the receiver
1120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // by creating correct wrapper object based on the calling frame's
1120146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // native context.
1120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.Advance();
1120346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Handle<Context> calling_frames_native_context(
1120446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        Context::cast(Context::cast(it.frame()->context())->native_context()));
11205bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ASSERT(!receiver->IsUndefined() && !receiver->IsNull());
11206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    receiver =
1120746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->factory()->ToObject(receiver, calling_frames_native_context);
1120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsReceiverIndex, *receiver);
1121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT_EQ(details_size, details_index);
11212ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(details);
1121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11216eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// Create a plain JSObject which materializes the local scope for the specified
11217eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// frame.
11218ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic Handle<JSObject> MaterializeStackLocalsWithFrameInspector(
1121984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    Isolate* isolate,
11220ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSObject> target,
11221ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSFunction> function,
11222659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    FrameInspector* frame_inspector) {
112236a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11225eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11226eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // First fill all parameters.
11227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
1122809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> value(i < frame_inspector->GetParametersCount()
1122909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             ? frame_inspector->GetParameter(i)
1123009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             : isolate->heap()->undefined_value(),
1123109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                         isolate);
11232594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(!value->IsTheHole());
11233659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11234496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    RETURN_IF_EMPTY_HANDLE_VALUE(
11235ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
112368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        SetProperty(isolate,
11237ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                    target,
11238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                    Handle<String>(scope_info->ParameterName(i)),
11239659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                    value,
112409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                    NONE,
112419ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                    kNonStrictMode),
11242496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        Handle<JSObject>());
11243eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11244eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11245eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Second fill all stack locals.
11246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11247594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (value->IsTheHole()) continue;
11249594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
11250496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    RETURN_IF_EMPTY_HANDLE_VALUE(
11251ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
112528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        SetProperty(isolate,
11253ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                    target,
11254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                    Handle<String>(scope_info->StackLocalName(i)),
11255594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                    value,
112569ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                    NONE,
112579ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                    kNonStrictMode),
11258496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org        Handle<JSObject>());
11259eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11260eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11261ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return target;
11262ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
112634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
11264ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11265ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11266ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    Handle<JSObject> target,
11267ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    Handle<JSFunction> function,
11268ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    JavaScriptFrame* frame,
11269ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    int inlined_jsframe_index) {
11270ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11271ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Optimized frames are not supported.
11272ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // TODO(yangguo): make sure all code deoptimized when debugger is active
11273ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    //                and assert that this cannot happen.
11274ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return;
11275ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11276ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11277ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11278ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11279ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11280ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Parameters.
11281ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11282594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(!frame->GetParameter(i)->IsTheHole());
11283ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HandleScope scope(isolate);
11284ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<Object> value = GetProperty(
11285ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        isolate, target, Handle<String>(scope_info->ParameterName(i)));
11286ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    frame->SetParameterValue(i, *value);
11287ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11288ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11289ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Stack locals.
11290ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11291594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (frame->GetExpression(i)->IsTheHole()) continue;
11292ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HandleScope scope(isolate);
11293ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<Object> value = GetProperty(
11294ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        isolate, target, Handle<String>(scope_info->StackLocalName(i)));
11295ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    frame->SetExpression(i, *value);
11296ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11297ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
11298ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11299ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11300ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
11301ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                Handle<JSObject> target,
11302ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                Handle<JSFunction> function,
11303ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                JavaScriptFrame* frame) {
11304ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  HandleScope scope(isolate);
11305ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11306ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11307ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11308ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!scope_info->HasContext()) return target;
11309ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11310ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Third fill all context locals.
11311ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Context> frame_context(Context::cast(frame->context()));
11312ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Context> function_context(frame_context->declaration_context());
11313ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!scope_info->CopyContextLocalsToScopeObject(
11314ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org          isolate, function_context, target)) {
11315ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return Handle<JSObject>();
11316ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11317ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11318ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Finally copy any properties from the function context extension.
11319ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // These will be variables introduced by eval.
11320ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (function_context->closure() == *function) {
11321ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (function_context->has_extension() &&
11322ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        !function_context->IsNativeContext()) {
11323ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11324ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      bool threw = false;
11325ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Handle<FixedArray> keys =
11326ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org          GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
11327ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      if (threw) return Handle<JSObject>();
11328ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11329ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      for (int i = 0; i < keys->length(); i++) {
11330ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        // Names of variables introduced by eval are strings.
11331ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        ASSERT(keys->get(i)->IsString());
11332ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        Handle<String> key(String::cast(keys->get(i)));
11333ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        RETURN_IF_EMPTY_HANDLE_VALUE(
11334ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            isolate,
11335ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            SetProperty(isolate,
11336ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                        target,
11337ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                        key,
11338ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                        GetProperty(isolate, ext, key),
11339ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                        NONE,
11340ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                        kNonStrictMode),
11341ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            Handle<JSObject>());
11342eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      }
11343eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11344eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
113454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
11346ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return target;
11347eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
11348eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11349eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11350659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgstatic Handle<JSObject> MaterializeLocalScope(
11351659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Isolate* isolate,
11352659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JavaScriptFrame* frame,
11353659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int inlined_jsframe_index) {
11354659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
11355ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11356ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11357ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSObject> local_scope =
11358ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
11359ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  local_scope = MaterializeStackLocalsWithFrameInspector(
11360ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                    isolate, local_scope, function, &frame_inspector);
11361ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, local_scope, Handle<JSObject>());
11362ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11363ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return MaterializeLocalContext(isolate, local_scope, function, frame);
11364659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
11365659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11366659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11367a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Set the context local variable value.
11368a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic bool SetContextLocalValue(Isolate* isolate,
11369a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<ScopeInfo> scope_info,
11370a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<Context> context,
11371a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<String> variable_name,
11372a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<Object> new_value) {
11373a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
11374a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<String> next_name(scope_info->ContextLocalName(i));
11375a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (variable_name->Equals(*next_name)) {
11376a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      VariableMode mode;
11377a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      InitializationFlag init_flag;
11378a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      int context_index =
11379a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          scope_info->ContextSlotIndex(*next_name, &mode, &init_flag);
11380a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      context->set(context_index, *new_value);
11381a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return true;
11382a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11383a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11384a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11385a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return false;
11386a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11387a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11388a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11389a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic bool SetLocalVariableValue(Isolate* isolate,
11390a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  JavaScriptFrame* frame,
11391a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  int inlined_jsframe_index,
11392a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<String> variable_name,
11393a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<Object> new_value) {
11394a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11395a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Optimized frames are not supported.
11396a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
11397a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11398a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11399169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Handle<JSFunction> function(frame->function());
11400a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11401a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11402a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11403a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool default_result = false;
11404a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11405a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Parameters.
11406a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11407a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (scope_info->ParameterName(i)->Equals(*variable_name)) {
11408a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      frame->SetParameterValue(i, *new_value);
11409a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Argument might be shadowed in heap context, don't stop here.
11410a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      default_result = true;
11411a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11412a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11413a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11414a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Stack locals.
11415a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11416a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (scope_info->StackLocalName(i)->Equals(*variable_name)) {
11417a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      frame->SetExpression(i, *new_value);
11418a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return true;
11419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11420a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11421a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11422a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (scope_info->HasContext()) {
11423a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Context locals.
11424a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<Context> frame_context(Context::cast(frame->context()));
11425a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<Context> function_context(frame_context->declaration_context());
11426a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (SetContextLocalValue(
11427a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        isolate, scope_info, function_context, variable_name, new_value)) {
11428a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return true;
11429a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11430a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11431a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Function context extension. These are variables introduced by eval.
11432a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (function_context->closure() == *function) {
11433a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (function_context->has_extension() &&
11434a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          !function_context->IsNativeContext()) {
11435a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11436a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11437a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        if (ext->HasProperty(*variable_name)) {
11438a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          // We don't expect this to do anything except replacing
11439a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          // property value.
11440a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          SetProperty(isolate,
11441a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      ext,
11442a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      variable_name,
11443a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      new_value,
11444a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      NONE,
11445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      kNonStrictMode);
11446a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          return true;
11447a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        }
11448a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
11449a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11450a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11451a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11452a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return default_result;
11453a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11454a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11455a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11456eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// Create a plain JSObject which materializes the closure content for the
11457eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// context.
11458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic Handle<JSObject> MaterializeClosure(Isolate* isolate,
11459ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                           Handle<Context> context) {
114606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  ASSERT(context->IsFunctionContext());
11461eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
114626a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  Handle<SharedFunctionInfo> shared(context->closure()->shared());
11463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11464eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
114652efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Allocate and initialize a JSObject with all the content of this function
11466eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // closure.
11467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSObject> closure_scope =
11468ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
11469eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11470eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Fill all context locals to the context extension.
1147171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  if (!scope_info->CopyContextLocalsToScopeObject(
1147271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org          isolate, context, closure_scope)) {
11473496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    return Handle<JSObject>();
11474496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  }
11475eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11476eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Finally copy any properties from the function context extension. This will
11477eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // be variables introduced by eval.
11478eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (context->has_extension()) {
11479eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    Handle<JSObject> ext(JSObject::cast(context->extension()));
11480394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bool threw = false;
11481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<FixedArray> keys =
11482394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
11483394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (threw) return Handle<JSObject>();
11484394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
11485eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    for (int i = 0; i < keys->length(); i++) {
11486eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      // Names of variables introduced by eval are strings.
11487eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      ASSERT(keys->get(i)->IsString());
11488eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      Handle<String> key(String::cast(keys->get(i)));
11489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org       RETURN_IF_EMPTY_HANDLE_VALUE(
11490ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate,
114918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          SetProperty(isolate,
114928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                      closure_scope,
114939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                      key,
1149409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                      GetProperty(isolate, ext, key),
114959ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                      NONE,
114969ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                      kNonStrictMode),
11497496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org          Handle<JSObject>());
11498eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11499eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11500eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11501eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  return closure_scope;
11502eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
11503eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11504eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1150549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// This method copies structure of MaterializeClosure method above.
1150649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgstatic bool SetClosureVariableValue(Isolate* isolate,
1150749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                    Handle<Context> context,
1150849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                    Handle<String> variable_name,
1150949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                    Handle<Object> new_value) {
1151049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  ASSERT(context->IsFunctionContext());
1151149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1151249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  Handle<SharedFunctionInfo> shared(context->closure()->shared());
1151349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
1151449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1151549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Context locals to the context extension.
11516a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (SetContextLocalValue(
11517a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          isolate, scope_info, context, variable_name, new_value)) {
11518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return true;
1151949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1152049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1152149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Properties from the function context extension. This will
1152249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // be variables introduced by eval.
1152349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  if (context->has_extension()) {
1152449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    Handle<JSObject> ext(JSObject::cast(context->extension()));
1152549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    if (ext->HasProperty(*variable_name)) {
1152649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      // We don't expect this to do anything except replacing property value.
1152749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      SetProperty(isolate,
1152849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                  ext,
1152949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                  variable_name,
1153049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                  new_value,
1153149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                  NONE,
1153249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                  kNonStrictMode);
1153349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      return true;
1153449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
1153549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1153649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1153749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return false;
1153849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
1153949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1154049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
115416d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// Create a plain JSObject which materializes the scope for the specified
115426d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// catch context.
115436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgstatic Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
115446d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                                              Handle<Context> context) {
115456d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  ASSERT(context->IsCatchContext());
115466d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Handle<String> name(String::cast(context->extension()));
1154709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
1154809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                               isolate);
115496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Handle<JSObject> catch_scope =
115506d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
115516d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  RETURN_IF_EMPTY_HANDLE_VALUE(
115526d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      isolate,
115538e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      SetProperty(isolate,
115548e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                  catch_scope,
115558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                  name,
115568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                  thrown_object,
115578e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                  NONE,
115588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                  kNonStrictMode),
115596d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      Handle<JSObject>());
115606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return catch_scope;
115616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
115626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
115636d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
11564a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic bool SetCatchVariableValue(Isolate* isolate,
11565a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<Context> context,
11566a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<String> variable_name,
11567a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<Object> new_value) {
11568a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(context->IsCatchContext());
11569a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<String> name(String::cast(context->extension()));
11570a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (!name->Equals(*variable_name)) {
11571a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
11572a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11573a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  context->set(Context::THROWN_OBJECT_INDEX, *new_value);
11574a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return true;
11575a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11576a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11577a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
115784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org// Create a plain JSObject which materializes the block scope for the specified
115794acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org// block context.
115804acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgstatic Handle<JSObject> MaterializeBlockScope(
115814acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Isolate* isolate,
115824acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Handle<Context> context) {
115834acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  ASSERT(context->IsBlockContext());
11584c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
115854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
115864acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Allocate and initialize a JSObject with all the arguments, stack locals
115874acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // heap locals and extension properties of the debugged function.
115884acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Handle<JSObject> block_scope =
115894acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
115904acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
115914acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Fill all context locals.
1159271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  if (!scope_info->CopyContextLocalsToScopeObject(
1159371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org          isolate, context, block_scope)) {
11594c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    return Handle<JSObject>();
115954acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
115964acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
115974acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return block_scope;
115984acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
115994acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
116004acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
11601f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// Create a plain JSObject which materializes the module scope for the specified
11602f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// module context.
11603f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic Handle<JSObject> MaterializeModuleScope(
11604f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Isolate* isolate,
11605f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Handle<Context> context) {
11606f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  ASSERT(context->IsModuleContext());
11607f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11608f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11609f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Allocate and initialize a JSObject with all the members of the debugged
11610f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // module.
11611f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<JSObject> module_scope =
11612f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
11613f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11614f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Fill all context locals.
1161571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  if (!scope_info->CopyContextLocalsToScopeObject(
1161671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org          isolate, context, module_scope)) {
11617f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    return Handle<JSObject>();
11618f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
11619f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11620f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return module_scope;
11621f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
11622f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11623f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
116241044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// Iterate over the actual scopes visible from a stack frame or from a closure.
116251044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// The iteration proceeds from the innermost visible nested scope outwards.
116261044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// All scopes are backed by an actual context except the local scope,
116271044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// which is inserted "artificially" in the context chain.
11628eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgclass ScopeIterator {
11629eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org public:
11630eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  enum ScopeType {
11631eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ScopeTypeGlobal = 0,
11632eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ScopeTypeLocal,
11633eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ScopeTypeWith,
11634a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    ScopeTypeClosure,
116354acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    ScopeTypeCatch,
11636f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    ScopeTypeBlock,
11637f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    ScopeTypeModule
11638eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  };
11639eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1164084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ScopeIterator(Isolate* isolate,
1164184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                JavaScriptFrame* frame,
11642659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                int inlined_jsframe_index)
11643ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(isolate),
11644ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      frame_(frame),
11645659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      inlined_jsframe_index_(inlined_jsframe_index),
11646169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      function_(frame->function()),
11647eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      context_(Context::cast(frame->context())),
1164856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      nested_scope_chain_(4),
1164956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      failed_(false) {
116501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
116511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Catch the case when the debugger stops in an internal function.
116521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Handle<SharedFunctionInfo> shared_info(function_->shared());
116531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Handle<ScopeInfo> scope_info(shared_info->scope_info());
116541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (shared_info->script() == isolate->heap()->undefined_value()) {
116551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      while (context_->closure() == *function_) {
116561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        context_ = Handle<Context>(context_->previous(), isolate_);
116571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
116581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return;
116591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
116601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
116611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Get the debug info (create it if it does not exist).
116625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
116631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Return if ensuring debug info failed.
116641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return;
116651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
116661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
116671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
116681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Find the break point where execution has stopped.
116691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    BreakLocationIterator break_location_iterator(debug_info,
116701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                                  ALL_BREAK_LOCATIONS);
116718a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // pc points to the instruction after the current one, possibly a break
116728a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    // location as well. So the "- 1" to exclude it from the search.
116738a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
116741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (break_location_iterator.IsExit()) {
116751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // We are within the return sequence. At the momemt it is not possible to
116761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // get a source position which is consistent with the current scope chain.
116771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Thus all nested with, catch and block contexts are skipped and we only
116781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // provide the function scope.
116791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (scope_info->HasContext()) {
116801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        context_ = Handle<Context>(context_->declaration_context(), isolate_);
116811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      } else {
116821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        while (context_->closure() == *function_) {
116831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          context_ = Handle<Context>(context_->previous(), isolate_);
116841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
116851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
11686dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (scope_info->scope_type() != EVAL_SCOPE) {
11687dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        nested_scope_chain_.Add(scope_info);
11688dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      }
116891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else {
116901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Reparse the code and analyze the scopes.
116911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Handle<Script> script(Script::cast(shared_info->script()));
116921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Scope* scope = NULL;
116931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
116941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Check whether we are in global, eval or function code.
116951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Handle<ScopeInfo> scope_info(shared_info->scope_info());
11696dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (scope_info->scope_type() != FUNCTION_SCOPE) {
116971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // Global or eval code.
116985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        CompilationInfoWithZone info(script);
11699dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        if (scope_info->scope_type() == GLOBAL_SCOPE) {
117001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          info.MarkAsGlobal();
117011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        } else {
11702dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org          ASSERT(scope_info->scope_type() == EVAL_SCOPE);
117031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          info.MarkAsEval();
11704355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          info.SetContext(Handle<Context>(function_->context()));
117051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
11706e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
117071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          scope = info.function()->scope();
117081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
117095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        RetrieveScopeChain(scope, shared_info);
117101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      } else {
117111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // Function code
117125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        CompilationInfoWithZone info(shared_info);
11713e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
117141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          scope = info.function()->scope();
117151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
117165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        RetrieveScopeChain(scope, shared_info);
117171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
11718eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11719eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11720eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
117211044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ScopeIterator(Isolate* isolate,
117221044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org                Handle<JSFunction> function)
117231044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    : isolate_(isolate),
117241044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      frame_(NULL),
117251044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      inlined_jsframe_index_(0),
117261044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      function_(function),
1172756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      context_(function->context()),
1172856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      failed_(false) {
117291044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    if (function->IsBuiltin()) {
117301044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      context_ = Handle<Context>();
117311044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    }
117321044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
117331044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
11734eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // More scopes?
1173556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool Done() {
1173656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
1173756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    return context_.is_null();
1173856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
1173956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
1174056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool Failed() { return failed_; }
11741eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11742eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Move to the next scope.
11743eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void Next() {
1174456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
117451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ScopeType scope_type = Type();
117461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (scope_type == ScopeTypeGlobal) {
117471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // The global scope is always the last in the chain.
1174846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(context_->IsNativeContext());
11749eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      context_ = Handle<Context>();
11750eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return;
11751eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
117521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (nested_scope_chain_.is_empty()) {
117531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      context_ = Handle<Context>(context_->previous(), isolate_);
117541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else {
117551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (nested_scope_chain_.last()->HasContext()) {
117561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        ASSERT(context_->previous() != NULL);
117571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        context_ = Handle<Context>(context_->previous(), isolate_);
117581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
117591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      nested_scope_chain_.RemoveLast();
11760eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11761eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11762eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11763eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Return the type of the current scope.
1176434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ScopeType Type() {
1176556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
117661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!nested_scope_chain_.is_empty()) {
117671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
11768dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      switch (scope_info->scope_type()) {
117691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case FUNCTION_SCOPE:
117701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(context_->IsFunctionContext() ||
117711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                 !scope_info->HasContext());
117721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeLocal;
11773f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        case MODULE_SCOPE:
11774f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org          ASSERT(context_->IsModuleContext());
11775f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org          return ScopeTypeModule;
117761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case GLOBAL_SCOPE:
1177746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          ASSERT(context_->IsNativeContext());
117781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeGlobal;
117791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case WITH_SCOPE:
117801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(context_->IsWithContext());
117811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeWith;
117821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case CATCH_SCOPE:
117831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(context_->IsCatchContext());
117841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeCatch;
117851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case BLOCK_SCOPE:
117861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(!scope_info->HasContext() ||
117871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                 context_->IsBlockContext());
117881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeBlock;
117891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case EVAL_SCOPE:
117901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          UNREACHABLE();
117911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
11792eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
1179346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (context_->IsNativeContext()) {
1179446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(context_->global_object()->IsGlobalObject());
11795eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return ScopeTypeGlobal;
11796eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
117976d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (context_->IsFunctionContext()) {
11798eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return ScopeTypeClosure;
11799eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
118006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (context_->IsCatchContext()) {
11801a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      return ScopeTypeCatch;
11802a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    }
118034acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (context_->IsBlockContext()) {
118044acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      return ScopeTypeBlock;
118054acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
11806f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    if (context_->IsModuleContext()) {
11807f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ScopeTypeModule;
11808f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    }
118096d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    ASSERT(context_->IsWithContext());
11810eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    return ScopeTypeWith;
11811eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11812eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11813eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Return the JavaScript object with the content of the current scope.
11814eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<JSObject> ScopeObject() {
1181556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
11816eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    switch (Type()) {
11817eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeGlobal:
1181846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        return Handle<JSObject>(CurrentContext()->global_object());
11819eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeLocal:
11820eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        // Materialize the content of the local scope into a JSObject.
118211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        ASSERT(nested_scope_chain_.length() == 1);
11822659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
11823eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeWith:
11824eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        // Return the with object.
118256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
118266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeCatch:
118276d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        return MaterializeCatchScope(isolate_, CurrentContext());
11828eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeClosure:
11829eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        // Materialize the content of the closure scope into a JSObject.
11830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return MaterializeClosure(isolate_, CurrentContext());
118314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      case ScopeIterator::ScopeTypeBlock:
118324acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        return MaterializeBlockScope(isolate_, CurrentContext());
11833f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      case ScopeIterator::ScopeTypeModule:
11834f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        return MaterializeModuleScope(isolate_, CurrentContext());
11835eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11836eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    UNREACHABLE();
11837eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    return Handle<JSObject>();
11838eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11839eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1184049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  bool SetVariableValue(Handle<String> variable_name,
1184149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                        Handle<Object> new_value) {
1184249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    ASSERT(!failed_);
1184349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    switch (Type()) {
1184449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeGlobal:
1184549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1184649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeLocal:
11847a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
11848a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org            variable_name, new_value);
1184949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeWith:
1185049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1185149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeCatch:
11852a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        return SetCatchVariableValue(isolate_, CurrentContext(),
11853a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org            variable_name, new_value);
1185449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeClosure:
1185549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        return SetClosureVariableValue(isolate_, CurrentContext(),
1185649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org            variable_name, new_value);
1185749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeBlock:
1185849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        // TODO(2399): should we implement it?
1185949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1186049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeModule:
1186149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        // TODO(2399): should we implement it?
1186249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1186349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
1186449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    return false;
1186549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1186649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
118671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<ScopeInfo> CurrentScopeInfo() {
1186856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
118691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!nested_scope_chain_.is_empty()) {
118701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return nested_scope_chain_.last();
118711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else if (context_->IsBlockContext()) {
118721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
118731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else if (context_->IsFunctionContext()) {
118741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
118751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
118761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return Handle<ScopeInfo>::null();
118771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
118781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
11879eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Return the context for this scope. For the local context there might not
11880eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // be an actual context.
11881eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<Context> CurrentContext() {
1188256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
118831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (Type() == ScopeTypeGlobal ||
118841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        nested_scope_chain_.is_empty()) {
118851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return context_;
118861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else if (nested_scope_chain_.last()->HasContext()) {
118871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return context_;
118881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else {
11889eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return Handle<Context>();
11890eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11891eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11892eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11893eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG
11894eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Debug print of the content of the current scope.
11895eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void DebugPrint() {
1189656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
11897eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    switch (Type()) {
11898eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeGlobal:
11899eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("Global:\n");
11900eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        CurrentContext()->Print();
11901eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
11902eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11903eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeLocal: {
11904eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("Local:\n");
11905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        function_->shared()->scope_info()->Print();
11906eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        if (!CurrentContext().is_null()) {
11907eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          CurrentContext()->Print();
11908eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          if (CurrentContext()->has_extension()) {
1190909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org            Handle<Object> extension(CurrentContext()->extension(), isolate_);
11910eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org            if (extension->IsJSContextExtensionObject()) {
11911eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org              extension->Print();
11912eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org            }
11913eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          }
11914eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        }
11915eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
11916eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      }
11917eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
119186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeWith:
11919eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("With:\n");
119206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        CurrentContext()->extension()->Print();
11921eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
11922eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
119236d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeCatch:
11924a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        PrintF("Catch:\n");
119256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        CurrentContext()->extension()->Print();
119266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
11927a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        break;
11928a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
119296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeClosure:
11930eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("Closure:\n");
11931eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        CurrentContext()->Print();
11932eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        if (CurrentContext()->has_extension()) {
1193309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org          Handle<Object> extension(CurrentContext()->extension(), isolate_);
11934eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          if (extension->IsJSContextExtensionObject()) {
11935eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org            extension->Print();
11936eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          }
11937eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        }
11938eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
11939eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11940eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      default:
11941eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        UNREACHABLE();
11942eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11943eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    PrintF("\n");
11944eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11945eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
11946eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11947eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org private:
11948ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
11949eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame_;
11950659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int inlined_jsframe_index_;
11951eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<JSFunction> function_;
11952eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<Context> context_;
119531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  List<Handle<ScopeInfo> > nested_scope_chain_;
1195456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool failed_;
11955eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
119565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void RetrieveScopeChain(Scope* scope,
119575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                          Handle<SharedFunctionInfo> shared_info) {
119585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (scope != NULL) {
119595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      int source_position = shared_info->code()->SourcePosition(frame_->pc());
119605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
119615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    } else {
119625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // A failed reparse indicates that the preparser has diverged from the
119635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // parser or that the preparse data given to the initial parse has been
119645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // faulty. We fail in debug mode but in release mode we only provide the
119655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // information we get from the context chain but nothing about
119665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // completely stack allocated scopes or stack allocated locals.
1196756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      // Or it could be due to stack overflow.
1196856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      ASSERT(isolate_->has_pending_exception());
1196956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      failed_ = true;
119705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
119715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
119725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
11973eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
11974eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org};
11975eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11976eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11977c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
11978ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
11979eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(args.length() == 2);
11980eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11981eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Check arguments.
11982303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check;
11983c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
11984c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
11985303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
11986303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
11987f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
11988eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11989eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Get the frame where the debugging is performed.
11990eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
1199174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate, id);
11992eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame = it.frame();
11993eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11994eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Count the visible scopes.
11995eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  int n = 0;
1199684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  for (ScopeIterator it(isolate, frame, 0);
1199784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       !it.Done();
1199884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       it.Next()) {
11999eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    n++;
12000eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12001eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12002eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  return Smi::FromInt(n);
12003eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12004eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12005eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
120061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Returns the list of step-in positions (text offset) in a function of the
120071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// stack frame in a range from the current debug break position to the end
120081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// of the corresponding statement.
120091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
120101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
120111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 2);
120121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
120131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Check arguments.
120141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* check;
120151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
120161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
120171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
120181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
120191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
120201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
120211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Get the frame where the debugging is performed.
120221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
120231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  JavaScriptFrameIterator frame_it(isolate, id);
120241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  JavaScriptFrame* frame = frame_it.frame();
120251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12026594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSFunction> fun =
12027594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Handle<JSFunction>(frame->function());
120281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<SharedFunctionInfo> shared =
12029594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Handle<SharedFunctionInfo>(fun->shared());
12030594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
12031594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
12032594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->undefined_value();
12033594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
12034594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
120351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
120361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
120371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int len = 0;
120381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<JSArray> array(isolate->factory()->NewJSArray(10));
120391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Find the break point where execution has stopped.
120401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  BreakLocationIterator break_location_iterator(debug_info,
120411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                ALL_BREAK_LOCATIONS);
120421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
120431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  break_location_iterator.FindBreakLocationFromAddress(frame->pc());
120441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int current_statement_pos = break_location_iterator.statement_position();
120451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
120461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  while (!break_location_iterator.Done()) {
12047594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (break_location_iterator.pc() > frame->pc()) {
12048594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (break_location_iterator.IsStepInLocation(isolate)) {
12049594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Smi* position_value = Smi::FromInt(break_location_iterator.position());
12050594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        JSObject::SetElement(array, len,
12051594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            Handle<Object>(position_value, isolate),
12052594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE, kNonStrictMode);
12053594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        len++;
12054594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
120551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
120561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // Advance iterator.
120571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    break_location_iterator.Next();
120581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (current_statement_pos !=
120591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        break_location_iterator.statement_position()) {
120601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      break;
120611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
120621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
120631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return *array;
120641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
120651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
120661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12067eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgstatic const int kScopeDetailsTypeIndex = 0;
12068eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgstatic const int kScopeDetailsObjectIndex = 1;
12069eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgstatic const int kScopeDetailsSize = 2;
12070eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
120711044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
120721044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.orgstatic MaybeObject* MaterializeScopeDetails(Isolate* isolate,
120731044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    ScopeIterator* it) {
120741044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Calculate the size of the result.
120751044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  int details_size = kScopeDetailsSize;
120761044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
120771044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
120781044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Fill in scope details.
120791044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
120801044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  Handle<JSObject> scope_object = it->ScopeObject();
120811044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, scope_object);
120821044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  details->set(kScopeDetailsObjectIndex, *scope_object);
120831044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
120841044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  return *isolate->factory()->NewJSArrayWithElements(details);
120851044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org}
120861044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
12087e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
12088eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// Return an array with scope details
12089eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// args[0]: number: break id
12090eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// args[1]: number: frame index
1209184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org// args[2]: number: inlined frame index
1209284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org// args[3]: number: scope index
12093eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org//
12094eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// The array returned contains the following information:
12095eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// 0: Scope type
12096eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// 1: Scope object
12097c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
12098ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1209984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ASSERT(args.length() == 4);
12100eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12101eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Check arguments.
12102303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check;
12103c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
12104c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
12105303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
12106303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
12107f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12108659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1210984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12110eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12111eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Get the frame where the debugging is performed.
12112eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
1211374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator frame_it(isolate, id);
12114eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame = frame_it.frame();
12115eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12116eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Find the requested scope.
12117eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  int n = 0;
12118659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  ScopeIterator it(isolate, frame, inlined_jsframe_index);
12119eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  for (; !it.Done() && n < index; it.Next()) {
12120eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    n++;
12121eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12122eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (it.Done()) {
12123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
12124eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
121251044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  return MaterializeScopeDetails(isolate, &it);
121261044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org}
12127eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12128eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
121291044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
121301044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  HandleScope scope(isolate);
121311044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(args.length() == 1);
12132eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
121331044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Check arguments.
121341044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
121351044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121361044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Count the visible scopes.
121371044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  int n = 0;
121381044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
121391044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    n++;
121401044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
121411044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121421044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  return Smi::FromInt(n);
121431044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org}
121441044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121451044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121461044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) {
121471044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  HandleScope scope(isolate);
121481044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(args.length() == 2);
121491044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121501044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Check arguments.
121511044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
121521044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
121531044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121541044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Find the requested scope.
121551044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  int n = 0;
121561044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ScopeIterator it(isolate, fun);
121571044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  for (; !it.Done() && n < index; it.Next()) {
121581044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    n++;
121591044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
121601044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  if (it.Done()) {
121611044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    return isolate->heap()->undefined_value();
121621044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
121631044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
121641044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  return MaterializeScopeDetails(isolate, &it);
12165eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12166eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12167eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1216849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgstatic bool SetScopeVariableValue(ScopeIterator* it, int index,
1216949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                  Handle<String> variable_name,
1217049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                  Handle<Object> new_value) {
1217149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  for (int n = 0; !it->Done() && n < index; it->Next()) {
1217249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    n++;
1217349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1217449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  if (it->Done()) {
1217549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    return false;
1217649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1217749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return it->SetVariableValue(variable_name, new_value);
1217849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
1217949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1218049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1218149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// Change variable value in closure or local scope
1218249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[0]: number or JsFunction: break id or function
1218349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[1]: number: frame index (when arg[0] is break id)
1218449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[2]: number: inlined frame index (when arg[0] is break id)
1218549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[3]: number: scope index
1218649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[4]: string: variable name
1218749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[5]: object: new value
1218849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org//
1218949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// Return true if success and false otherwise
1219049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) {
1219149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  HandleScope scope(isolate);
1219249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  ASSERT(args.length() == 6);
1219349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1219449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Check arguments.
1219549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
1219649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
1219749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  Handle<Object> new_value = args.at<Object>(5);
1219849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1219949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  bool res;
1220049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  if (args[0]->IsNumber()) {
1220149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    Object* check;
1220249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    { MaybeObject* maybe_check = Runtime_CheckExecutionState(
1220349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        RUNTIME_ARGUMENTS(isolate, args));
1220449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      if (!maybe_check->ToObject(&check)) return maybe_check;
1220549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
1220649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1220749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1220849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1220949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    // Get the frame where the debugging is performed.
1221049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    StackFrame::Id id = UnwrapFrameId(wrapped_id);
1221149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    JavaScriptFrameIterator frame_it(isolate, id);
1221249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    JavaScriptFrame* frame = frame_it.frame();
1221349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1221449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    ScopeIterator it(isolate, frame, inlined_jsframe_index);
1221549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    res = SetScopeVariableValue(&it, index, variable_name, new_value);
1221649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  } else {
1221749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1221849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    ScopeIterator it(isolate, fun);
1221949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    res = SetScopeVariableValue(&it, index, variable_name, new_value);
1222049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1222149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1222249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return isolate->heap()->ToBoolean(res);
1222349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
1222449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1222549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
12226c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
12227ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12228eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(args.length() == 0);
12229eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12230eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG
12231eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Print the scopes for the top frame.
12232c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  StackFrameLocator locator(isolate);
12233eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
1223484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  for (ScopeIterator it(isolate, frame, 0);
1223584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       !it.Done();
1223684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       it.Next()) {
12237eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    it.DebugPrint();
12238eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12239eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
12240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
12241eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12242eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12243eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12244c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
12245ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12246bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(args.length() == 1);
12247bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12248bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Check arguments.
12249303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
12250c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_result = Runtime_CheckExecutionState(
12251c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
12252303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
12253303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
12254bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12255bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Count all archived V8 threads.
12256bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int n = 0;
12257ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  for (ThreadState* thread =
12258ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->thread_manager()->FirstThreadStateInUse();
12259bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org       thread != NULL;
12260bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org       thread = thread->Next()) {
12261bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    n++;
12262bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
12263bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12264bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Total number of threads is current thread and archived threads.
12265bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return Smi::FromInt(n + 1);
12266bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
12267bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12268bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12269bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kThreadDetailsCurrentThreadIndex = 0;
12270bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kThreadDetailsThreadIdIndex = 1;
12271bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kThreadDetailsSize = 2;
12272bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12273bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Return an array with thread details
12274bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// args[0]: number: break id
12275bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// args[1]: number: thread index
12276bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//
12277bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// The array returned contains the following information:
12278bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// 0: Is current thread?
12279bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// 1: Thread id
12280c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
12281ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12282bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(args.length() == 2);
12283bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12284bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Check arguments.
12285303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check;
12286c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
12287c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
12288303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
12289303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
12290bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12291bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12292bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Allocate array for result.
12293ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> details =
12294ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFixedArray(kThreadDetailsSize);
12295bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12296bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Thread index 0 is current thread.
12297bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (index == 0) {
12298bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Fill the details.
12299ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    details->set(kThreadDetailsCurrentThreadIndex,
12300ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                 isolate->heap()->true_value());
12301bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    details->set(kThreadDetailsThreadIdIndex,
12302a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                 Smi::FromInt(ThreadId::Current().ToInteger()));
12303bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else {
12304bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Find the thread with the requested index.
12305bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int n = 1;
12306ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ThreadState* thread =
12307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->thread_manager()->FirstThreadStateInUse();
12308bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    while (index != n && thread != NULL) {
12309bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      thread = thread->Next();
12310bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      n++;
12311bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
12312bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (thread == NULL) {
12313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->heap()->undefined_value();
12314bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
12315bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12316bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Fill the details.
12317ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    details->set(kThreadDetailsCurrentThreadIndex,
12318ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                 isolate->heap()->false_value());
12319a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    details->set(kThreadDetailsThreadIdIndex,
12320a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                 Smi::FromInt(thread->id().ToInteger()));
12321bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
12322bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12323bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Convert to JS array and return.
12324ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(details);
12325bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
12326bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12327bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12328e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org// Sets the disable break state
12329e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org// args[0]: disable break state
12330c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetDisableBreak) {
12331ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12332e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  ASSERT(args.length() == 1);
12333f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
12334ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->set_disable_break(disable_break);
12335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return  isolate->heap()->undefined_value();
12336e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
12337e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
12338e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
1233993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgstatic bool IsPositionAlignmentCodeCorrect(int alignment) {
1234093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
1234193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org}
1234293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1234393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
12344c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
12345ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1234693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  ASSERT(args.length() == 2);
1234743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12348f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1234993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
1235093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1235193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
1235293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    return isolate->ThrowIllegalOperation();
1235393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
1235493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  BreakPositionAlignment alignment =
1235593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      static_cast<BreakPositionAlignment>(statement_aligned_code);
1235693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
123575aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  Handle<SharedFunctionInfo> shared(fun->shared());
1235843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the number of break points
1235993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  Handle<Object> break_locations =
1236093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      Debug::GetSourceBreakLocations(shared, alignment);
12361ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
1236243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return array as JS array
12363ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(
1236443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<FixedArray>::cast(break_locations));
1236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1236643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1236743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
123685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Set a break point in a function.
123695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// args[0]: function
123705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// args[1]: number: break source position (within the function source)
123715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// args[2]: number: break point object
123725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
123735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HandleScope scope(isolate);
123745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  ASSERT(args.length() == 3);
123755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
123765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
123775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  RUNTIME_ASSERT(source_position >= 0);
123785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Handle<Object> break_point_object_arg = args.at<Object>(2);
123795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
123805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Set break point.
123815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  isolate->debug()->SetBreakPoint(function, break_point_object_arg,
123825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                  &source_position);
123835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
123845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return Smi::FromInt(source_position);
123855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
123865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
123875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
123885ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// Changes the state of a break point in a script and returns source position
123895ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// where break point was set. NOTE: Regarding performance see the NOTE for
123905ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// GetScriptFromScriptData.
1239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: script to set break point in
1239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: number: break source position (within the script source)
1239393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org// args[2]: number, breakpoint position alignment
1239493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org// args[3]: number: break point object
12395c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
12396ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1239793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  ASSERT(args.length() == 4);
12398f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
1239943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
1240043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(source_position >= 0);
1240193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
1240293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  Handle<Object> break_point_object_arg = args.at<Object>(3);
1240393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1240493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
1240593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    return isolate->ThrowIllegalOperation();
1240693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
1240793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  BreakPositionAlignment alignment =
1240893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      static_cast<BreakPositionAlignment>(statement_aligned_code);
1240943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1241043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the script from the script wrapper.
1241143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(wrapper->value()->IsScript());
1241243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Script> script(Script::cast(wrapper->value()));
1241343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Set break point.
124155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
1241693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org                                                &source_position,
1241793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org                                                alignment)) {
124185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return  isolate->heap()->undefined_value();
1241943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
124205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
124215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return Smi::FromInt(source_position);
1242243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1242343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1242443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1242543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clear a break point
1242643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: number: break point object
12427c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
12428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1242943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1243043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> break_point_object_arg = args.at<Object>(0);
1243143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1243243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear break point.
12433ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ClearBreakPoint(break_point_object_arg);
1243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1243743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12439c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// Change the state of break on exceptions.
12440c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
12441c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// args[1]: Boolean indicating on/off.
12442c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
12443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1244443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
12445c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  RUNTIME_ASSERT(args[0]->IsNumber());
12446f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
1244743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12448c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // If the number doesn't match an enum value, the ChangeBreakOnException
12449c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // function will default to affecting caught exceptions.
1245043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ExceptionBreakType type =
1245143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
12452c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // Update break point state.
12453ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ChangeBreakOnException(type, enable);
12454ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1245543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1245643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1245743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12458c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// Returns the state of break on exceptions
12459c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// args[0]: boolean indicating uncaught exceptions
12460c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
12461ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12462c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  ASSERT(args.length() == 1);
12463c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  RUNTIME_ASSERT(args[0]->IsNumber());
12464c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
12465c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  ExceptionBreakType type =
12466c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org      static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
12467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool result = isolate->debug()->IsBreakOnException(type);
12468c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  return Smi::FromInt(result);
12469c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org}
12470c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
12471c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
1247243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Prepare for stepping
1247343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: break id for checking execution state
1247443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: step action from the enumeration StepAction
12475a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// args[2]: number of times to perform the step, for step out it is the number
12476a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org//          of frames to step down.
12477c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
12478ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1247943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
1248043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check arguments.
12481303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check;
12482c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
12483c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
12484303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
12485303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1248643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
124874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
1248843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1249043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the step action and check validity.
1249143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
1249243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (step_action != StepIn &&
1249343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepNext &&
1249443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepOut &&
1249543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepInMin &&
1249643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepMin) {
124974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
1249843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1249943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1250043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of steps.
1250143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int step_count = NumberToInt32(args[2]);
1250243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (step_count < 1) {
125034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
1250443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1250543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12506a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Clear all current stepping setup.
12507ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ClearStepping();
12508a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1250943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Prepare step.
12510ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
12511ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                step_count);
12512ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1251343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1251643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clear all stepping set by PrepareStep.
12517c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
12518ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1251931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
12520ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ClearStepping();
12521ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1252243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1252343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1252443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1252543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper function to find or create the arguments object for
1252643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Runtime_DebugEvaluate.
12527ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic Handle<JSObject> MaterializeArgumentsObject(
12528ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Isolate* isolate,
12529ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSObject> target,
12530ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSFunction> function) {
12531ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Do not materialize the arguments object for eval or top-level code.
12532ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Skip if "arguments" is already taken.
12533ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!function->shared()->is_function() ||
12534ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      target->HasLocalProperty(isolate->heap()->arguments_string())) {
12535ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return target;
1253643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1253743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12538ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // FunctionGetArguments can't throw an exception.
12539ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSObject> arguments = Handle<JSObject>::cast(
12540ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Accessors::FunctionGetArguments(function));
12541ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  SetProperty(isolate,
12542ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              target,
12543ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              isolate->factory()->arguments_string(),
12544ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              arguments,
12545ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              ::NONE,
12546ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org              kNonStrictMode);
12547ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return target;
1254843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1254943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1255043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12551c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org// Compile and evaluate source for the given context.
12552c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.orgstatic MaybeObject* DebugEvaluate(Isolate* isolate,
12553c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                                  Handle<Context> context,
12554c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                                  Handle<Object> context_extension,
12555c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                                  Handle<Object> receiver,
12556c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org                                  Handle<String> source) {
12557c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  if (context_extension->IsJSObject()) {
12558c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
12559c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    Handle<JSFunction> closure(context->closure(), isolate);
12560c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    context = isolate->factory()->NewWithContext(closure, context, extension);
12561c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  }
12562c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12563c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
12564c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      source,
12565c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      context,
12566c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      context->IsNativeContext(),
12567c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      CLASSIC_MODE,
12568c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      NO_PARSE_RESTRICTION,
12569c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      RelocInfo::kNoPosition);
12570e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, shared);
12571c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12572c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  Handle<JSFunction> eval_fun =
12573c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      isolate->factory()->NewFunctionFromSharedFunctionInfo(
12574c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org          shared, context, NOT_TENURED);
12575c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  bool pending_exception;
12576c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  Handle<Object> result = Execution::Call(
12577c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org      eval_fun, receiver, 0, NULL, &pending_exception);
12578c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12579c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  if (pending_exception) return Failure::Exception();
12580c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12581c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  // Skip the global proxy as it has no properties and always delegates to the
12582c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  // real global object.
12583c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  if (result->IsJSGlobalProxy()) {
12584c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
12585c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  }
12586c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12587c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  // Clear the oneshot breakpoints so that the debugger does not step further.
12588c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  isolate->debug()->ClearStepping();
12589c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  return *result;
12590c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org}
12591ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
12592ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1259343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Evaluate a piece of JavaScript in the context of a stack frame for
12594ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// debugging.  Things that need special attention are:
12595ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// - Parameters and stack-allocated locals need to be materialized.  Altered
12596ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org//   values need to be written back to the stack afterwards.
12597ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// - The arguments object needs to materialized.
12598c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
12599ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1260043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1260143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the execution state and decode arguments frame and source to be
1260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // evaluated.
1260384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ASSERT(args.length() == 6);
12604303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check_result;
12605c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  { MaybeObject* maybe_result = Runtime_CheckExecutionState(
12606c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
12607c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    if (!maybe_result->ToObject(&check_result)) return maybe_result;
12608303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
12609f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12610659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12611f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
12612f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
12613c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  Handle<Object> context_extension(args[5], isolate);
12614bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
12615bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  // Handle the processing of break.
12616bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  DisableBreak disable_break_save(disable_break);
1261743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1261843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the frame where the debugging is performed.
1261943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  StackFrame::Id id = UnwrapFrameId(wrapped_id);
1262074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate, id);
1262143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JavaScriptFrame* frame = it.frame();
12622659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
12623659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
1262443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1262543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the saved contexts chain to find the active context for the
1262643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // selected frame.
12627c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SaveContext* save = FindSavedContextForFrame(isolate, frame);
12628c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
12629ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SaveContext savex(isolate);
12630ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->set_context(*(save->context()));
1263143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12632ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Evaluate on the context of the frame.
12633ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Context> context(Context::cast(frame->context()));
12634ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(!context.is_null());
1263543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12636ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Materialize stack locals and the arguments object.
12637ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSObject> materialized =
12638ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
1263943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12640ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  materialized = MaterializeStackLocalsWithFrameInspector(
12641ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate, materialized, function, &frame_inspector);
12642ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, materialized);
12643ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
12644ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  materialized = MaterializeArgumentsObject(isolate, materialized, function);
12645ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, materialized);
12646ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
12647ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Add the materialized object in a with-scope to shadow the stack locals.
12648ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  context = isolate->factory()->NewWithContext(function, context, materialized);
1264943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12650ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> receiver(frame->receiver(), isolate);
126511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* evaluate_result_object;
126521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  { MaybeObject* maybe_result =
126531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    DebugEvaluate(isolate, context, context_extension, receiver, source);
126541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result;
126551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
126561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12657ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Object> result(evaluate_result_object, isolate);
126581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12659ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Write back potential changes to materialized stack locals to the stack.
12660ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  UpdateStackLocalsFromMaterializedObject(
12661ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate, materialized, function, frame, inlined_jsframe_index);
126621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12663ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
1266443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1266543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1266643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12667c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
12668ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1266943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1267043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the execution state and decode arguments frame and source to be
1267143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // evaluated.
126725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(args.length() == 4);
12673303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* check_result;
12674c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  { MaybeObject* maybe_result = Runtime_CheckExecutionState(
12675c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
12676c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    if (!maybe_result->ToObject(&check_result)) return maybe_result;
12677303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
12678f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
12679f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
12680c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  Handle<Object> context_extension(args[3], isolate);
12681bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
12682bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  // Handle the processing of break.
12683bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  DisableBreak disable_break_save(disable_break);
1268443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1268543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Enter the top context from before the debugger was invoked.
12686ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SaveContext save(isolate);
1268743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  SaveContext* top = &save;
12688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
1268943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    top = top->prev();
1269043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1269143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (top != NULL) {
12692ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->set_context(*top->context());
1269343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1269443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1269546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Get the native context now set to the top context from before the
1269643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // debugger was invoked.
1269746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> context = isolate->native_context();
1269846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Object> receiver = isolate->global_object();
12699c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  return DebugEvaluate(isolate, context, context_extension, receiver, source);
1270043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1270143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1270243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12703c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
12704ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1270531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
1270643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1270743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the script objects.
12708ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
1270943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1271043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert the script objects to proper JS objects.
1271171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  for (int i = 0; i < instances->length(); i++) {
127127c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
127137c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // Get the script wrapper in a local handle before calling GetScriptWrapper,
127147c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // because using
127157c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    //   instances->set(i, *GetScriptWrapper(script))
127167c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
127172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // already have dereferenced the instances handle.
127187c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    Handle<JSValue> wrapper = GetScriptWrapper(script);
127197c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    instances->set(i, *wrapper);
1272043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1272143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1272243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return result as a JS array.
12723ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSObject> result =
12724ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewJSObject(isolate->array_function());
12725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances);
1272643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
1272743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1272843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper function used by Runtime_DebugReferencedBy below.
12731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int DebugReferencedBy(HeapIterator* iterator,
12732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             JSObject* target,
1273343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             Object* instance_filter, int max_references,
1273443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             FixedArray* instances, int instances_size,
1273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             JSFunction* arguments_function) {
127368432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Isolate* isolate = target->GetIsolate();
1273779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1273879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1273943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1274043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate the heap.
1274143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
1274243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSObject* last = NULL;
12743b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  HeapObject* heap_obj = NULL;
12744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (((heap_obj = iterator->next()) != NULL) &&
1274543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         (max_references == 0 || count < max_references)) {
1274643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Only look at all JSObjects.
1274743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (heap_obj->IsJSObject()) {
1274843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Skip context extension objects and argument arrays as these are
1274943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // checked in the context of functions using them.
1275043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      JSObject* obj = JSObject::cast(heap_obj);
12751245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      if (obj->IsJSContextExtensionObject() ||
1275243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          obj->map()->constructor() == arguments_function) {
1275343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        continue;
1275443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1275543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1275643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Check if the JS object has a reference to the object looked for.
1275743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (obj->ReferencesObject(target)) {
1275843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Check instance filter if supplied. This is normally used to avoid
1275943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // references from mirror objects (see Runtime_IsInPrototypeChain).
1276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (!instance_filter->IsUndefined()) {
1276143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          Object* V = obj;
1276243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          while (true) {
127638432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            Object* prototype = V->GetPrototype(isolate);
1276443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (prototype->IsNull()) {
1276543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              break;
1276643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            }
1276743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (instance_filter == prototype) {
1276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              obj = NULL;  // Don't add this object.
1276943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              break;
1277043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            }
1277143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            V = prototype;
1277243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
1277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (obj != NULL) {
1277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          // Valid reference found add to instance array if supplied an update
1277743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          // count.
1277843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          if (instances != NULL && count < instances_size) {
1277943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            instances->set(count, obj);
1278043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
1278143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          last = obj;
1278243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          count++;
1278343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1278443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1278543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1278643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1278743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1278843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check for circular reference only. This can happen when the object is only
1278943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // referenced from mirrors and has a circular reference in which case the
1279043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // object is not really alive and would have been garbage collected if not
1279143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // referenced from the mirror.
1279243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (count == 1 && last == target) {
1279343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    count = 0;
1279443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1279543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1279643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the number of referencing objects found.
1279743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return count;
1279843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1279943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1280043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1280143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Scan the heap for objects with direct references to an object
1280243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: the object to find references to
1280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: constructor function for instances to exclude (Mirror)
1280443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[2]: the the maximum number of objects to return
12805c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
1280679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1280743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
1280843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1280943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First perform a full GC in order to avoid references from dead objects.
12810994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
12811994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                     "%DebugReferencedBy");
12812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The heap iterator reserves the right to do a GC to make the heap iterable.
12813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Due to the GC above we know it won't need to do that, but it seems cleaner
12814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // to get the heap iterator constructed before we start having unprotected
12815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Object* locals that are not protected by handles.
1281643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1281743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check parameters.
12818f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, target, 0);
1281943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* instance_filter = args[1];
1282043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(instance_filter->IsUndefined() ||
1282143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                 instance_filter->IsJSObject());
1282243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
1282343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(max_references >= 0);
1282443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12825c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the constructor function for context extension and arguments array.
1282743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSObject* arguments_boilerplate =
1282846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->context()->native_context()->arguments_boilerplate();
1282943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSFunction* arguments_function =
1283043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      JSFunction::cast(arguments_boilerplate->map()->constructor());
1283143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1283243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of referencing objects.
1283343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count;
128347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = isolate->heap();
128357c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HeapIterator heap_iterator(heap);
12836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  count = DebugReferencedBy(&heap_iterator,
12837c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            target, instance_filter, max_references,
12838245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                            NULL, 0, arguments_function);
1283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate an array to hold the result.
12841303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* object;
128427c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
12843303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_object->ToObject(&object)) return maybe_object;
12844303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1284543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* instances = FixedArray::cast(object);
1284643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1284743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the referencing objects.
12848c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // AllocateFixedArray above does not make the heap non-iterable.
128497c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  ASSERT(heap->IsHeapIterable());
128507c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HeapIterator heap_iterator2(heap);
12851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  count = DebugReferencedBy(&heap_iterator2,
12852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            target, instance_filter, max_references,
12853245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                            instances, count, arguments_function);
1285443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return result as JS array.
12856303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
128577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  MaybeObject* maybe_result = heap->AllocateJSObject(
1285846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->context()->native_context()->array_function());
12859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!maybe_result->ToObject(&result)) return maybe_result;
12860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return JSArray::cast(result)->SetContent(instances);
1286143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1286243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1286343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1286443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper function used by Runtime_DebugConstructedBy below.
12865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int DebugConstructedBy(HeapIterator* iterator,
12866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              JSFunction* constructor,
12867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              int max_references,
12868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              FixedArray* instances,
12869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              int instances_size) {
1287079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1287143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1287243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate the heap.
1287343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
12874b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  HeapObject* heap_obj = NULL;
12875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (((heap_obj = iterator->next()) != NULL) &&
1287643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         (max_references == 0 || count < max_references)) {
1287743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Only look at all JSObjects.
1287843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (heap_obj->IsJSObject()) {
1287943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      JSObject* obj = JSObject::cast(heap_obj);
1288043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (obj->map()->constructor() == constructor) {
1288143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Valid reference found add to instance array if supplied an update
1288243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // count.
1288343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (instances != NULL && count < instances_size) {
1288443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          instances->set(count, obj);
1288543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1288643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        count++;
1288743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1288843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1288943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1289043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1289143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the number of referencing objects found.
1289243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return count;
1289343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1289443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1289543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1289643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Scan the heap for objects constructed by a specific function.
1289743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: the constructor to find instances of
1289843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: the the maximum number of objects to return
12899c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
1290079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1290143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1290243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1290343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First perform a full GC in order to avoid dead objects.
129047c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = isolate->heap();
129057c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
1290643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check parameters.
12908f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
1290943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
1291043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(max_references >= 0);
1291143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of referencing objects.
1291343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count;
129147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HeapIterator heap_iterator(heap);
12915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  count = DebugConstructedBy(&heap_iterator,
12916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             constructor,
12917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             max_references,
12918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             NULL,
12919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             0);
1292043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1292143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate an array to hold the result.
12922303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* object;
129237c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
12924303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_object->ToObject(&object)) return maybe_object;
12925303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
1292643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* instances = FixedArray::cast(object);
1292743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(HEAP->IsHeapIterable());
1292943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the referencing objects.
129307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HeapIterator heap_iterator2(heap);
12931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  count = DebugConstructedBy(&heap_iterator2,
12932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             constructor,
12933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             max_references,
12934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             instances,
12935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             count);
1293643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1293743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return result as JS array.
12938303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  Object* result;
12939ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject(
129407c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      isolate->context()->native_context()->array_function());
12941303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    if (!maybe_result->ToObject(&result)) return maybe_result;
12942303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
12943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return JSArray::cast(result)->SetContent(instances);
1294443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1294543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1294643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12947ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Find the effective prototype object as returned by __proto__.
12948ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// args[0]: the object to find the prototype for.
12949c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
1295079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1295143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
12952f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj, 0);
12953e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return GetPrototypeSkipHiddenPrototypes(isolate, obj);
1295443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1295543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1295643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129572c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org// Patches script source (should be called upon BeforeCompile event).
129582c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
129592c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  HandleScope scope(isolate);
129602c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  ASSERT(args.length() == 2);
129612c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
129622c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
1296346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
129642c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
129652c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  RUNTIME_ASSERT(script_wrapper->value()->IsScript());
129662c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Handle<Script> script(Script::cast(script_wrapper->value()));
129672c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
12968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  int compilation_state = script->compilation_state();
129692c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
129702c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  script->set_source(*source);
129712c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
129722c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  return isolate->heap()->undefined_value();
129732c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
129742c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
129752c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
12976c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
1297779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1297831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
1297943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CPU::DebugBreak();
12980ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1298143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1298243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1298343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12984c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
12985ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
129866e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org#ifdef DEBUG
1298765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  ASSERT(args.length() == 1);
1298865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Get the function and make sure it is compiled.
12989f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
129905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
1299165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    return Failure::Exception();
1299265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
1299365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  func->code()->PrintLn();
1299418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif  // DEBUG
12995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1299618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
1299718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
1299818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
12999c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
13000ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
130016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org#ifdef DEBUG
1300218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  ASSERT(args.length() == 1);
1300318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Get the function and make sure it is compiled.
13004f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
130055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) {
1300618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    return Failure::Exception();
1300718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
13008400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  func->shared()->construct_stub()->PrintLn();
1300965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif  // DEBUG
13010ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1301165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
130129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
130139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13014c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
1301579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
130169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  ASSERT(args.length() == 1);
130179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13018f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
130199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  return f->shared()->inferred_name();
130209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}
13021ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
13022ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int FindSharedFunctionInfosForScript(HeapIterator* iterator,
13024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                            Script* script,
13025ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            FixedArray* buffer) {
1302679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
13027ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int counter = 0;
13028ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int buffer_size = buffer->length();
13029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* obj = iterator->next();
13030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       obj != NULL;
13031c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       obj = iterator->next()) {
13032ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(obj != NULL);
13033ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (!obj->IsSharedFunctionInfo()) {
13034ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      continue;
13035ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
13036ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
13037ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (shared->script() != script) {
13038ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      continue;
13039ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
13040ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (counter < buffer_size) {
13041ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      buffer->set(counter, shared);
13042ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
13043ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    counter++;
13044ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
13045ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return counter;
13046ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13047ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13048e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13049ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For a script finds all SharedFunctionInfo's in the heap that points
13050ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// to this script. Returns JSArray of SharedFunctionInfo wrapped
13051ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// in OpaqueReferences.
13052c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*,
13053c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                 Runtime_LiveEditFindSharedFunctionInfosForScript) {
130546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13055de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13056ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 1);
13057f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSValue, script_value, 0);
13058ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13059de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  RUNTIME_ASSERT(script_value->value()->IsScript());
13060ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
13061ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13062ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  const int kBufferSize = 32;
13063ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13064ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<FixedArray> array;
13065ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  array = isolate->factory()->NewFixedArray(kBufferSize);
13066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int number;
130677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = isolate->heap();
13068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
130697c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    heap->EnsureHeapIsIterable();
1307079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_allocation;
130717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    HeapIterator heap_iterator(heap);
13072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Script* scr = *script;
13073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FixedArray* arr = *array;
13074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
13076ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (number > kBufferSize) {
13077ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    array = isolate->factory()->NewFixedArray(number);
130787c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    heap->EnsureHeapIsIterable();
1307979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_allocation;
130807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    HeapIterator heap_iterator(heap);
13081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Script* scr = *script;
13082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FixedArray* arr = *array;
13083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13084ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
13085ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13086ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
13087ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  result->set_length(Smi::FromInt(number));
13088ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13089ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  LiveEdit::WrapSharedFunctionInfos(result);
13090ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13091ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return *result;
13092ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13093ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13094e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13095ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For a script calculates compilation information about all its functions.
13096ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// The script source is explicitly specified by the second argument.
13097ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// The source of the actual script is not used, however it is important that
13098ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// all generated code keeps references to this particular instance of script.
13099ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Returns a JSArray of compilation infos. The array is ordered so that
13100ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// each function with all its descendant is always stored in a continues range
13101ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// with the function itself going first. The root function is a script function.
13102c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
131036e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13104de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13105ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13106f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSValue, script, 0);
13107f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13108de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
13109de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  RUNTIME_ASSERT(script->value()->IsScript());
13110ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
13111ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13112ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  JSArray* result =  LiveEdit::GatherCompileInfo(script_handle, source);
13113ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (isolate->has_pending_exception()) {
13115ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return Failure::Exception();
13116ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
13117ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13118ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return result;
13119ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13120ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13121e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
131224111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// Changes the source of the script to a new_source.
131234111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// If old_script_name is provided (i.e. is a String), also creates a copy of
131244111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// the script with its original source and sends notification to debugger.
13125c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
131266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13127de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13128ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 3);
13129f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
13130f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
13131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> old_script_name(args[2], isolate);
13132ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13133f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(original_script_value->value()->IsScript());
13134f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<Script> original_script(Script::cast(original_script_value->value()));
13135ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
131364111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  Object* old_script = LiveEdit::ChangeScriptSource(original_script,
131374111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org                                                    new_source,
131384111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org                                                    old_script_name);
13139ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
131404111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (old_script->IsScript()) {
131414111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Handle<Script> script_handle(Script::cast(old_script));
131424111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    return *(GetScriptWrapper(script_handle));
131434111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  } else {
13144ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->null_value();
131454111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
13146ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13147ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13149c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
131506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13151de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
13153f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
13154a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return LiveEdit::FunctionSourceUpdated(shared_info);
13155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
13156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13158ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Replaces code of SharedFunctionInfo with a new one.
13159c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
131606e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13161de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13162ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13163f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
13164f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
13165ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13166ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
13167ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13168ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13169e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13170ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Connects SharedFunctionInfo to another script.
13171c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
131726e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13173de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13174ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> function_object(args[0], isolate);
13176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> script_object(args[1], isolate);
131774111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
131784111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (function_object->IsJSValue()) {
131794111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
131804111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    if (script_object->IsJSValue()) {
13181f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
13182f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Script* script = Script::cast(JSValue::cast(*script_object)->value());
13183ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      script_object = Handle<Object>(script, isolate);
131844111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    }
131854111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
131864111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    LiveEdit::SetFunctionScript(function_wrapper, script_object);
131874111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  } else {
131884111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    // Just ignore this. We may not have a SharedFunctionInfo for some functions
131894111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    // and we check it in this function.
131904111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
131914111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
13192ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
131934111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
13194ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
131954111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
131964111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// In a code of a parent function replaces original function as embedded object
131974111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// with a substitution one.
13198c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
131996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13200de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
132014111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  ASSERT(args.length() == 3);
132024111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
13203f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
13204f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
13205f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
132064111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
132074111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
132084111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org                                       subst_wrapper);
13209ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13210ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
13211ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13212ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
132134111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
13214ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Updates positions of a shared function info (first parameter) according
13215ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// to script source change. Text change is described in second parameter as
13216ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// array of groups of 3 numbers:
13217ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// (change_begin, change_end, change_end_new_position).
13218ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Each group describes a change in text; groups are sorted by change_begin.
13219c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
132206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13221de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13222ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13223f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13224f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
13225ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13226ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
13227ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13228ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13229ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13230ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For array of SharedFunctionInfo's (each wrapped in JSValue)
13231ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// checks that none of them have activations on stacks (of any thread).
13232ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Returns array of the same length with corresponding results of
13233ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// LiveEdit::FunctionPatchabilityStatus type.
13234c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
132356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13236de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13237357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  ASSERT(args.length() == 2);
13238f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13239f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
13240ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
132411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
13242ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13243ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13244e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Compares 2 strings line-by-line, then token-wise and returns diff in form
13246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
13247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// of diff chunks.
13248c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
132496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13250de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13251c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  ASSERT(args.length() == 2);
13252f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
13253f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
13254c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
13255c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  return *LiveEdit::CompareStrings(s1, s2);
13256c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
13257c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
13258c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
132595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Restarts a call frame and completely drops all frames above.
132605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Returns true if successful. Otherwise returns undefined or an error message.
132615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditRestartFrame) {
132625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HandleScope scope(isolate);
132636e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
132645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  ASSERT(args.length() == 2);
132655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
132665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Check arguments.
132675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Object* check;
132685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  { MaybeObject* maybe_check = Runtime_CheckExecutionState(
132695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      RUNTIME_ARGUMENTS(isolate, args));
132705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (!maybe_check->ToObject(&check)) return maybe_check;
132715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
132725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
132735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Heap* heap = isolate->heap();
132745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
132755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Find the relevant frame with the requested index.
132765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  StackFrame::Id id = isolate->debug()->break_frame_id();
132775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (id == StackFrame::NO_ID) {
132785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // If there are no JavaScript stack frames return undefined.
132795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return heap->undefined_value();
132805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
132815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
132825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int count = 0;
132835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  JavaScriptFrameIterator it(isolate, id);
132845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  for (; !it.done(); it.Advance()) {
132855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (index < count + it.frame()->GetInlineCount()) break;
132865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    count += it.frame()->GetInlineCount();
132875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
132885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (it.done()) return heap->undefined_value();
132895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
132901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  const char* error_message = LiveEdit::RestartFrame(it.frame());
132915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (error_message) {
132924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return *(isolate->factory()->InternalizeUtf8String(error_message));
132935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
132945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return heap->true_value();
132955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
132965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
132975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
13298086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org// A testing entry. Returns statement position which is the closest to
13299086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org// source_position.
13300c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
133016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13302de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CHECK(isolate->debugger()->live_edit_enabled());
13303086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  ASSERT(args.length() == 2);
13304f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13305086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
13306086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Code> code(function->code(), isolate);
13308086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (code->kind() != Code::FUNCTION &&
13310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      code->kind() != Code::OPTIMIZED_FUNCTION) {
13311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
13312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
13313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
13315086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int closest_pc = 0;
13316086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int distance = kMaxInt;
13317086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  while (!it.done()) {
13318086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    int statement_position = static_cast<int>(it.rinfo()->data());
13319086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    // Check if this break point is closer that what was previously found.
13320086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    if (source_position <= statement_position &&
13321086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org        statement_position - source_position < distance) {
13322b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org      closest_pc =
13323b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org          static_cast<int>(it.rinfo()->pc() - code->instruction_start());
13324086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      distance = statement_position - source_position;
13325086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      // Check whether we can't get any closer.
13326086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      if (distance == 0) break;
13327086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    }
13328086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    it.next();
13329086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
13330086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13331086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  return Smi::FromInt(closest_pc);
13332086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
13333086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13334086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13335357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// Calls specified function with or without entering the debugger.
13336357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// This is used in unit tests to run code as if debugger is entered or simply
13337357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// to have a stack with C++ frame in the middle.
13338c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
13339ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
133406e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 2);
13341f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13342f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
13343357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
13344357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  Handle<Object> result;
13345357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  bool pending_exception;
13346357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  {
13347357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    if (without_debugger) {
1334846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      result = Execution::Call(function, isolate->global_object(), 0, NULL,
13349357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org                               &pending_exception);
13350357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    } else {
13351357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org      EnterDebugger enter_debugger;
1335246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      result = Execution::Call(function, isolate->global_object(), 0, NULL,
13353357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org                               &pending_exception);
13354357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    }
13355357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  }
13356357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  if (!pending_exception) {
13357357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    return *result;
13358357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  } else {
13359357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org    return Failure::Exception();
13360357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  }
13361357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
13362357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
13363357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
13364d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Sets a v8 flag.
13365c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
1336679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
13367f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, arg, 0);
1336883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  SmartArrayPointer<char> flags =
13369d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
13370d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  FlagList::SetFlagsFromString(*flags, StrLength(*flags));
13371ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
13372d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
13373d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13374d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13375d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Performs a GC.
13376d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Presently, it only does a full GC.
13377c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CollectGarbage) {
1337879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
13379bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
13380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
13381d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
13382d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13383d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13384d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Gets the current heap usage.
13385c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
1338679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
13387ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
13388d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  if (!Smi::IsValid(usage)) {
13389ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return *isolate->factory()->NewNumberFromInt(usage);
13390d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
13391d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  return Smi::FromInt(usage);
13392d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
133939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
1339465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif  // ENABLE_DEBUGGER_SUPPORT
1339565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
13396ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
13397594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#ifdef V8_I18N_SUPPORT
13398594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
13399594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13400594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13401594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
13402594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
13403594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13404594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
13405594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13406594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Return value which denotes invalid language tag.
13407594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const char* const kInvalidTag = "invalid-tag";
13408594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13409594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode error = U_ZERO_ERROR;
13410594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char icu_result[ULOC_FULLNAME_CAPACITY];
13411594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int icu_length = 0;
13412594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13413594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
13414594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                      &icu_length, &error);
13415594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(error) || icu_length == 0) {
13416594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
13417594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13418594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13419594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char result[ULOC_FULLNAME_CAPACITY];
13420594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13421594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Force strict BCP47 rules.
13422594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
13423594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13424594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(error)) {
13425594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
13426594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13427594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13428594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
13429594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13430594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13431594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13432594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
13433594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13435594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
13436594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
13437594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13438594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const icu::Locale* available_locales = NULL;
13439594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int32_t count = 0;
13440594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13441594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (service->IsUtf8EqualTo(CStrVector("collator"))) {
13442594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::Collator::getAvailableLocales(count);
13443594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
13444594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::NumberFormat::getAvailableLocales(count);
13445594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
13446594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::DateFormat::getAvailableLocales(count);
13447594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
13448594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::BreakIterator::getAvailableLocales(count);
13449594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13450594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13451594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode error = U_ZERO_ERROR;
13452594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char result[ULOC_FULLNAME_CAPACITY];
13453594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> locales =
13454594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
13455594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13456594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (int32_t i = 0; i < count; ++i) {
13457594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    const char* icu_name = available_locales[i].getName();
13458594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13459594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    error = U_ZERO_ERROR;
13460594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // No need to force strict BCP47 rules.
13461594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13462594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (U_FAILURE(error)) {
13463594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // This shouldn't happen, but lets not break the user.
13464594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      continue;
13465594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13466594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13467594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate,
13468594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        JSObject::SetLocalPropertyIgnoreAttributes(
13469594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            locales,
13470594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            isolate->factory()->NewStringFromAscii(CStrVector(result)),
13471594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            isolate->factory()->NewNumber(i),
13472594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE));
13473594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13474594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13475594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *locales;
13476594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13477594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13478594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13479594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) {
13480594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  SealHandleScope shs(isolate);
13481594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13482594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 0);
13483594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13484594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Locale default_locale;
13485594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13486594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set the locale
13487594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char result[ULOC_FULLNAME_CAPACITY];
13488594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
13489594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uloc_toLanguageTag(
13490594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
13491594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_SUCCESS(status)) {
13492594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
13493594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13494594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13495594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return isolate->heap()->AllocateStringFromOneByte(CStrVector("und"));
13496594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13497594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13498594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13499594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
13500594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13501594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13502594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
13503594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13504594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
13505594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13506594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uint32_t length = static_cast<uint32_t>(input->length()->Number());
13507594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<FixedArray> output = isolate->factory()->NewFixedArray(length);
13508594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<Name> maximized =
13509594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate->factory()->NewStringFromAscii(CStrVector("maximized"));
13510594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<Name> base =
13511594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate->factory()->NewStringFromAscii(CStrVector("base"));
13512594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (unsigned int i = 0; i < length; ++i) {
13513594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    MaybeObject* maybe_string = input->GetElement(i);
13514594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Object* locale_id;
13515594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) {
13516594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return isolate->Throw(isolate->heap()->illegal_argument_string());
13517594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13518594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13519594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    v8::String::Utf8Value utf8_locale_id(
13520594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        v8::Utils::ToLocal(Handle<String>(String::cast(locale_id))));
13521594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13522594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    UErrorCode error = U_ZERO_ERROR;
13523594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13524594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Convert from BCP47 to ICU format.
13525594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de-DE-u-co-phonebk -> de_DE@collation=phonebook
13526594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_locale[ULOC_FULLNAME_CAPACITY];
13527594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int icu_locale_length = 0;
13528594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
13529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        &icu_locale_length, &error);
13530594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (U_FAILURE(error) || icu_locale_length == 0) {
13531594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return isolate->Throw(isolate->heap()->illegal_argument_string());
13532594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13533594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13534594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Maximize the locale.
13535594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
13536594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_max_locale[ULOC_FULLNAME_CAPACITY];
13537594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_addLikelySubtags(
13538594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13539594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13540594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Remove extensions from maximized locale.
13541594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_Latn_DE@collation=phonebook -> de_Latn_DE
13542594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
13543594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_getBaseName(
13544594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13545594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13546594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Get original name without extensions.
13547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_DE@collation=phonebook -> de_DE
13548594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_base_locale[ULOC_FULLNAME_CAPACITY];
13549594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_getBaseName(
13550594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
13551594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13552594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Convert from ICU locale format to BCP47 format.
13553594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_Latn_DE -> de-Latn-DE
13554594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char base_max_locale[ULOC_FULLNAME_CAPACITY];
13555594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
13556594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       ULOC_FULLNAME_CAPACITY, FALSE, &error);
13557594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13558594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_DE -> de-DE
13559594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char base_locale[ULOC_FULLNAME_CAPACITY];
13560594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_toLanguageTag(
13561594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13562594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13563594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (U_FAILURE(error)) {
13564594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return isolate->Throw(isolate->heap()->illegal_argument_string());
13565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13566594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13567594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<JSObject> result =
13568594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        isolate->factory()->NewJSObject(isolate->object_function());
13569594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate,
13570594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        JSObject::SetLocalPropertyIgnoreAttributes(
13571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            result,
13572594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            maximized,
13573594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)),
13574594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE));
13575594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    RETURN_IF_EMPTY_HANDLE(isolate,
13576594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        JSObject::SetLocalPropertyIgnoreAttributes(
13577594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            result,
13578594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            base,
13579594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            isolate->factory()->NewStringFromAscii(CStrVector(base_locale)),
13580594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE));
13581594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    output->set(i, *result);
13582594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13583594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13584594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output);
13585594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  result->set_length(Smi::FromInt(length));
13586594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *result;
13587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13589594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13590594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
13591594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13592594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13593594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
13594594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13595594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
13596594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
13597594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
13598594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13599594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<ObjectTemplateInfo> date_format_template =
13600594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      I18N::GetTemplate(isolate);
13601594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13602594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Create an empty object wrapper.
13603594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool has_pending_exception = false;
13604594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> local_object = Execution::InstantiateObject(
13605594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      date_format_template, &has_pending_exception);
13606594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (has_pending_exception) {
13607594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(isolate->has_pending_exception());
13608594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Failure::Exception();
13609594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13610594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13611594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set date time formatter as internal field of the resulting JS object.
13612594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
13613594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate, locale, options, resolved);
13614594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13615594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!date_format) return isolate->ThrowIllegalOperation();
13616594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13617594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
13618594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13619594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate,
13620594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      JSObject::SetLocalPropertyIgnoreAttributes(
13621594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          local_object,
13622594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")),
13623594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector("valid")),
13624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          NONE));
13625594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13626594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
13627594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                 v8::Utils::ToLocal(local_object));
13628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Make object handle weak so we can delete the data format once GC kicks in.
13629594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  wrapper.MakeWeak<void>(NULL, &DateFormat::DeleteDateFormat);
13630594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  wrapper.ClearAndLeak();
13631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *local_object;
13632594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13633594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13634594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13635594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
13636594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13637594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13638594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
13639594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
13641594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
13642594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13643594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool has_pending_exception = false;
1364421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  Handle<Object> value = Execution::ToNumber(date, &has_pending_exception);
13645594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (has_pending_exception) {
13646594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(isolate->has_pending_exception());
13647594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Failure::Exception();
13648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13649594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13650594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::SimpleDateFormat* date_format =
13651594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      DateFormat::UnpackDateFormat(isolate, date_format_holder);
13652594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!date_format) return isolate->ThrowIllegalOperation();
13653594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13654594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString result;
1365521af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  date_format->format(value->Number(), result);
13656594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13657594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *isolate->factory()->NewStringFromTwoByte(
13658594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Vector<const uint16_t>(
13659594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          reinterpret_cast<const uint16_t*>(result.getBuffer()),
13660594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          result.length()));
13661594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13662594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13663594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13664594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) {
13665594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13666594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13667594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
13668594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13669594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
13670594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
13671594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13672594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
13673594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
13674594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::SimpleDateFormat* date_format =
13675594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      DateFormat::UnpackDateFormat(isolate, date_format_holder);
13676594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!date_format) return isolate->ThrowIllegalOperation();
13677594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13678594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
13679594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UDate date = date_format->parse(u_date, status);
13680594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
13681594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13682594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool has_pending_exception = false;
13683594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSDate> result = Handle<JSDate>::cast(
13684594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Execution::NewDate(static_cast<double>(date), &has_pending_exception));
13685594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (has_pending_exception) {
13686594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(isolate->has_pending_exception());
13687594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Failure::Exception();
13688594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13689594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *result;
13690594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13691594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13692594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13693594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
13694594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13695594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13696594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
13697594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
13699594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
13700594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
13701594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13702594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<ObjectTemplateInfo> number_format_template =
13703594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      I18N::GetTemplate(isolate);
13704594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13705594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Create an empty object wrapper.
13706594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool has_pending_exception = false;
13707594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> local_object = Execution::InstantiateObject(
13708594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      number_format_template, &has_pending_exception);
13709594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (has_pending_exception) {
13710594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(isolate->has_pending_exception());
13711594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Failure::Exception();
13712594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13713594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13714594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set number formatter as internal field of the resulting JS object.
13715594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
13716594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate, locale, options, resolved);
13717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13718594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!number_format) return isolate->ThrowIllegalOperation();
13719594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13720594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
13721594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13722594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate,
13723594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      JSObject::SetLocalPropertyIgnoreAttributes(
13724594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          local_object,
13725594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector("numberFormat")),
13726594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector("valid")),
13727594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          NONE));
13728594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13729594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
13730594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                 v8::Utils::ToLocal(local_object));
13731594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Make object handle weak so we can delete the number format once GC kicks
13732594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // in.
13733594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  wrapper.MakeWeak<void>(NULL, &NumberFormat::DeleteNumberFormat);
13734594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  wrapper.ClearAndLeak();
13735594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *local_object;
13736594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13737594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13738594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13739594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
13740594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13741594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13742594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
13743594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13744594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
13745594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
13746594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13747594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool has_pending_exception = false;
1374821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  Handle<Object> value = Execution::ToNumber(number, &has_pending_exception);
13749594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (has_pending_exception) {
13750594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(isolate->has_pending_exception());
13751594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Failure::Exception();
13752594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13753594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13754594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::DecimalFormat* number_format =
13755594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
13756594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!number_format) return isolate->ThrowIllegalOperation();
13757594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13758594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString result;
1375921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  number_format->format(value->Number(), result);
13760594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13761594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *isolate->factory()->NewStringFromTwoByte(
13762594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Vector<const uint16_t>(
13763594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          reinterpret_cast<const uint16_t*>(result.getBuffer()),
13764594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          result.length()));
13765594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13766594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13767594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13768594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) {
13769594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13770594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13771594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
13772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
13774594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
13775594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13776594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
13777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
13778594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::DecimalFormat* number_format =
13779594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
13780594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!number_format) return isolate->ThrowIllegalOperation();
13781594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13782594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
13783594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Formattable result;
13784594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
13785594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // to be part of Chrome.
13786594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // TODO(cira): Include currency parsing code using parseCurrency call.
13787594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // We need to check if the formatter parses all currencies or only the
13788594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // one it was constructed with (it will impact the API - how to return ISO
13789594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // code and the value).
13790594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  number_format->parse(u_number, result, status);
13791594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
13792594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13793594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  switch (result.getType()) {
13794594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  case icu::Formattable::kDouble:
13795594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return *isolate->factory()->NewNumber(result.getDouble());
13796594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  case icu::Formattable::kLong:
13797594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return *isolate->factory()->NewNumberFromInt(result.getLong());
13798594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  case icu::Formattable::kInt64:
13799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return *isolate->factory()->NewNumber(
13800594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        static_cast<double>(result.getInt64()));
13801594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  default:
13802594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->undefined_value();
13803594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13805594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13806594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13807594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
13808594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13809594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13810594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
13811594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13812594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
13813594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
13814594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
13815594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13816594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
13817594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13818594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Create an empty object wrapper.
13819594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool has_pending_exception = false;
13820594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> local_object = Execution::InstantiateObject(
13821594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      collator_template, &has_pending_exception);
13822594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (has_pending_exception) {
13823594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(isolate->has_pending_exception());
13824594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Failure::Exception();
13825594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13826594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13827594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set collator as internal field of the resulting JS object.
13828594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Collator* collator = Collator::InitializeCollator(
13829594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate, locale, options, resolved);
13830594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13831594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!collator) return isolate->ThrowIllegalOperation();
13832594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13833594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
13834594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13835594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate,
13836594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      JSObject::SetLocalPropertyIgnoreAttributes(
13837594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          local_object,
13838594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector("collator")),
13839594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          isolate->factory()->NewStringFromAscii(CStrVector("valid")),
13840594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          NONE));
13841594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13842594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
13843594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                 v8::Utils::ToLocal(local_object));
13844594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Make object handle weak so we can delete the collator once GC kicks in.
13845594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  wrapper.MakeWeak<void>(NULL, &Collator::DeleteCollator);
13846594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  wrapper.ClearAndLeak();
13847594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *local_object;
13848594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13849594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13850594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13851594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InternalCompare) {
13852594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
13853594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13854594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
13855594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13856594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
13857594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
13858594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
13859594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13860594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
13861594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!collator) return isolate->ThrowIllegalOperation();
13862594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13863594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Value string_value1(v8::Utils::ToLocal(string1));
13864594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Value string_value2(v8::Utils::ToLocal(string2));
13865594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
13866594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
13867594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
13868594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UCollationResult result = collator->compare(u_string1,
13869594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              string_value1.length(),
13870594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              u_string2,
13871594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              string_value2.length(),
13872594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              status);
13873594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
13874594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13875594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *isolate->factory()->NewNumberFromInt(result);
13876594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13877594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#endif  // V8_I18N_SUPPORT
13878594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13879594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1388043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Finds the script object from the script data. NOTE: This operation uses
1388143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// heap traversal to find the function generated for the source position
1388243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for the requested break point. For lazily compiled functions several heap
1388343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// traversals might be required rendering this operation as a rather slow
1388443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// operation. However for setting break points which is normally done through
1388543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// some kind of user interaction the performance is not crucial.
1388643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic Handle<Object> Runtime_GetScriptFromScriptName(
1388743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<String> script_name) {
1388843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Scan the heap for Script objects to find the script with the requested
1388943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // script data.
1389043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Script> script;
13891d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Factory* factory = script_name->GetIsolate()->factory();
138927c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = script_name->GetHeap();
138937c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  heap->EnsureHeapIsIterable();
1389479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation_during_heap_iteration;
138957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HeapIterator iterator(heap);
13896b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  HeapObject* obj = NULL;
13897b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  while (script.is_null() && ((obj = iterator.next()) != NULL)) {
1389843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If a script is found check if it has the script data requested.
1389943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (obj->IsScript()) {
1390043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (Script::cast(obj)->name()->IsString()) {
1390143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
1390243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          script = Handle<Script>(Script::cast(obj));
1390343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1390443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1390543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1390643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1390743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1390843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If no script with the requested script data is found return undefined.
13909d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (script.is_null()) return factory->undefined_value();
1391043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1391143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the script found.
1391243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return GetScriptWrapper(script);
1391343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1391443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1391543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1391643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Get the script object from script data. NOTE: Regarding performance
1391743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// see the NOTE for GetScriptFromScriptData.
1391843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: script data for the script to find the source for
13919c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
13920ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1392143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1392243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1392343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13924f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, script_name, 0);
1392543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1392643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the requested script.
1392743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> result =
1392843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Runtime_GetScriptFromScriptName(Handle<String>(script_name));
1392943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
1393043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1393143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1393243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Collect the raw data for a stack trace.  Returns an array of 4
13934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// element segments each containing a receiver, function, code and
13935a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// native code offset.
13936c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
139376e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13938ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org  ASSERT_EQ(args.length(), 3);
13939f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
13940ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org  Handle<Object> caller = args.at<Object>(1);
13941ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
1394286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13943eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  // Optionally capture a more detailed stack trace for the message.
13944eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  isolate->CaptureAndSetDetailedStackTrace(error_object);
13945eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  // Capture a simple stack trace for the stack property.
13946eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
13947eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org}
1394886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
139492abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
13950fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Retrieve the stack trace.  This is the raw stack trace that yet has to
13951fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// be formatted.  Since we only need this once, clear it afterwards.
13952fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
1395346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  HandleScope scope(isolate);
13954eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  ASSERT_EQ(args.length(), 1);
13955eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  CONVERT_ARG_CHECKED(JSObject, error_object, 0);
139564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  String* key = isolate->heap()->hidden_stack_trace_string();
13957eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  Object* result = error_object->GetHiddenProperty(key);
13958fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (result->IsTheHole()) return isolate->heap()->undefined_value();
13959fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
13960fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  error_object->DeleteHiddenProperty(key);
13961eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  return result;
139622abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
139632abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
139642abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
139653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Returns V8 version as a string.
13966c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
1396779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
139686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT_EQ(args.length(), 0);
139693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
139703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  const char* version_string = v8::V8::GetVersion();
139713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
139728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string),
13973ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                  NOT_TENURED);
139743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
139753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
139763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
13977c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
1397879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1397943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
139806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  OS::PrintError("abort: %s\n",
139816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                 reinterpret_cast<char*>(args[0]) + args.smi_at(1));
13982bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  isolate->PrintStack(stderr);
1398343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  OS::Abort();
1398443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
1398543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
1398643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1398743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1398843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1398959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) {
1399059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  HandleScope scope(isolate);
1399159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(args.length() == 1);
1399259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
1399359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  FlattenString(str);
1399459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  return isolate->heap()->undefined_value();
1399559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
1399659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1399759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1399821af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
1399921af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  HandleScope scope(isolate);
1400021af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  ASSERT(args.length() == 0);
1400121af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  isolate->heap()->NotifyContextDisposed();
1400221af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org  return isolate->heap()->undefined_value();
1400321af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org}
1400421af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org
1400521af845429db249013386a8764cb52601d77a7a8jkummerow@chromium.org
14006594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) {
14007594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14008594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
14009594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14010594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!object->IsJSObject()) return Smi::FromInt(0);
14011594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
14012594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
14013594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  JSObject::MigrateInstance(js_object);
14014594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *object;
14015594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14016594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14017594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14018c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
1401979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14020c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // This is only called from codegen, so checks might be more lax.
14021f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
14022c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  Object* key = args[1];
14023c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
140240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  int finger_index = cache->finger_index();
14025c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  Object* o = cache->get(finger_index);
14026c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  if (o == key) {
14027c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    // The fastest case: hit the same place again.
14028c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    return cache->get(finger_index + 1);
14029c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
14030c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14031c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  for (int i = finger_index - 2;
14032c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org       i >= JSFunctionResultCache::kEntriesIndex;
14033c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org       i -= 2) {
14034c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    o = cache->get(i);
14035c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    if (o == key) {
140360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      cache->set_finger_index(i);
14037c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      return cache->get(i + 1);
14038c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    }
14039c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
14040c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
140410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  int size = cache->size();
14042c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  ASSERT(size <= cache->length());
14043c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14044c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  for (int i = size - 2; i > finger_index; i -= 2) {
14045c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    o = cache->get(i);
14046c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    if (o == key) {
140470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      cache->set_finger_index(i);
14048c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      return cache->get(i + 1);
14049c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    }
14050c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
14051c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
140520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // There is no value in the cache.  Invoke the function and cache result.
14053ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
140540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
140550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Handle<JSFunctionResultCache> cache_handle(cache);
1405609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> key_handle(key, isolate);
140570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Handle<Object> value;
140580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  {
140590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    Handle<JSFunction> factory(JSFunction::cast(
140600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
140610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    // TODO(antonm): consider passing a receiver when constructing a cache.
1406209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> receiver(isolate->native_context()->global_object(),
1406309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                            isolate);
140640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    // This handle is nor shared, nor used later, so it's safe.
14065a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    Handle<Object> argv[] = { key_handle };
14066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    bool pending_exception;
140670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    value = Execution::Call(factory,
140680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                            receiver,
14069a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                            ARRAY_SIZE(argv),
140700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                            argv,
140710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com                            &pending_exception);
140720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if (pending_exception) return Failure::Exception();
140730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  }
140740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
14075c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
14076394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
14077394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    cache_handle->JSFunctionResultCacheVerify();
14078394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
140790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif
140800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
140810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Function invocation may have cleared the cache.  Reread all the data.
140820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  finger_index = cache_handle->finger_index();
140830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  size = cache_handle->size();
140840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
140850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // If we have spare room, put new data into it, otherwise evict post finger
140860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // entry which is likely to be the least recently used.
140870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  int index = -1;
140880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if (size < cache_handle->length()) {
140890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
140900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    index = size;
14091c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  } else {
140920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    index = finger_index + JSFunctionResultCache::kEntrySize;
140930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if (index == cache_handle->length()) {
140940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      index = JSFunctionResultCache::kEntriesIndex;
14095397e23cb4f6fae2f4b020b914ce08c8b150c12e2antonm@chromium.org    }
14096c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
140970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
140980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(index % 2 == 0);
140990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
141000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(index < cache_handle->length());
141010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
141020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  cache_handle->set(index, *key_handle);
141030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  cache_handle->set(index + 1, *value);
141040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  cache_handle->set_finger_index(index);
141050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
14106c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
14107394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
14108394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    cache_handle->JSFunctionResultCacheVerify();
14109394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
141100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif
141110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
141120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  return *value;
14113c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
14114c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
1411531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
14116c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
1411779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14118f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
1411931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  return Smi::FromInt(message->start_position());
1412031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
1412131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
1412231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
14123c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
1412479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14125f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
1412631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  return message->script();
1412731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
1412831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
1412931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
1413044510671e908d0efc639513d81efcd81e7f14240kasper.lund#ifdef DEBUG
1413144510671e908d0efc639513d81efcd81e7f14240kasper.lund// ListNatives is ONLY used by the fuzz-natives.js in debug mode
1413244510671e908d0efc639513d81efcd81e7f14240kasper.lund// Exclude the code in release mode.
14133c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
14134c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate);
141356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 0);
141368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#define COUNT_ENTRY(Name, argc, ressize) + 1
141378f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  int entry_count = 0
141388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
141398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      INLINE_FUNCTION_LIST(COUNT_ENTRY)
141408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY);
141418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#undef COUNT_ENTRY
14142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Factory* factory = isolate->factory();
14143ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
1414443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index = 0;
14145f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  bool inline_runtime_functions = false;
14146a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#define ADD_ENTRY(Name, argc, ressize)                                       \
1414743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  {                                                                          \
14148c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    HandleScope inner(isolate);                                              \
14149f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    Handle<String> name;                                                     \
14150f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    /* Inline runtime functions have an underscore in front of the name. */  \
14151f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    if (inline_runtime_functions) {                                          \
14152ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      name = factory->NewStringFromAscii(                                    \
14153f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org          Vector<const char>("_" #Name, StrLength("_" #Name)));              \
14154f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    } else {                                                                 \
14155ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      name = factory->NewStringFromAscii(                                    \
14156f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org          Vector<const char>(#Name, StrLength(#Name)));                      \
14157f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    }                                                                        \
14158ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
141598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    pair_elements->set(0, *name);                                            \
141608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    pair_elements->set(1, Smi::FromInt(argc));                               \
14161ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
141628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    elements->set(index++, *pair);                                           \
1416343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
14164f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  inline_runtime_functions = false;
1416543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_FUNCTION_LIST(ADD_ENTRY)
14166f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  inline_runtime_functions = true;
14167d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  INLINE_FUNCTION_LIST(ADD_ENTRY)
14168f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
1416943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef ADD_ENTRY
141708f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  ASSERT_EQ(index, entry_count);
14171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
1417243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
1417343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1417444510671e908d0efc639513d81efcd81e7f14240kasper.lund#endif
1417543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1417643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14177c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
1417879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1417937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  ASSERT(args.length() == 2);
14180f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, format, 0);
14181f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSArray, elms, 1);
1418279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
14183ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent format_content = format->GetFlatContent();
14184ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  RUNTIME_ASSERT(format_content.IsAscii());
1418559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  Vector<const uint8_t> chars = format_content.ToOneByteVector();
14186e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  isolate->logger()->LogRuntime(Vector<const char>::cast(chars), elms);
14187ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1418837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
1418937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1419037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
14191c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
1419243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();  // implemented as macro in the parser
1419343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
1419443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1419543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1419643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
141974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
141984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) {     \
14199f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    CONVERT_ARG_CHECKED(JSObject, obj, 0);              \
142004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return isolate->heap()->ToBoolean(obj->Has##Name());  \
142014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
142024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
14203830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
14204830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
14205830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
142064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
14207830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
142084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
14209a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(NonStrictArgumentsElements)
142104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
142114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
142124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
142134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
142144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
142154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
142164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
142174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
142184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
142194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
142207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// Properties test sitting with elements tests - not fooling anyone.
142217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
142224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
142234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
142244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
14225b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
14226b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
1422779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14228b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  ASSERT(args.length() == 2);
14229f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14230f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14231b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14232b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org}
14233b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
14234e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14235e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
1423679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14237e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 1);
14238b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
14239b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
14240b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  JSReceiver* obj = JSReceiver::cast(args[0]);
1424132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  if (obj->IsJSGlobalProxy()) {
1424232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    Object* proto = obj->GetPrototype();
14243f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    if (proto->IsNull()) return isolate->heap()->false_value();
1424432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    ASSERT(proto->IsJSGlobalObject());
1424532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    obj = JSReceiver::cast(proto);
1424632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
14247e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return isolate->heap()->ToBoolean(obj->map()->is_observed());
14248e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14249e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14250e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14251e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) {
1425279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14253169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(args.length() == 1);
14254e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
1425532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  if (obj->IsJSGlobalProxy()) {
1425632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    Object* proto = obj->GetPrototype();
14257f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    if (proto->IsNull()) return isolate->heap()->undefined_value();
1425832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    ASSERT(proto->IsJSGlobalObject());
1425932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    obj = JSReceiver::cast(proto);
1426032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
14261594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (obj->IsJSProxy())
14262594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->undefined_value();
14263594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14264a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() &&
14265a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org           JSObject::cast(obj)->HasFastElements()));
14266169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(obj->IsJSObject());
14267169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return JSObject::cast(obj)->SetObserved(isolate);
14268e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14269e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14270e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14271e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_SetObserverDeliveryPending) {
1427279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14273e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 0);
14274e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  isolate->set_observer_delivery_pending(true);
14275e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return isolate->heap()->undefined_value();
14276e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14277e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14278e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14279e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_GetObservationState) {
1428079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14281e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 0);
14282e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return isolate->heap()->observation_state();
14283e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14284e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14285e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
142862f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapCreate) {
142872f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  HandleScope scope(isolate);
14288e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 0);
142892f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  // TODO(adamk): Currently this runtime function is only called three times per
142902f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  // isolate. If it's called more often, the map should be moved into the
142912f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  // strong root list.
142922f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  Handle<Map> map =
142932f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
142942f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  Handle<JSWeakMap> weakmap =
142952f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
14296ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return WeakCollectionInitialize(isolate, weakmap);
14297e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14298e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14299e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
143002f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) {
1430179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
143022f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  ASSERT(args.length() == 1);
143032f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  Object* object = args[0];
143042f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  if (object->IsJSGlobalProxy()) {
143058432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    object = object->GetPrototype(isolate);
143062f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    if (object->IsNull()) return isolate->heap()->undefined_value();
1430732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
143082f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  return object;
14309e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14310e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14311dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14312dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgstatic MaybeObject* ArrayConstructorCommon(Isolate* isolate,
14313dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                           Handle<JSFunction> constructor,
14314dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                           Handle<Object> type_info,
14315dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                           Arguments* caller_args) {
14316dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool holey = false;
14317dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool can_use_type_feedback = true;
14318dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (caller_args->length() == 1) {
14319dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Object* argument_one = (*caller_args)[0];
14320dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (argument_one->IsSmi()) {
14321dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      int value = Smi::cast(argument_one)->value();
14322dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
14323dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        // the array is a dictionary in this case.
14324dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        can_use_type_feedback = false;
14325dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      } else if (value != 0) {
14326dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        holey = true;
14327dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      }
14328dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    } else {
14329dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      // Non-smi length argument produces a dictionary
14330dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      can_use_type_feedback = false;
14331dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
14332dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
14333dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14334dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  JSArray* array;
14335dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  MaybeObject* maybe_array;
14336dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (!type_info.is_null() &&
14337dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      *type_info != isolate->heap()->undefined_value() &&
14338bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      Cell::cast(*type_info)->value()->IsAllocationSite() &&
14339dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      can_use_type_feedback) {
14340bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<Cell> cell = Handle<Cell>::cast(type_info);
14341bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<AllocationSite> site = Handle<AllocationSite>(
14342bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        AllocationSite::cast(cell->value()), isolate);
14343bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ASSERT(!site->IsLiteralSite());
14344bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ElementsKind to_kind = site->GetElementsKind();
14345dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (holey && !IsFastHoleyElementsKind(to_kind)) {
14346dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      to_kind = GetHoleyElementsKind(to_kind);
14347dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      // Update the allocation site info to reflect the advice alteration.
14348bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      site->SetElementsKind(to_kind);
14349dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
14350dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14351dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
14352bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        *constructor, site);
14353dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (!maybe_array->To(&array)) return maybe_array;
14354dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else {
14355dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    maybe_array = isolate->heap()->AllocateJSObject(*constructor);
14356dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (!maybe_array->To(&array)) return maybe_array;
14357dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    // We might need to transition to holey
14358dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    ElementsKind kind = constructor->initial_map()->elements_kind();
14359dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (holey && !IsFastHoleyElementsKind(kind)) {
14360dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      kind = GetHoleyElementsKind(kind);
14361dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      maybe_array = array->TransitionElementsKind(kind);
14362dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (maybe_array->IsFailure()) return maybe_array;
14363dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
14364dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
14365dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14366dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  maybe_array = isolate->heap()->AllocateJSArrayStorage(array, 0, 0,
14367dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      DONT_INITIALIZE_ARRAY_ELEMENTS);
14368dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (maybe_array->IsFailure()) return maybe_array;
14369dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  maybe_array = ArrayConstructInitializeElements(array, caller_args);
14370dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (maybe_array->IsFailure()) return maybe_array;
14371dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return array;
14372dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
14373dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14374dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14375dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
14376dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  HandleScope scope(isolate);
14377dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // If we get 2 arguments then they are the stub parameters (constructor, type
14378dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // info).  If we get 3, then the first one is a pointer to the arguments
14379dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // passed by the caller.
14380dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments empty_args(0, NULL);
14381dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool no_caller_args = args.length() == 2;
14382dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ASSERT(no_caller_args || args.length() == 3);
14383dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int parameters_start = no_caller_args ? 0 : 1;
14384dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments* caller_args = no_caller_args
14385dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ? &empty_args
14386dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      : reinterpret_cast<Arguments*>(args[0]);
14387dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
14388dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
14389dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14390dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return ArrayConstructorCommon(isolate,
14391dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                constructor,
14392dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                type_info,
14393dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                caller_args);
14394dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
14395dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14396dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14397dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) {
14398dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  HandleScope scope(isolate);
14399dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments empty_args(0, NULL);
14400dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool no_caller_args = args.length() == 1;
14401dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ASSERT(no_caller_args || args.length() == 2);
14402dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int parameters_start = no_caller_args ? 0 : 1;
14403dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments* caller_args = no_caller_args
14404dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ? &empty_args
14405dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      : reinterpret_cast<Arguments*>(args[0]);
14406dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
14407dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14408dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return ArrayConstructorCommon(isolate,
14409dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                constructor,
14410dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                Handle<Object>::null(),
14411dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                caller_args);
14412dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
14413dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
14414e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1441543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
1441643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Runtime
1441743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14418d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com#define F(name, number_of_args, result_size)                             \
14419d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  { Runtime::k##name, Runtime::RUNTIME, #name,   \
14420d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
14421d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
14422d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
14423d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com#define I(name, number_of_args, result_size)                             \
14424d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  { Runtime::kInline##name, Runtime::INLINE,     \
14425d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    "_" #name, NULL, number_of_args, result_size },
1442643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const Runtime::Function kIntrinsicFunctions[] = {
1442843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_FUNCTION_LIST(F)
14429d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  INLINE_FUNCTION_LIST(I)
14430d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  INLINE_RUNTIME_FUNCTION_LIST(I)
1443143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
1443243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1443343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14434ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
14435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                       Object* dictionary) {
14436ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(Isolate::Current()->heap() == heap);
14437d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  ASSERT(dictionary != NULL);
14438750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0);
14439d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  for (int i = 0; i < kNumFunctions; ++i) {
144404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Object* name_string;
144414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    { MaybeObject* maybe_name_string =
144424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          heap->InternalizeUtf8String(kIntrinsicFunctions[i].name);
144434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
14444303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
14445750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
14446750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    { MaybeObject* maybe_dictionary = name_dictionary->Add(
144474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          String::cast(name_string),
14448303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org          Smi::FromInt(i),
14449f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org          PropertyDetails(NONE, NORMAL, Representation::None()));
14450303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      if (!maybe_dictionary->ToObject(&dictionary)) {
14451303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        // Non-recoverable failure.  Calling code must restart heap
14452303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        // initialization.
14453303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org        return maybe_dictionary;
14454303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org      }
14455303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
14456d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  }
14457d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  return dictionary;
1445843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1445943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1446043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
144614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgconst Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
14462ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = name->GetHeap();
14463ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int entry = heap->intrinsic_function_names()->FindEntry(*name);
14464d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  if (entry != kNotFound) {
14465ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
14466d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    int function_index = Smi::cast(smi_index)->value();
14467d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    return &(kIntrinsicFunctions[function_index]);
1446843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1446943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
1447043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1447143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1447243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14473ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
14474d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  return &(kIntrinsicFunctions[static_cast<int>(id)]);
14475d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com}
14476d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
14477d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
1447843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Runtime::PerformGC(Object* result) {
144797979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Isolate* isolate = Isolate::Current();
1448043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Failure* failure = Failure::cast(result);
144819bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  if (failure->IsRetryAfterGC()) {
14482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (isolate->heap()->new_space()->AddFreshPage()) {
14483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return;
14484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
144852c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
144869bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // Try to do a garbage collection; ignore it if it fails. The C
144879bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // entry stub will throw an out-of-memory exception in that case.
14488994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    isolate->heap()->CollectGarbage(failure->allocation_space(),
14489994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                    "Runtime::PerformGC");
144909bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  } else {
144919bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // Handle last resort GC and make sure to allow future allocations
144929bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // to grow the heap without causing GCs (if possible).
144937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    isolate->counters()->gc_last_resort_from_js()->Increment();
14494994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14495994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org                                       "Runtime::PerformGC");
144969bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
1449743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1449843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1449943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1450043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
14501