1fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdlib.h>
6f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org#include <limits>
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/accessors.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation-site-scopes.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arguments.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compilation-cache.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/conversions.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu.h"
20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h"
21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/dateparser-inl.h"
22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
24196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/date.h"
25196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h"
26196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h"
27196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/global-handles.h"
28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h"
29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/jsregexp.h"
30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/jsregexp-inl.h"
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/json-parser.h"
32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/json-stringifier.h"
33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/liveedit.h"
34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/misc-intrinsics.h"
35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h"
36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/platform.h"
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime-profiler.h"
38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h"
39196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h"
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/smart-pointers.h"
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/string-search.h"
42196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/stub-cache.h"
43196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/uri.h"
44196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8threads.h"
45196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/vm-state-inl.h"
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#ifdef V8_I18N_SUPPORT
48196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/i18n.h"
49594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/brkiter.h"
50594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/calendar.h"
51594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/coll.h"
52594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/curramt.h"
53594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/datefmt.h"
54594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/dcfmtsym.h"
55594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/decimfmt.h"
56594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/dtfmtsym.h"
57594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/dtptngen.h"
58594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/locid.h"
59594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/numfmt.h"
60594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/numsys.h"
6132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org#include "unicode/rbbi.h"
62594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/smpdtfmt.h"
63594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/timezone.h"
64594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/uchar.h"
65594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/ucol.h"
66594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/ucurr.h"
67594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/uloc.h"
68594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/unum.h"
69594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#include "unicode/uversion.h"
70594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#endif
71594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
7277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org#ifndef _STLP_VENDOR_CSTD
7377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org// STLPort doesn't import fpclassify and isless into the std namespace.
7477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgusing std::fpclassify;
7577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgusing std::isless;
7677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org#endif
7777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
7871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
7971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
823e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org#define RUNTIME_ASSERT(value) \
83ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!(value)) return isolate->ThrowIllegalOperation();
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
858496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org#define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
868496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (!(value)) {                                                    \
878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    isolate->ThrowIllegalOperation();                                \
888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return MaybeHandle<T>();                                         \
898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  }
908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Cast the given object to a value of the specified type and store
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// it in a variable with the given name.  If the object is not of the
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// expected type call IllegalOperation and return.
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CONVERT_ARG_CHECKED(Type, name, index)                       \
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(args[index]->Is##Type());                           \
96f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Type* name = Type::cast(args[index]);
97f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
98f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
99f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->Is##Type());                           \
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Type> name = args.at<Type>(index);
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1028496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org#define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
1038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(args[index]->IsNumber());                           \
1048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Object> name = args.at<Object>(index);
1058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
106bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// Cast the given object to a boolean and store it in a variable with
107bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// the given name.  If the object is not a boolean call IllegalOperation
108bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund// and return.
109f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
110f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->IsBoolean());                          \
111f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  bool name = args[index]->IsTrue();
112bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
1136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// Cast the given argument to a Smi and store its value in an int variable
1146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// with the given name.  If the argument is not a Smi call IllegalOperation
115bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// and return.
1166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#define CONVERT_SMI_ARG_CHECKED(name, index)                         \
1176d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  RUNTIME_ASSERT(args[index]->IsSmi());                              \
1186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int name = args.smi_at(index);
119bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
1206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// Cast the given argument to a double and store it in a variable with
1216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// the given name.  If the argument is not a number (as opposed to
12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the number not-a-number) call IllegalOperation and return.
1236d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
1246d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  RUNTIME_ASSERT(args[index]->IsNumber());                           \
1256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  double name = args.number_at(index);
12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Call the specified converter on the object *comand store the result in
12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// a variable of the specified type with the given name.  If the
12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object is not a Number call IllegalOperation and return.
13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(obj->IsNumber());                                   \
13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  type name = NumberTo##Type(obj);
13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
135f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// Cast the given argument to PropertyDetails and store its value in a
136f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// variable with the given name.  If the argument is not a Smi call
137f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// IllegalOperation and return.
138f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
139f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->IsSmi());                              \
140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
141f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
142f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
143486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org// Assert that the given argument has a valid value for a StrictMode
144486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org// and store it in a StrictMode variable with the given name.
145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org#define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
146f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(args[index]->IsSmi());                              \
147486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
148486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                 args.smi_at(index) == SLOPPY);                      \
149486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode name = static_cast<StrictMode>(args.smi_at(index));
1501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
1511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
152236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgstatic Handle<Map> ComputeObjectLiteralMap(
153236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    Handle<Context> context,
154236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    Handle<FixedArray> constant_properties,
1555a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    bool* is_result_from_cache) {
156ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = context->GetIsolate();
157ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  int properties_length = constant_properties->length();
158ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  int number_of_properties = properties_length / 2;
1594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Check that there are only internal strings and array indices among keys.
1604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int number_of_string_keys = 0;
16178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  for (int p = 0; p != properties_length; p += 2) {
16278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    Object* key = constant_properties->get(p);
16378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    uint32_t element_index = 0;
1644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (key->IsInternalizedString()) {
1654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      number_of_string_keys++;
16678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    } else if (key->ToArrayIndex(&element_index)) {
16778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // An index key does not require space in the property backing store.
16878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      number_of_properties--;
16978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    } else {
1704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // Bail out as a non-internalized-string non-index key makes caching
1714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // impossible.
17278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // ASSERT to make sure that the if condition after the loop is false.
1734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      ASSERT(number_of_string_keys != number_of_properties);
17478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      break;
175236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
17678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
1774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // If we only have internalized strings and array indices among keys then we
1784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // can use the map cache in the native context.
17978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  const int kMaxKeys = 10;
1804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if ((number_of_string_keys == number_of_properties) &&
1814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      (number_of_string_keys < kMaxKeys)) {
18278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // Create the fixed array with the key.
18378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    Handle<FixedArray> keys =
1844a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        isolate->factory()->NewFixedArray(number_of_string_keys);
1854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (number_of_string_keys > 0) {
18678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      int index = 0;
18778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      for (int p = 0; p < properties_length; p += 2) {
18878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        Object* key = constant_properties->get(p);
1894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        if (key->IsInternalizedString()) {
19078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          keys->set(index++, key);
191ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org        }
192236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      }
1934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      ASSERT(index == number_of_string_keys);
194236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
19578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    *is_result_from_cache = true;
19678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
197236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
1985a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  *is_result_from_cache = false;
1994edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  return Map::Create(handle(context->object_function()), number_of_properties);
200236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
201236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
202236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
2038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
204ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
205bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
206bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> constant_properties);
20741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
208bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
2098f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
210ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
211bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
212f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    Handle<FixedArray> constant_properties,
213ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    bool should_have_fast_elements,
214ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    bool has_function_literal) {
21546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Get the native context from the literals array.  This is the
21641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // context in which the function was created and we use the object
21741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // function from this context to create the object literal.  We do
21846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // not use the object function from the current native context
21941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // because this might be the object function from another context
22041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // which we should not have access to.
221236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  Handle<Context> context =
22246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
223236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
224ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // In case we have function literals, we want the object to be in
225ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // slow properties mode for now. We don't go in the map cache because
226ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // maps with constant functions can't be shared if the functions are
227ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // not the same (which is the common case).
228ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool is_result_from_cache = false;
229ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Map> map = has_function_literal
230ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ? Handle<Map>(context->object_function()->initial_map())
231ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : ComputeObjectLiteralMap(context,
232ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                constant_properties,
233ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                &is_result_from_cache);
23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
235bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  PretenureFlag pretenure_flag =
236bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
237bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
23857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSObject> boilerplate =
239bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
240f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
241f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  // Normalize the elements of the boilerplate to save space if needed.
242f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
243f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
244ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Add the constant properties to the boilerplate.
245ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int length = constant_properties->length();
246ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool should_transform =
247ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      !is_result_from_cache && boilerplate->HasFastProperties();
24870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  bool should_normalize = should_transform || has_function_literal;
24970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  if (should_normalize) {
25070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org    // TODO(verwaest): We might not want to ever normalize here.
251f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::NormalizeProperties(
252f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
253ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
25470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  Object::ValueType value_type = should_normalize
25570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org      ? Object::FORCE_TAGGED : Object::OPTIMAL_REPRESENTATION;
256ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
257f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // TODO(verwaest): Support tracking representations in the boilerplate.
258ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  for (int index = 0; index < length; index +=2) {
259ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> key(constant_properties->get(index+0), isolate);
260ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> value(constant_properties->get(index+1), isolate);
261ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (value->IsFixedArray()) {
262ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // The value contains the constant_properties of a
263ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // simple object or array literal.
264ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<FixedArray> array = Handle<FixedArray>::cast(value);
2658f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
2668f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          isolate, value,
2678f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          CreateLiteralBoilerplate(isolate, literals, array),
2688f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          Object);
269ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
2708f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    MaybeHandle<Object> maybe_result;
271ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    uint32_t element_index = 0;
2729259716434187c932704601f700375e53d865de8rossberg@chromium.org    StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
2734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (key->IsInternalizedString()) {
274ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
275ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        // Array index as string (uint32).
2768f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        maybe_result = JSObject::SetOwnElement(
277486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            boilerplate, element_index, value, SLOPPY);
27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
279ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        Handle<String> name(String::cast(*key));
280ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        ASSERT(!name->AsArrayIndex(&element_index));
281fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
282fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org            boilerplate, name, value, NONE,
28370d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org            value_type, mode);
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
285ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    } else if (key->ToArrayIndex(&element_index)) {
286ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // Array index (uint32).
2878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      maybe_result = JSObject::SetOwnElement(
288486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          boilerplate, element_index, value, SLOPPY);
289ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    } else {
290ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      // Non-uint32 number.
291ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      ASSERT(key->IsNumber());
292ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      double num = key->Number();
293ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      char arr[100];
294ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Vector<char> buffer(arr, ARRAY_SIZE(arr));
295ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      const char* str = DoubleToCString(num, buffer);
2968496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
297fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
298fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org          boilerplate, name, value, NONE,
29970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org          value_type, mode);
300ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
301ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // If setting the property on the boilerplate throws an
302ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // exception, the exception is converted to an empty handle in
303ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // the handle based operations.  In that case, we need to
304ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // convert back to an exception.
3058f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
306ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
308ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Transform to fast properties if necessary. For object literals with
309ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // containing function literals we defer this operation until after all
310ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // computed properties have been assigned so that we can generate
311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // constant function properties.
312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (should_transform && !has_function_literal) {
313f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::TransformToFastProperties(
314f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        boilerplate, boilerplate->map()->unused_property_fields());
3157be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  }
3167be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
317bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return boilerplate;
318bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
319bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
320bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3219e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
3229e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Object> object,
3239e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    ElementsKind to_kind,
3249e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Isolate* isolate) {
325fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  HandleScope scope(isolate);
3269e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (!object->IsJSObject()) {
3279e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    isolate->ThrowIllegalOperation();
3289e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return MaybeHandle<Object>();
3299e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  }
330fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  ElementsKind from_kind =
331fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      Handle<JSObject>::cast(object)->map()->elements_kind();
332fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (Map::IsValidElementsTransition(from_kind, to_kind)) {
333528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
3349e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return object;
335fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
3369e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  isolate->ThrowIllegalOperation();
3379e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return MaybeHandle<Object>();
338fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
339fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
340fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
341830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgstatic const int kSmiLiteralMinimumLength = 1024;
342a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
343a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
3448f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
345ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
346bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
347bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> elements) {
348bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Create the JSArray.
349bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<JSFunction> constructor(
35046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      JSFunction::NativeContextFromLiterals(*literals)->array_function());
35157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
352bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  PretenureFlag pretenure_flag =
353bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
354bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
35557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSArray> object = Handle<JSArray>::cast(
356bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      isolate->factory()->NewJSObject(constructor, pretenure_flag));
357394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
358394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ElementsKind constant_elements_kind =
359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
360394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArrayBase> constant_elements_values(
361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      FixedArrayBase::cast(elements->get(1)));
362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3639e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  { DisallowHeapAllocation no_gc;
3649e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    ASSERT(IsFastElementsKind(constant_elements_kind));
3659e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Context* native_context = isolate->context()->native_context();
3669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Object* maps_array = native_context->js_array_maps();
3679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    ASSERT(!maps_array->IsUndefined());
3689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
3699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    object->set_map(Map::cast(map));
3709e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  }
371394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArrayBase> copied_elements_values;
373830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsFastDoubleElementsKind(constant_elements_kind)) {
374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ASSERT(FLAG_smi_only_arrays);
375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Handle<FixedDoubleArray>::cast(constant_elements_values));
377394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
378830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    const bool is_cow =
380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        (constant_elements_values->map() ==
381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com         isolate->heap()->fixed_cow_array_map());
382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (is_cow) {
383394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      copied_elements_values = constant_elements_values;
384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#if DEBUG
385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> fixed_array_values =
386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<FixedArray>::cast(copied_elements_values);
387394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      for (int i = 0; i < fixed_array_values->length(); i++) {
388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ASSERT(!fixed_array_values->get(i)->IsFixedArray());
389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
390a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org#endif
391394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> fixed_array_values =
393394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<FixedArray>::cast(constant_elements_values);
394394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> fixed_array_values_copy =
395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          isolate->factory()->CopyFixedArray(fixed_array_values);
396394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      copied_elements_values = fixed_array_values_copy;
397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      for (int i = 0; i < fixed_array_values->length(); i++) {
3989e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        if (fixed_array_values->get(i)->IsFixedArray()) {
399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          // The value contains the constant_properties of a
400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          // simple object or array literal.
401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
4028f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          Handle<Object> result;
4038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION(
4048f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org              isolate, result,
4058f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org              CreateLiteralBoilerplate(isolate, literals, fa),
4068f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org              Object);
407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          fixed_array_values_copy->set(i, *result);
408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
4090b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org      }
410bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
411bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
412394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  object->set_elements(*copied_elements_values);
413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  object->set_length(Smi::FromInt(copied_elements_values->length()));
414fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
415830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
416fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  //  on or the object is larger than the threshold.
417fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  if (!FLAG_smi_only_arrays &&
418830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      constant_elements_values->length() < kSmiLiteralMinimumLength) {
419830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind elements_kind = object->GetElementsKind();
420830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (!IsFastObjectElementsKind(elements_kind)) {
421830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      if (IsFastHoleyElementsKind(elements_kind)) {
4229e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        TransitionElements(object, FAST_HOLEY_ELEMENTS, isolate).Check();
423830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      } else {
4249e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        TransitionElements(object, FAST_ELEMENTS, isolate).Check();
425830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      }
426fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    }
427fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
428fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
42949ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  JSObject::ValidateElements(object);
430bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return object;
431bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
432bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
433bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4348f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
436bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> literals,
437bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<FixedArray> array) {
438bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
439ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  const bool kHasNoFunctionLiteral = false;
440dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  switch (CompileTimeValue::GetLiteralType(array)) {
441f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
442ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return CreateObjectLiteralBoilerplate(isolate,
443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            literals,
444ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            elements,
445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            true,
446ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            kHasNoFunctionLiteral);
447f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
448ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return CreateObjectLiteralBoilerplate(isolate,
449ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            literals,
450ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            elements,
451ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            false,
452ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            kHasNoFunctionLiteral);
453bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    case CompileTimeValue::ARRAY_LITERAL:
4547ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      return Runtime::CreateArrayLiteralBoilerplate(
4557ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          isolate, literals, elements);
456bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    default:
457bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      UNREACHABLE();
4588f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      return MaybeHandle<Object>();
459bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
460bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
461bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
462bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
463a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_CreateObjectLiteral) {
464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
465f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  ASSERT(args.length() == 4);
466f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
4676d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
468f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
4696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 3);
470ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
471ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
47213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
4738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
4748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
47513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Check if boilerplate exists. If not, create it first.
476dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<Object> literal_site(literals->get(literals_index), isolate);
477dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<AllocationSite> site;
478b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  Handle<JSObject> boilerplate;
479dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (*literal_site == isolate->heap()->undefined_value()) {
4808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Object> raw_boilerplate;
4818f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4828f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        isolate, raw_boilerplate,
4838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        CreateObjectLiteralBoilerplate(
4848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            isolate,
4858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            literals,
4868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            constant_properties,
4878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            should_have_fast_elements,
4888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            has_function_literal));
489b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    boilerplate = Handle<JSObject>::cast(raw_boilerplate);
490b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
491b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    AllocationSiteCreationContext creation_context(isolate);
492b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    site = creation_context.EnterNewScope();
493a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(
494a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        isolate,
495a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        JSObject::DeepWalk(boilerplate, &creation_context));
496b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    creation_context.ExitScope(site, boilerplate);
497dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
49813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    // Update the functions literal and return the boilerplate.
499dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    literals->set(literals_index, *site);
500dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  } else {
501dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    site = Handle<AllocationSite>::cast(literal_site);
502b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
503b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                   isolate);
50413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
50513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
506b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  AllocationSiteUsageContext usage_context(isolate, site, true);
507b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  usage_context.EnterNewScope();
508a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
509a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      boilerplate, &usage_context);
510b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  usage_context.ExitScope(site, boilerplate);
511a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Handle<Object> copy;
512a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
513528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return *copy;
51413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
51513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
51613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
5178f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
518bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Isolate* isolate,
519bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<FixedArray> literals,
520bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    int literals_index,
521bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<FixedArray> elements) {
522bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Check if boilerplate exists. If not, create it first.
523bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<Object> literal_site(literals->get(literals_index), isolate);
524bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<AllocationSite> site;
525bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (*literal_site == isolate->heap()->undefined_value()) {
526bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ASSERT(*elements != isolate->heap()->empty_fixed_array());
5278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Object> boilerplate;
5288f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
5298f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        isolate, boilerplate,
5308f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
5318f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        AllocationSite);
532b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
533b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    AllocationSiteCreationContext creation_context(isolate);
534b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    site = creation_context.EnterNewScope();
535b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
536b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                           &creation_context).is_null()) {
537b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return Handle<AllocationSite>::null();
538528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
539b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
540b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
541bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    literals->set(literals_index, *site);
542bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else {
543bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    site = Handle<AllocationSite>::cast(literal_site);
544bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
545bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
546bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return site;
547bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
548bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
549bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
550e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
55137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                           Handle<FixedArray> literals,
55237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                           int literals_index,
55337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                           Handle<FixedArray> elements,
55437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                           int flags) {
5558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
5568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                            literals_index < literals->length(), JSObject);
5578f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<AllocationSite> site;
558e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
5598f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, site,
560e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      GetLiteralAllocationSite(isolate, literals, literals_index, elements),
561e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      JSObject);
562bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
56337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
564528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
56537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
566b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  usage_context.EnterNewScope();
56737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
56837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      ? JSObject::kNoHints
56937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      : JSObject::kObjectIsShallowArray;
570a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
571a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                                                  hints);
572b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  usage_context.ExitScope(site, boilerplate);
573e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return copy;
57413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
57513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
57613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
577a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteral) {
57837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  HandleScope scope(isolate);
57937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  ASSERT(args.length() == 4);
58037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
58137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
58237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
58337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 3);
58437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
585e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<JSObject> result;
586e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
587e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
588e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                             flags));
589e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *result;
59037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org}
59137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
59237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
593a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteralStubBailout) {
59437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  HandleScope scope(isolate);
59537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  ASSERT(args.length() == 3);
59637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
59737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
59837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
59937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
600e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<JSObject> result;
601e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
602e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org     CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
603e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                            ArrayLiteral::kShallowElements));
604e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *result;
60537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org}
60637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
60737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
608a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateSymbol) {
609f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
610f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
6118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
612f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
613e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<Symbol> symbol = isolate->factory()->NewSymbol();
614f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (name->IsString()) symbol->set_name(*name);
615e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *symbol;
616f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
617f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
618f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
619a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
6200cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HandleScope scope(isolate);
6210cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  ASSERT(args.length() == 1);
6228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
6230cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
624e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
6250cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (name->IsString()) symbol->set_name(*name);
626e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *symbol;
6270cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
6280cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
6290cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
630a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
631a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  HandleScope scope(isolate);
632a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  ASSERT(args.length() == 1);
633a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
634a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  Handle<JSObject> registry = isolate->GetSymbolRegistry();
635a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  Handle<String> part = isolate->factory()->private_intern_string();
636202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> privates;
637202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
638202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, privates, Object::GetPropertyOrElement(registry, part));
639202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> symbol;
640202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
641202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, symbol, Object::GetPropertyOrElement(privates, name));
642a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  if (!symbol->IsSymbol()) {
643a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    ASSERT(symbol->IsUndefined());
644a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    symbol = isolate->factory()->NewPrivateSymbol();
645a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    Handle<Symbol>::cast(symbol)->set_name(*name);
646202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    JSObject::SetProperty(Handle<JSObject>::cast(privates),
647202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                          name, symbol, NONE, STRICT).Assert();
648a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  }
649a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  return *symbol;
650a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org}
651a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
652a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
653a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
65474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  HandleScope scope(isolate);
655f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(args.length() == 1);
65674dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
65774dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  return *Object::ToObject(isolate, symbol).ToHandleChecked();
658f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
659f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
660f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
661a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SymbolDescription) {
66279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
663f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
664f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
665f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return symbol->name();
66613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org}
66713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
66813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
669a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SymbolRegistry) {
670a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  HandleScope scope(isolate);
671fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  ASSERT(args.length() == 0);
672a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  return *isolate->GetSymbolRegistry();
673fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org}
674fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
675fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
676a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
6770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  SealHandleScope shs(isolate);
6780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  ASSERT(args.length() == 1);
6790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
6800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  return isolate->heap()->ToBoolean(symbol->is_private());
6810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
6820cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
6830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
684a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateJSProxy) {
685e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
6867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  ASSERT(args.length() == 2);
687e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
6888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
689e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
690e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewJSProxy(handler, prototype);
6917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
6927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
6937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
694a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
695e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
69634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 4);
697e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
6988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
699de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
700e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
7018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
702e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
703e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewJSFunctionProxy(
704e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      handler, call_trap, construct_trap, prototype);
70534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
70634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
70734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
708a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsJSProxy) {
70979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
710d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ASSERT(args.length() == 1);
7118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
7127c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSProxy());
713d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
714d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
715d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
716a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
71779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
71834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 1);
7198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
72034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
72134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
72234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
72334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
724a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetHandler) {
72579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
726d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ASSERT(args.length() == 1);
727f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
728d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  return proxy->handler();
729d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
730d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
731d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
732a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetCallTrap) {
73379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
73434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 1);
735f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
73634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return proxy->call_trap();
73734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
73834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
73934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
740a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetConstructTrap) {
74179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
74234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 1);
743f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
74434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return proxy->construct_trap();
74534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
74634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
74734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
748a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Fix) {
7498fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  HandleScope scope(isolate);
750717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  ASSERT(args.length() == 1);
7518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
7528fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  JSProxy::Fix(proxy);
7539fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org  return isolate->heap()->undefined_value();
754717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
755717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
756717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
7571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid Runtime::FreeArrayBuffer(Isolate* isolate,
7581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                              JSArrayBuffer* phantom_array_buffer) {
759f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (phantom_array_buffer->should_be_freed()) {
760f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    ASSERT(phantom_array_buffer->is_external());
761f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    free(phantom_array_buffer->backing_store());
762f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
7631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (phantom_array_buffer->is_external()) return;
764f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
7651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t allocated_length = NumberToSize(
7661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      isolate, phantom_array_buffer->byte_length());
7671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
7681e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  reinterpret_cast<v8::Isolate*>(isolate)
7691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      ->AdjustAmountOfExternalAllocatedMemory(
7701e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          -static_cast<int64_t>(allocated_length));
7711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CHECK(V8::ArrayBufferAllocator() != NULL);
772307dd6ea3b729c8058ada645b42a1cf083c92128danno@chromium.org  V8::ArrayBufferAllocator()->Free(
773307dd6ea3b729c8058ada645b42a1cf083c92128danno@chromium.org      phantom_array_buffer->backing_store(),
774307dd6ea3b729c8058ada645b42a1cf083c92128danno@chromium.org      allocated_length);
775f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
776f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
777f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
778a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgvoid Runtime::SetupArrayBuffer(Isolate* isolate,
779ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                               Handle<JSArrayBuffer> array_buffer,
780a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                               bool is_external,
781ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                               void* data,
782ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                               size_t allocated_length) {
783a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(array_buffer->GetInternalFieldCount() ==
784a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      v8::ArrayBuffer::kInternalFieldCount);
785a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
786a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    array_buffer->SetInternalField(i, Smi::FromInt(0));
787a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
788ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  array_buffer->set_backing_store(data);
789a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  array_buffer->set_flag(Smi::FromInt(0));
790a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  array_buffer->set_is_external(is_external);
791ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
792ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Handle<Object> byte_length =
7934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      isolate->factory()->NewNumberFromSize(allocated_length);
794ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
795ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  array_buffer->set_byte_length(*byte_length);
7961fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
7971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
7981fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  isolate->heap()->set_array_buffers_list(*array_buffer);
7991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
800ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
801ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
802ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
803ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgbool Runtime::SetupArrayBufferAllocatingData(
804ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Isolate* isolate,
805ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Handle<JSArrayBuffer> array_buffer,
806d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    size_t allocated_length,
807d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    bool initialize) {
808ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void* data;
809837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  CHECK(V8::ArrayBufferAllocator() != NULL);
810ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (allocated_length != 0) {
811d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (initialize) {
812d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
813d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    } else {
814d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      data =
8158496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
816d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
817ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (data == NULL) return false;
818ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
819ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    data = NULL;
820ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
821ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
822a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
823ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
8241e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  reinterpret_cast<v8::Isolate*>(isolate)
8251e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
826ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
827ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return true;
828ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
829ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
830ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
8314452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.orgvoid Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
8324452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  Isolate* isolate = array_buffer->GetIsolate();
8334452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
8344452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org       !view_obj->IsUndefined();) {
8354452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
8364452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    if (view->IsJSTypedArray()) {
8374452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      JSTypedArray::cast(*view)->Neuter();
8384452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    } else if (view->IsJSDataView()) {
8394452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      JSDataView::cast(*view)->Neuter();
8404452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    } else {
8414452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      UNREACHABLE();
8424452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    }
8434452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    view_obj = handle(view->weak_next(), isolate);
8444452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  }
8454452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  array_buffer->Neuter();
8464452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org}
8474452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org
8484452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org
849a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
850f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
851f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 2);
852f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
8538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
854f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (!holder->byte_length()->IsUndefined()) {
855f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    // ArrayBuffer is already initialized; probably a fuzz test.
856f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    return *holder;
857f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  }
8588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  size_t allocated_length = 0;
8598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
8608496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return isolate->Throw(
8618496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        *isolate->factory()->NewRangeError("invalid_array_buffer_length",
8628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                           HandleVector<Object>(NULL, 0)));
863f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
864ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (!Runtime::SetupArrayBufferAllocatingData(isolate,
865ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                                               holder, allocated_length)) {
8668496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return isolate->Throw(
8678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        *isolate->factory()->NewRangeError("invalid_array_buffer_length",
8688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                           HandleVector<Object>(NULL, 0)));
869f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
870f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return *holder;
871f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
872f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
873f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
874a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
87579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
876f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 1);
877f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
878f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return holder->byte_length();
879f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
880f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
881f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
882a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
883f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
884f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 3);
885f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
886f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
8878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
888a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(!source.is_identical_to(target));
8898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  size_t start = 0;
8908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
891e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  size_t target_length = NumberToSize(isolate, target->byte_length());
892f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
893b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (target_length == 0) return isolate->heap()->undefined_value();
894f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
8954452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
8968496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(start <= source_byte_length);
8978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(source_byte_length - start >= target_length);
898f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
899f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
900f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CopyBytes(target_data, source_data + start, target_length);
901f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return isolate->heap()->undefined_value();
902f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
903f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
904f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
905a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
90663ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  HandleScope scope(isolate);
90763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  ASSERT(args.length() == 1);
90863ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  CONVERT_ARG_CHECKED(Object, object, 0);
9098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
91063ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org}
91163ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
91263ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org
913a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
9144452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  HandleScope scope(isolate);
9158496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
9164452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
9179b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (array_buffer->backing_store() == NULL) {
9189b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    CHECK(Smi::FromInt(0) == array_buffer->byte_length());
9199b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    return isolate->heap()->undefined_value();
9209b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  }
9214452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  ASSERT(!array_buffer->is_external());
9224452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  void* backing_store = array_buffer->backing_store();
9234452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
9244452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  array_buffer->set_is_external(true);
9254452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  Runtime::NeuterArrayBuffer(array_buffer);
9264452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
9274452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  return isolate->heap()->undefined_value();
9284452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org}
9294452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org
9304452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org
93137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgvoid Runtime::ArrayIdToTypeAndSize(
932895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    int arrayId,
933895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ExternalArrayType* array_type,
934895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ElementsKind* external_elements_kind,
935895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ElementsKind* fixed_elements_kind,
936895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    size_t* element_size) {
937e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  switch (arrayId) {
938af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
939af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case ARRAY_ID_##TYPE:                                                      \
940af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      *array_type = kExternal##Type##Array;                                    \
941895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
942895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
943af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      *element_size = size;                                                    \
94457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      break;
945af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
946af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(ARRAY_ID_CASE)
947af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef ARRAY_ID_CASE
948af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
949e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    default:
950e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      UNREACHABLE();
951e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
952d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
953d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
954d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
955a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
956d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HandleScope scope(isolate);
957d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(args.length() == 5);
958d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
959d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
960895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
9618496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
9628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
964a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
965a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                 arrayId <= Runtime::ARRAY_ID_LAST);
966d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
967af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t element_size = 1;  // Bogus initialization.
969c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  ElementsKind external_elements_kind =
970c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
971c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
972895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Runtime::ArrayIdToTypeAndSize(arrayId,
973895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &array_type,
974895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &external_elements_kind,
975895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &fixed_elements_kind,
976895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &element_size);
977a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
978a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org
9798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  size_t byte_offset = 0;
9808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  size_t byte_length = 0;
9818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
9828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
9838496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
98479d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  if (maybe_buffer->IsJSArrayBuffer()) {
98579d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
98679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    size_t array_buffer_byte_length =
98779d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org        NumberToSize(isolate, buffer->byte_length());
98879d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
98979d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
99079d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  } else {
99179d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    RUNTIME_ASSERT(maybe_buffer->IsNull());
99279d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  }
993e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
994a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(byte_length % element_size == 0);
995d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t length = byte_length / element_size;
996e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
997ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (length > static_cast<unsigned>(Smi::kMaxValue)) {
9988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return isolate->Throw(
9998496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        *isolate->factory()->NewRangeError("invalid_typed_array_length",
10008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                           HandleVector<Object>(NULL, 0)));
1001ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
1002ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
100379d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  // All checks are done, now we can modify objects.
100479d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org
100579d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  ASSERT(holder->GetInternalFieldCount() ==
100679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org      v8::ArrayBufferView::kInternalFieldCount);
100779d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
100879d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    holder->SetInternalField(i, Smi::FromInt(0));
100979d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  }
10104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
1011e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  holder->set_length(*length_obj);
101279d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  holder->set_byte_offset(*byte_offset_object);
101379d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  holder->set_byte_length(*byte_length_object);
1014895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
101579d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  if (!maybe_buffer->IsNull()) {
101679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
1017895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    holder->set_buffer(*buffer);
1018895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    holder->set_weak_next(buffer->weak_first_view());
1019895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    buffer->set_weak_first_view(*holder);
1020895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
1021895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Handle<ExternalArray> elements =
1022895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        isolate->factory()->NewExternalArray(
1023895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org            static_cast<int>(length), array_type,
1024895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org            static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
1025895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Handle<Map> map =
1026895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        JSObject::GetElementsTransitionMap(holder, external_elements_kind);
102763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    JSObject::SetMapAndElements(holder, map, elements);
1028895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
1029895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  } else {
1030895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    holder->set_buffer(Smi::FromInt(0));
1031895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    holder->set_weak_next(isolate->heap()->undefined_value());
1032895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Handle<FixedTypedArrayBase> elements =
1033895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        isolate->factory()->NewFixedTypedArray(
1034895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org            static_cast<int>(length), array_type);
1035895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    holder->set_elements(*elements);
1036895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
1037e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return isolate->heap()->undefined_value();
1038e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
1039e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1040e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1041d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Initializes a typed array from an array-like object.
1042d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// If an array-like object happens to be a typed array of the same type,
1043d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// initializes backing store using memove.
1044d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org//
1045d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Returns true if backing store was initialized or false otherwise.
1046a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
1047d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HandleScope scope(isolate);
1048d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(args.length() == 4);
1049d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1050d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
1051d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
1052f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
1053d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1054a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
1055a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                 arrayId <= Runtime::ARRAY_ID_LAST);
1056a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
1057af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
1058d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  size_t element_size = 1;  // Bogus initialization.
1059c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  ElementsKind external_elements_kind =
1060c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
1061c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
1062895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Runtime::ArrayIdToTypeAndSize(arrayId,
1063895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &array_type,
1064895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &external_elements_kind,
1065895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &fixed_elements_kind,
1066895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &element_size);
1067d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1068a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
1069a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org
1070d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
107197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (source->IsJSTypedArray() &&
107297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      JSTypedArray::cast(*source)->type() == array_type) {
107397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
107497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
1075f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  size_t length = 0;
1076f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
1077ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1078ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
1079ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      (length > (kMaxInt / element_size))) {
1080d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return isolate->Throw(*isolate->factory()->
1081ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          NewRangeError("invalid_typed_array_length",
1082d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            HandleVector<Object>(NULL, 0)));
1083d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1084feecfdecd0a36aaebe2d2b7cab8178d2b71d45cfmachenbach@chromium.org  size_t byte_length = length * element_size;
1085d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
108679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  ASSERT(holder->GetInternalFieldCount() ==
108779d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org      v8::ArrayBufferView::kInternalFieldCount);
108879d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
108979d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    holder->SetInternalField(i, Smi::FromInt(0));
109079d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  }
109179d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org
10923d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // NOTE: not initializing backing store.
1093d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // We assume that the caller of this function will initialize holder
1094d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // with the loop
1095d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
10963d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // We assume that the caller of this function is always a typed array
10973d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // constructor.
1098d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // If source is a typed array, this loop will always run to completion,
1099d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // so we are sure that the backing store will be initialized.
11003d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Otherwise, the indexing operation might throw, so the loop will not
11013d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // run to completion and the typed array might remain partly initialized.
11023d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // However we further assume that the caller of this function is a typed array
11033d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // constructor, and the exception will propagate out of the constructor,
11043d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // therefore uninitialized memory will not be accessible by a user program.
11053d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  //
11063d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // TODO(dslomov): revise this once we support subclassing.
1107d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1108d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (!Runtime::SetupArrayBufferAllocatingData(
11093d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org        isolate, buffer, byte_length, false)) {
1110d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return isolate->Throw(*isolate->factory()->
1111d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          NewRangeError("invalid_array_buffer_length",
1112d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            HandleVector<Object>(NULL, 0)));
1113d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1114d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1115d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_buffer(*buffer);
1116d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_byte_offset(Smi::FromInt(0));
1117d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Handle<Object> byte_length_obj(
1118d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      isolate->factory()->NewNumberFromSize(byte_length));
1119d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_byte_length(*byte_length_obj);
1120d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_length(*length_obj);
1121d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  holder->set_weak_next(buffer->weak_first_view());
1122d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  buffer->set_weak_first_view(*holder);
1123d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1124d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Handle<ExternalArray> elements =
1125d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      isolate->factory()->NewExternalArray(
1126d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          static_cast<int>(length), array_type,
1127d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          static_cast<uint8_t*>(buffer->backing_store()));
1128895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Map> map = JSObject::GetElementsTransitionMap(
1129895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      holder, external_elements_kind);
113063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  JSObject::SetMapAndElements(holder, map, elements);
1131d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1132d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (source->IsJSTypedArray()) {
1133d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
1134d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1135d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    if (typed_array->type() == holder->type()) {
1136d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      uint8_t* backing_store =
1137d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        static_cast<uint8_t*>(
1138895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          typed_array->GetBuffer()->backing_store());
1139d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      size_t source_byte_offset =
1140d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          NumberToSize(isolate, typed_array->byte_offset());
114132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      memcpy(
1142d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          buffer->backing_store(),
1143d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          backing_store + source_byte_offset,
1144d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          byte_length);
11458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return isolate->heap()->true_value();
1146d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
1147d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1148d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
11498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return isolate->heap()->false_value();
1150d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1151d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1152d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
11532f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
1154a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
115557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    HandleScope scope(isolate);                                               \
115657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT(args.length() == 1);                                               \
11572f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
11582f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    return holder->accessor();                                                \
1159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
11612f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgBUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
11622f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgBUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
11632f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgBUFFER_VIEW_GETTER(TypedArray, Length, length)
11642f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgBUFFER_VIEW_GETTER(DataView, Buffer, buffer)
1165e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
11662f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#undef BUFFER_VIEW_GETTER
1167e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1168a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
1169895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HandleScope scope(isolate);
1170895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ASSERT(args.length() == 1);
11712f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
11722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return *holder->GetBuffer();
1173895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
1174895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
1175895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
1176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Return codes for Runtime_TypedArraySetFastCases.
1177d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org// Should be synchronized with typedarray.js natives.
1178d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgenum TypedArraySetResultCodes {
1179d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from typed array of the same type.
1180d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // This is processed by TypedArraySetFastCases
1181d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
1182d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from typed array of the different type, overlapping in memory.
1183d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
1184d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from typed array of the different type, non-overlapping.
1185d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
1186d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Set from non-typed array.
1187d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
1188d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org};
1189d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1190d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1191a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
119257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  HandleScope scope(isolate);
11938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 3);
1194f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (!args[0]->IsJSTypedArray())
119557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return isolate->Throw(*isolate->factory()->NewTypeError(
119657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        "not_typed_array", HandleVector<Object>(NULL, 0)));
119757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1198f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (!args[1]->IsJSTypedArray())
1199d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
120057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1201f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
1202f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
1203f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
1204f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
120557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
120657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
1207a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  size_t offset = 0;
1208a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
120957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t target_length = NumberToSize(isolate, target->length());
121057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t source_length = NumberToSize(isolate, source->length());
121157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t target_byte_length = NumberToSize(isolate, target->byte_length());
121257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
121357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (offset > target_length ||
121457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      offset + source_length > target_length ||
121557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      offset + source_length < offset)  // overflow
121657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return isolate->Throw(*isolate->factory()->NewRangeError(
121757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
121857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
121957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t target_offset = NumberToSize(isolate, target->byte_offset());
122057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  size_t source_offset = NumberToSize(isolate, source->byte_offset());
122157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  uint8_t* target_base =
1222d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      static_cast<uint8_t*>(
1223895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        target->GetBuffer()->backing_store()) + target_offset;
122457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  uint8_t* source_base =
1225d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      static_cast<uint8_t*>(
1226895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        source->GetBuffer()->backing_store()) + source_offset;
122757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
122857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  // Typed arrays of the same type: use memmove.
122957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (target->type() == source->type()) {
123057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    memmove(target_base + offset * target->element_size(),
123157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        source_base, source_byte_length);
1232d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
123357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
123457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
123557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  // Typed arrays of different types over the same backing store
123657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if ((source_base <= target_base &&
123757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        source_base + source_byte_length > target_base) ||
123857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      (target_base <= source_base &&
123957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        target_base + target_byte_length > source_base)) {
1240d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // We do not support overlapping ArrayBuffers
1241d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    ASSERT(
1242895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      target->GetBuffer()->backing_store() ==
1243895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      source->GetBuffer()->backing_store());
1244d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
124557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  } else {  // Non-overlapping typed arrays
1246d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
124757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
124857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
124957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
125057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1251a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
12528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
12532f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  ASSERT_OBJECT_SIZE(
12542f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org      FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
1255895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
1256895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
1257895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
1258895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
1259a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DataViewInitialize) {
12601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
12611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 4);
12621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
12631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
1264f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
1265f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
12661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1267e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  ASSERT(holder->GetInternalFieldCount() ==
1268e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      v8::ArrayBufferView::kInternalFieldCount);
1269e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1270e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    holder->SetInternalField(i, Smi::FromInt(0));
1271e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
1272f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  size_t buffer_length = 0;
1273f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  size_t offset = 0;
1274f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  size_t length = 0;
1275f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(
1276f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
1277f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
1278f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
1279f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
1280f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
1281f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // Entire range [offset, offset + length] must be in bounds.
1282f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(offset <= buffer_length);
1283f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(offset + length <= buffer_length);
1284f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // No overflow.
1285f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(offset + length >= offset);
1286e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
12871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_buffer(*buffer);
12881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_byte_offset(*byte_offset);
12891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_byte_length(*byte_length);
12901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  holder->set_weak_next(buffer->weak_first_view());
12921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  buffer->set_weak_first_view(*holder);
12931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return isolate->heap()->undefined_value();
12951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
12961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline static bool NeedToFlipBytes(bool is_little_endian) {
12991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#ifdef V8_TARGET_LITTLE_ENDIAN
13001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return !is_little_endian;
13011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#else
13021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return is_little_endian;
13031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#endif
13041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
13051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<int n>
13081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline void CopyBytes(uint8_t* target, uint8_t* source) {
13091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (int i = 0; i < n; i++) {
13101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    *(target++) = *(source++);
13111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
13131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<int n>
13161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline void FlipBytes(uint8_t* target, uint8_t* source) {
13171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  source = source + (n-1);
13181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (int i = 0; i < n; i++) {
13191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    *(target++) = *(source--);
13201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
13221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<typename T>
13251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orginline static bool DataViewGetValue(
13261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Isolate* isolate,
13271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<JSDataView> data_view,
13281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Object> byte_offset_obj,
13291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    bool is_little_endian,
13301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T* result) {
1331af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  size_t byte_offset = 0;
1332af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1333af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return false;
1334af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
13351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
13361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_offset =
13381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_offset());
13391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_length =
13401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_length());
13411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (byte_offset + sizeof(T) > data_view_byte_length ||
13421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      byte_offset + sizeof(T) < byte_offset)  {  // overflow
13431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return false;
13441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  union Value {
13471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T data;
13481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    uint8_t bytes[sizeof(T)];
13491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  };
13501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Value value;
13521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t buffer_offset = data_view_byte_offset + byte_offset;
13531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(
13541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, buffer->byte_length())
13551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      >= buffer_offset + sizeof(T));
13561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  uint8_t* source =
13571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
13581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (NeedToFlipBytes(is_little_endian)) {
13591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    FlipBytes<sizeof(T)>(value.bytes, source);
13601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else {
13611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CopyBytes<sizeof(T)>(value.bytes, source);
13621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  *result = value.data;
13641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return true;
13651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
13661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<typename T>
13691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic bool DataViewSetValue(
13701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Isolate* isolate,
13711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<JSDataView> data_view,
13721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Object> byte_offset_obj,
13731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    bool is_little_endian,
13741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T data) {
1375af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  size_t byte_offset = 0;
1376af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1377af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return false;
1378af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
13791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
13801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_offset =
13821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_offset());
13831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t data_view_byte_length =
13841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, data_view->byte_length());
13851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (byte_offset + sizeof(T) > data_view_byte_length ||
13861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      byte_offset + sizeof(T) < byte_offset)  {  // overflow
13871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return false;
13881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  union Value {
13911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    T data;
13921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    uint8_t bytes[sizeof(T)];
13931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  };
13941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Value value;
13961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  value.data = data;
13971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size_t buffer_offset = data_view_byte_offset + byte_offset;
13981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(
13991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      NumberToSize(isolate, buffer->byte_length())
14001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      >= buffer_offset + sizeof(T));
14011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  uint8_t* target =
14021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
14031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (NeedToFlipBytes(is_little_endian)) {
14041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    FlipBytes<sizeof(T)>(target, value.bytes);
14051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else {
14061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CopyBytes<sizeof(T)>(target, value.bytes);
14071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
14081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return true;
14091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
14101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
14111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
14121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
1413874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                           \
14141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HandleScope scope(isolate);                                               \
14151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ASSERT(args.length() == 3);                                               \
14161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1417874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
14181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
14191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Type result;                                                              \
14201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (DataViewGetValue(                                                     \
14211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          isolate, holder, offset, is_little_endian, &result)) {              \
1422e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return *isolate->factory()->Converter(result);                          \
14231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else {                                                                  \
14241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->Throw(*isolate->factory()->NewRangeError(               \
14251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          "invalid_data_view_accessor_offset",                                \
14261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          HandleVector<Object>(NULL, 0)));                                    \
14271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }                                                                         \
14281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
14291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1430e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
1431e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
1432e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
1433e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
1434e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
1435e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
1436e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Float32, float, NewNumber)
1437e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgDATA_VIEW_GETTER(Float64, double, NewNumber)
14381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
14391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#undef DATA_VIEW_GETTER
14401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
144110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
144210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <typename T>
144310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgstatic T DataViewConvertValue(double value);
144410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
144510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
144610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
144710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgint8_t DataViewConvertValue<int8_t>(double value) {
144810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<int8_t>(DoubleToInt32(value));
144910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
145010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
145110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
145210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
145310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgint16_t DataViewConvertValue<int16_t>(double value) {
145410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<int16_t>(DoubleToInt32(value));
145510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
145610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
145710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
145810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
145910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgint32_t DataViewConvertValue<int32_t>(double value) {
146010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return DoubleToInt32(value);
146110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
146210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
146310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
146410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
146510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orguint8_t DataViewConvertValue<uint8_t>(double value) {
146610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<uint8_t>(DoubleToUint32(value));
146710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
146810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
146910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
147010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
147110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orguint16_t DataViewConvertValue<uint16_t>(double value) {
147210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<uint16_t>(DoubleToUint32(value));
147310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
147410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
147510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
147610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
147710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orguint32_t DataViewConvertValue<uint32_t>(double value) {
147810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return DoubleToUint32(value);
147910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
148010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
148110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
148210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
148310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgfloat DataViewConvertValue<float>(double value) {
148410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return static_cast<float>(value);
148510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
148610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
148710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
148810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgtemplate <>
148910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgdouble DataViewConvertValue<double>(double value) {
149010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  return value;
149110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}
149210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
149310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
14941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#define DATA_VIEW_SETTER(TypeName, Type)                                      \
1495874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                           \
14961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HandleScope scope(isolate);                                               \
14971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ASSERT(args.length() == 4);                                               \
14981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1499874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
1500874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org    CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                              \
15011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
150210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Type v = DataViewConvertValue<Type>(value->Number());                     \
15031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (DataViewSetValue(                                                     \
15041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          isolate, holder, offset, is_little_endian, v)) {                    \
15051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->heap()->undefined_value();                              \
15061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    } else {                                                                  \
15071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return isolate->Throw(*isolate->factory()->NewRangeError(               \
15081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          "invalid_data_view_accessor_offset",                                \
15091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          HandleVector<Object>(NULL, 0)));                                    \
15101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }                                                                         \
15111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
15121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
15131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Uint8, uint8_t)
15141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Int8, int8_t)
15151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Uint16, uint16_t)
15161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Int16, int16_t)
15171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Uint32, uint32_t)
15181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Int32, int32_t)
15191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Float32, float)
15201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDATA_VIEW_SETTER(Float64, double)
15211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
15221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#undef DATA_VIEW_SETTER
15231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
15241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1525a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetInitialize) {
1526394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1527394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
1528f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
15299e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
1530394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
1531394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *holder;
1532394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1533394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1534394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1535a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetAdd) {
1536394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1537394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1538f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
15398496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
15409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
15419e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  table = OrderedHashSet::Add(table, key);
1542394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
15435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
1544394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1545394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1546394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1547a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetHas) {
1548394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1549394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1550f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
15518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
15529e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
15533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return isolate->heap()->ToBoolean(table->Contains(key));
1554394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1555394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1556394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1557a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetDelete) {
1558394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1559394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1560f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
15618496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
15629e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
156379d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  bool was_present = false;
156479d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  table = OrderedHashSet::Remove(table, key, &was_present);
1565394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
156679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  return isolate->heap()->ToBoolean(was_present);
1567394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1568394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1569394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1570a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetClear) {
15714ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  HandleScope scope(isolate);
15724ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  ASSERT(args.length() == 1);
15734ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
15744ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
15754ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  table = OrderedHashSet::Clear(table);
15764ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  holder->set_table(*table);
15774ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  return isolate->heap()->undefined_value();
15784ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
15794ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
15804ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1581a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetGetSize) {
1582e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  HandleScope scope(isolate);
1583e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 1);
1584e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
15859e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1586e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return Smi::FromInt(table->NumberOfElements());
1587e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1588e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1589e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1590196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
15914ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  HandleScope scope(isolate);
1592196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(args.length() == 3);
1593196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1594196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
1595196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(kind, 2)
1596f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
1597f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                 kind == JSSetIterator::kKindEntries);
1598196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
1599196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  holder->set_table(*table);
1600196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  holder->set_index(Smi::FromInt(0));
1601196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  holder->set_kind(Smi::FromInt(kind));
1602196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return isolate->heap()->undefined_value();
16034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
16044ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
16054ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1606a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetIteratorNext) {
16074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  HandleScope scope(isolate);
16084ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  ASSERT(args.length() == 1);
16094ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1610a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  return *JSSetIterator::Next(holder);
16114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
16124ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
16134ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1614a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapInitialize) {
1615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1616394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
1617f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16189e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
1619394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*table);
1620394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *holder;
1621394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1622394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1623394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1624a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapGet) {
1625394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1626394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 2);
1627f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16287a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
16299e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
16303484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> lookup(table->Lookup(key), isolate);
16317a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
16327a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
16337a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
16347a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1635a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapHas) {
16367a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
16377a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
16387a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16397a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
16409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
16413484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> lookup(table->Lookup(key), isolate);
16427a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
16437a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
16447a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
16457a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1646a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapDelete) {
16477a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
16487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
16497a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16507a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
16519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1652196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  bool was_present = false;
16539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> new_table =
1654196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      OrderedHashMap::Remove(table, key, &was_present);
16557a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  holder->set_table(*new_table);
1656196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return isolate->heap()->ToBoolean(was_present);
1657394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1658394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1659394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1660a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapClear) {
16614ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  HandleScope scope(isolate);
16624ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  ASSERT(args.length() == 1);
16634ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16644ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
16654ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  table = OrderedHashMap::Clear(table);
16664ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  holder->set_table(*table);
16674ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  return isolate->heap()->undefined_value();
16684ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
16694ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
16704ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1671a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapSet) {
1672394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
1673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 3);
1674f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16757a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
16767a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
16779e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
16789e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
1679394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  holder->set_table(*new_table);
16805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
1681394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1682394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1683394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1684a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapGetSize) {
1685e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  HandleScope scope(isolate);
1686e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 1);
1687e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
16889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1689e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return Smi::FromInt(table->NumberOfElements());
1690e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1691e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1692e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1693196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
16944ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  HandleScope scope(isolate);
1695196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(args.length() == 3);
1696196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1697196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
1698196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(kind, 2)
1699a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
17004ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org      || kind == JSMapIterator::kKindValues
17014ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org      || kind == JSMapIterator::kKindEntries);
1702196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
1703196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  holder->set_table(*table);
1704196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  holder->set_index(Smi::FromInt(0));
1705196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  holder->set_kind(Smi::FromInt(kind));
1706196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return isolate->heap()->undefined_value();
17074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
17084ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
17094ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1710a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MapIteratorNext) {
17114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  HandleScope scope(isolate);
17124ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  ASSERT(args.length() == 1);
17134ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1714a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  return *JSMapIterator::Next(holder);
17154ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
17164ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
17174ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1718a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic Handle<JSWeakCollection> WeakCollectionInitialize(
1719a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    Isolate* isolate,
1720ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSWeakCollection> weak_collection) {
1721ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(weak_collection->map()->inobject_properties() == 0);
1722865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
1723ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_table(*table);
1724a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  return weak_collection;
17257c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
17267c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
17277c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1728a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
17292f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  HandleScope scope(isolate);
17302f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  ASSERT(args.length() == 1);
1731ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1732a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  return *WeakCollectionInitialize(isolate, weak_collection);
17332f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org}
17342f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org
17352f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org
1736a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
17377a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
17387a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
1739ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1740750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1741a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1742ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(
1743ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ObjectHashTable::cast(weak_collection->table()));
1744a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(table->IsKey(*key));
17453484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> lookup(table->Lookup(key), isolate);
17467a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
17477a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
17487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
17497a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1750a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
17517a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
17527c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 2);
1753ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1754750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1755a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1756ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(
1757ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ObjectHashTable::cast(weak_collection->table()));
1758a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(table->IsKey(*key));
17593484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> lookup(table->Lookup(key), isolate);
17607a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
17617a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org}
17627a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
17637a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org
1764a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
17657a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  HandleScope scope(isolate);
17667a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  ASSERT(args.length() == 2);
1767ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1768750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1769a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1770ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(ObjectHashTable::cast(
1771ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      weak_collection->table()));
1772a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(table->IsKey(*key));
1773196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  bool was_present = false;
17747a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  Handle<ObjectHashTable> new_table =
1775196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ObjectHashTable::Remove(table, key, &was_present);
1776ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_table(*new_table);
1777196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return isolate->heap()->ToBoolean(was_present);
17787c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
17797c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
17807c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1781a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
17827c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  HandleScope scope(isolate);
17837c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 3);
1784ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1785750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1786a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
17878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1788ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ObjectHashTable> table(
1789ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ObjectHashTable::cast(weak_collection->table()));
1790a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(table->IsKey(*key));
1791057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1792ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  weak_collection->set_table(*new_table);
17935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return isolate->heap()->undefined_value();
17947c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
17957c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
17967c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
1797a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ClassOf) {
179879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
179943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
18008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
1801ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!obj->IsJSObject()) return isolate->heap()->null_value();
180243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return JSObject::cast(obj)->class_name();
180343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
180443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
1806a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetPrototype) {
1807fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  HandleScope scope(isolate);
1808d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ASSERT(args.length() == 1);
1809fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
18104668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  // We don't expect access checks to be needed on JSProxy objects.
18114668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
18126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  do {
18134668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    if (obj->IsAccessCheckNeeded() &&
1814c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
1815c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                 isolate->factory()->proto_string(),
1816c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                 v8::ACCESS_GET)) {
1817c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
1818c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                       v8::ACCESS_GET);
18198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
18204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      return isolate->heap()->undefined_value();
18214668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    }
1822e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    obj = Object::GetPrototype(isolate, obj);
18236db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  } while (obj->IsJSObject() &&
1824fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org           JSObject::cast(*obj)->map()->is_hidden_prototype());
1825fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return *obj;
1826d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com}
1827d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
1828d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
1829e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
1830e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Isolate* isolate, Handle<Object> receiver) {
1831e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<Object> current = Object::GetPrototype(isolate, receiver);
1832e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  while (current->IsJSObject() &&
1833e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org         JSObject::cast(*current)->map()->is_hidden_prototype()) {
1834e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    current = Object::GetPrototype(isolate, current);
1835e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1836e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return current;
1837e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
1838e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1839e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1840a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetPrototype) {
1841c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HandleScope scope(isolate);
1842750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(args.length() == 2);
1843c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1844c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1845fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  if (obj->IsAccessCheckNeeded() &&
1846c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->MayNamedAccess(
1847c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
1848c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
18498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1850fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    return isolate->heap()->undefined_value();
1851fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  }
185297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (obj->map()->is_observed()) {
1853e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1854a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    Handle<Object> result;
1855a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1856a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        isolate, result,
1857a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        JSObject::SetPrototype(obj, prototype, true));
1858e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1859e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1860e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (!new_value->SameValue(*old_value)) {
1861e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      JSObject::EnqueueChangeRecord(obj, "setPrototype",
1862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                    isolate->factory()->proto_string(),
1863e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                    old_value);
1864e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
1865c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    return *result;
1866e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1867a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Handle<Object> result;
1868a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1869a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      isolate, result,
1870a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      JSObject::SetPrototype(obj, prototype, true));
1871c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  return *result;
1872750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
1873750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1874750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1875a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
1876e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope shs(isolate);
187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
187843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
18798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
18808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
188143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (true) {
1882e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> prototype = Object::GetPrototype(isolate, V);
1883ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (prototype->IsNull()) return isolate->heap()->false_value();
1884e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (*O == *prototype) return isolate->heap()->true_value();
188543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    V = prototype;
188643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
188943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic bool CheckAccessException(Object* callback,
18918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                 v8::AccessType access_type) {
1892fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  DisallowHeapAllocation no_gc;
18933484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  ASSERT(!callback->IsForeign());
18948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (callback->IsAccessorInfo()) {
18958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    AccessorInfo* info = AccessorInfo::cast(callback);
18968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return
18978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        (access_type == v8::ACCESS_HAS &&
18988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org           (info->all_can_read() || info->all_can_write())) ||
18998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        (access_type == v8::ACCESS_GET && info->all_can_read()) ||
19008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        (access_type == v8::ACCESS_SET && info->all_can_write());
19018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
19021e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (callback->IsAccessorPair()) {
19031e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    AccessorPair* info = AccessorPair::cast(callback);
19041e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    return
19051e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org        (access_type == v8::ACCESS_HAS &&
19061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org           (info->all_can_read() || info->all_can_write())) ||
19071e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org        (access_type == v8::ACCESS_GET && info->all_can_read()) ||
19081e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org        (access_type == v8::ACCESS_SET && info->all_can_write());
19091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  }
19108e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return false;
19118e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
19120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1913753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
19148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgtemplate<class Key>
19158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic bool CheckGenericAccess(
1916fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    Handle<JSObject> receiver,
1917fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    Handle<JSObject> holder,
19188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Key key,
19198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    v8::AccessType access_type,
1920fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
19218e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Isolate* isolate = receiver->GetIsolate();
1922fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  for (Handle<JSObject> current = receiver;
19238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org       true;
1924fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org       current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
19258e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (current->IsAccessCheckNeeded() &&
19268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        !(isolate->*mayAccess)(current, key, access_type)) {
19278e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      return false;
19288e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
1929fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (current.is_identical_to(holder)) break;
19308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
19318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return true;
19320c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
19330c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
19340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
19358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgenum AccessCheckResult {
19368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ACCESS_FORBIDDEN,
19378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ACCESS_ALLOWED,
19388e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ACCESS_ABSENT
19398e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org};
19408e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
19418e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
1942fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgstatic AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
1943fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                             Handle<Name> name,
1944fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                             v8::AccessType access_type) {
19458e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  uint32_t index;
19468e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (name->AsArrayIndex(&index)) {
1947169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // TODO(1095): we should traverse hidden prototype hierachy as well.
1948169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (CheckGenericAccess(
1949c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org            obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
1950169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      return ACCESS_ALLOWED;
1951169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
1952169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1953c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1954169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return ACCESS_FORBIDDEN;
19558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
1956fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1957fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Isolate* isolate = obj->GetIsolate();
1958fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  LookupResult lookup(isolate);
1959fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  obj->LookupOwn(name, &lookup, true);
1960fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
19618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (!lookup.IsProperty()) return ACCESS_ABSENT;
1962fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Handle<JSObject> holder(lookup.holder(), isolate);
1963fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  if (CheckGenericAccess<Handle<Object> >(
1964c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
19658e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return ACCESS_ALLOWED;
196683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
196783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
19688e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Access check callback denied the access, but some properties
19698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // can have a special permissions which override callbacks descision
19708e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // (currently see v8::AccessControl).
197183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // API callbacks can have per callback access exceptions.
19728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  switch (lookup.type()) {
19738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case CALLBACKS:
19748e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
19758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        return ACCESS_ALLOWED;
197683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
197783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      break;
19788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case INTERCEPTOR:
197983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      // If the object has an interceptor, try real named properties.
198083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      // Overwrite the result to fetch the correct property later.
19813484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      holder->LookupRealNamedProperty(name, &lookup);
19828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
19838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
19848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          return ACCESS_ALLOWED;
198583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        }
198683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      }
198783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      break;
198883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    default:
198983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      break;
199083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
199183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
1992c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  isolate->ReportFailedAccessCheck(obj, access_type);
19938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return ACCESS_FORBIDDEN;
1994f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org}
1995f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
1996f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
199730ce411529579186181838984710b0b0980857aaricow@chromium.org// Enumerator used as indices into the array returned from GetOwnProperty
199830ce411529579186181838984710b0b0980857aaricow@chromium.orgenum PropertyDescriptorIndices {
199930ce411529579186181838984710b0b0980857aaricow@chromium.org  IS_ACCESSOR_INDEX,
200030ce411529579186181838984710b0b0980857aaricow@chromium.org  VALUE_INDEX,
200130ce411529579186181838984710b0b0980857aaricow@chromium.org  GETTER_INDEX,
200230ce411529579186181838984710b0b0980857aaricow@chromium.org  SETTER_INDEX,
200330ce411529579186181838984710b0b0980857aaricow@chromium.org  WRITABLE_INDEX,
200430ce411529579186181838984710b0b0980857aaricow@chromium.org  ENUMERABLE_INDEX,
200530ce411529579186181838984710b0b0980857aaricow@chromium.org  CONFIGURABLE_INDEX,
200630ce411529579186181838984710b0b0980857aaricow@chromium.org  DESCRIPTOR_SIZE
200730ce411529579186181838984710b0b0980857aaricow@chromium.org};
200830ce411529579186181838984710b0b0980857aaricow@chromium.org
2009bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
20102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
20112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                          Handle<JSObject> obj,
20122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                          Handle<Name> name) {
2013ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
2014fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Factory* factory = isolate->factory();
20158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Due to some WebKit tests, we want to make sure that we do not log
20168e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // more than one access failure here.
2017169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  AccessCheckResult access_check_result =
2018fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
20192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2020169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  switch (access_check_result) {
2021fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    case ACCESS_FORBIDDEN: return factory->false_value();
20228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case ACCESS_ALLOWED: break;
2023fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    case ACCESS_ABSENT: return factory->undefined_value();
2024f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org  }
2025f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
20261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name);
2027169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (attrs == ABSENT) {
20282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2029fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    return factory->undefined_value();
2030169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
2031169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!isolate->has_scheduled_exception());
203249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  Handle<AccessorPair> accessors;
203349ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  bool has_accessors =
2034fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors);
20358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
20368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
20378e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
203849ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
20398e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
204049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  if (!has_accessors) {
20418e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
20422f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    // Runtime::GetObjectProperty does access check.
2043202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> value;
2044202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
2045202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
2046202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Object);
20478e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    elms->set(VALUE_INDEX, *value);
20488e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  } else {
20498e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // Access checks are performed for both accessors separately.
20508e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // When they fail, the respective field is not set in the descriptor.
2051fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
2052fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
2053fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
2054fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) {
2055169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      ASSERT(!isolate->has_scheduled_exception());
2056fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      elms->set(GETTER_INDEX, *getter);
2057169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
2058202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
205983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
2060fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
2061fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
2062169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      ASSERT(!isolate->has_scheduled_exception());
2063fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      elms->set(SETTER_INDEX, *setter);
2064169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
2065202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
206683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
20670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
20680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2069fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return isolate->factory()->NewJSArrayWithElements(elms);
20700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
20710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
20720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2073bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com// Returns an array with the property description:
2074bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//  if args[1] is not a property on args[0]
2075bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//          returns undefined
2076bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//  if args[1] is a data property on args[0]
2077bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//         [false, value, Writeable, Enumerable, Configurable]
2078bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//  if args[1] is an accessor on args[0]
2079bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com//         [true, GetFunction, SetFunction, Enumerable, Configurable]
2080a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetOwnProperty) {
2081bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  HandleScope scope(isolate);
20826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 2);
2083bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2084750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
2085202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> result;
2086202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2087202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, result, GetOwnProperty(isolate, obj, name));
2088fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return *result;
2089bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
2090bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
2091bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
2092a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_PreventExtensions) {
2093528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
209469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  ASSERT(args.length() == 1);
2095528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
20968496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Object> result;
20978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
20988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result, JSObject::PreventExtensions(obj));
2099528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return *result;
210069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
210169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
2102d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
2103a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsExtensible) {
210479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2105b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
2106f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj, 0);
2107d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  if (obj->IsJSGlobalProxy()) {
2108d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    Object* proto = obj->GetPrototype();
2109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (proto->IsNull()) return isolate->heap()->false_value();
2110d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    ASSERT(proto->IsJSGlobalObject());
2111d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    obj = JSObject::cast(proto);
2112d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  }
21137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
2114b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
2115b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2116b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
2117a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RegExpCompile) {
2118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
211943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
2120f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
2121f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
2122f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
21238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Object> result;
21248496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
21258496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result, RegExpImpl::Compile(re, pattern, flags));
21263bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  return *result;
212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
212943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2130a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateApiFunction) {
2131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2132a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ASSERT(args.length() == 2);
2133f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
2134a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
2135a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return *isolate->factory()->CreateApiFunction(data, prototype);
213643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
213743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
213843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2139a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsTemplate) {
214079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
214143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
21428496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
21439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
2144ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->ToBoolean(result);
214543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
214643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
214743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2148a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetTemplateField) {
214979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
215043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
2151f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(HeapObject, templ, 0);
21528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 1);
21539bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  int offset = index * kPointerSize + HeapObject::kHeaderSize;
21549bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  InstanceType type = templ->map()->instance_type();
21552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
21562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                 type == OBJECT_TEMPLATE_INFO_TYPE);
21579bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  RUNTIME_ASSERT(offset > 0);
21589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
21599bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
21609bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  } else {
21619bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
21629bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
21639bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  return *HeapObject::RawField(templ, offset);
216443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
216543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
216643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2167a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
2168ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  HandleScope scope(isolate);
2169870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT(args.length() == 1);
2170ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2171ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<Map> old_map(object->map());
21723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  bool needs_access_checks = old_map->is_access_check_needed();
21733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  if (needs_access_checks) {
21743291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    // Copy map so it won't interfere constructor's initial map.
2175ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    Handle<Map> new_map = Map::Copy(old_map);
2176753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    new_map->set_is_access_check_needed(false);
2177ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    if (object->IsJSObject()) {
2178ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2179ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    } else {
2180ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      object->set_map(*new_map);
2181ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    }
21823291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
21837c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(needs_access_checks);
2184870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
2185870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
2186870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
2187a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
2188ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  HandleScope scope(isolate);
2189870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT(args.length() == 1);
2190ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2191ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<Map> old_map(object->map());
21923291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  if (!old_map->is_access_check_needed()) {
21933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    // Copy map so it won't interfere constructor's initial map.
2194ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    Handle<Map> new_map = Map::Copy(old_map);
2195753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    new_map->set_is_access_check_needed(true);
2196ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    if (object->IsJSObject()) {
2197ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2198ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    } else {
2199ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      object->set_map(*new_map);
2200ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    }
22013291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
2202ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
2203870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
2204870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
2205870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
22061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// Transform getter or setter into something DefineAccessor can handle.
22071e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgstatic Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
22081e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                                   Handle<Object> component) {
22091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (component->IsUndefined()) return isolate->factory()->null_value();
22101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  Handle<FunctionTemplateInfo> info =
22111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      Handle<FunctionTemplateInfo>::cast(component);
22121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
22131e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org}
22141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
22151e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
2216a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
22171e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  HandleScope scope(isolate);
22181e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  ASSERT(args.length() == 6);
22191e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
22201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
22211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
22221e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
22231e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(attribute, 4);
22241e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(access_control, 5);
2225895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
2226895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
2227a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
2228a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      static_cast<PropertyAttributes>(attribute)));
22291e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  JSObject::DefineAccessor(object,
22301e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                           name,
22311e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                           InstantiateAccessorComponent(isolate, getter),
22321e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                           InstantiateAccessorComponent(isolate, setter),
22331e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                           static_cast<PropertyAttributes>(attribute),
22341e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                           static_cast<v8::AccessControl>(access_control));
22351e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  return isolate->heap()->undefined_value();
22361e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org}
22371e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
22381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
2239a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
2240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
22414edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  Handle<Object> args[1] = { name };
22424edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  Handle<Object> error = isolate->factory()->NewTypeError(
22434edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org      "var_redeclaration", HandleVector(args, 1));
2244ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->Throw(*error);
224543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
224643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
224743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2248a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_DeclareGlobals) {
2249ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
22506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 3);
2251ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<GlobalObject> global = Handle<GlobalObject>(
225246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->context()->global_object());
225343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
2255f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
22561805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 2);
225743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the name/value pairs and set the properties.
225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = pairs->length();
226043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < length; i += 2) {
2261ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<String> name(String::cast(pairs->get(i)));
2263ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> value(pairs->get(i + 1), isolate);
226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // We have to declare a global const property. To capture we only
226643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // assign to it when evaluating the assignment for "const x =
226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // <expr>" the initial value is the hole.
2268ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_var = value->IsUndefined();
2269ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_const = value->IsTheHole();
2270ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_function = value->IsSharedFunctionInfo();
22718e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    ASSERT(is_var + is_const + is_function == 1);
2272ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
2273ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (is_var || is_const) {
227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Lookup the property in the global object, and don't set the
227543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // value of the variable if the property is already there.
2276fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      // Do the lookup own properties only, see ES5 erratum.
2277394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate);
2278fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      global->LookupOwn(name, &lookup, true);
2279753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      if (lookup.IsFound()) {
2280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // We found an existing property. Unless it was an interceptor
2281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // that claims the property is absent, skip this declaration.
2282de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org        if (!lookup.IsInterceptor()) continue;
22831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        if (JSReceiver::GetPropertyAttributes(global, name) != ABSENT) continue;
2284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Fall-through and introduce the absent property by using
2285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // SetProperty.
228643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
2287ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    } else if (is_function) {
228843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Copy the function and update its context. Use it as value.
22895d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org      Handle<SharedFunctionInfo> shared =
22905d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org          Handle<SharedFunctionInfo>::cast(value);
229143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<JSFunction> function =
2292ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          isolate->factory()->NewFunctionFromSharedFunctionInfo(
2293ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              shared, context, TENURED);
229443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      value = function;
229543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
229643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    LookupResult lookup(isolate);
2298fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    global->LookupOwn(name, &lookup, true);
229943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2300ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // Compute the property attributes. According to ECMA-262,
2301ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // the property must be non-configurable except in eval.
23021805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    int attr = NONE;
2303ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
23048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!is_eval) {
23051805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      attr |= DONT_DELETE;
23061805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
2307394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    bool is_native = DeclareGlobalsNativeFlag::decode(flags);
23088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (is_const || (is_native && is_function)) {
23091805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      attr |= READ_ONLY;
23101805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    }
23111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
2312486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
23132c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
23148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!lookup.IsFound() || is_function) {
2315fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      // If the own property exists, check that we can reconfigure it
2316ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // as required for function declarations.
2317753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      if (lookup.IsFound() && lookup.IsDontDelete()) {
2318ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
231999aa490225c81012235659d9a183226b286178c8yangguo@chromium.org            lookup.IsPropertyCallbacks()) {
23204edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org          return ThrowRedeclarationError(isolate, name);
23212c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org        }
2322ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        // If the existing property is not configurable, keep its attributes.
2323ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        attr = lookup.GetAttributes();
23249ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      }
2325ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Define or redefine own property.
23268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_ON_EXCEPTION(isolate,
2327fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org          JSObject::SetOwnPropertyIgnoreAttributes(
2328ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              global, name, value, static_cast<PropertyAttributes>(attr)));
232943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
2330ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Do a [[Put]] on the existing (own) property.
23318f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      RETURN_FAILURE_ON_EXCEPTION(
23328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          isolate,
2333ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          JSObject::SetProperty(
2334ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com              global, name, value, static_cast<PropertyAttributes>(attr),
2335486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org              strict_mode));
233643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
233743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
23387c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
2339ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(!isolate->has_pending_exception());
2340ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
234143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
234243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
234343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2344a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_DeclareContextSlot) {
2345ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
23467c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  ASSERT(args.length() == 4);
234743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
234846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Declarations are always made in a function or native context.  In the
2349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // case of eval code, the context passed is the context of the caller,
2350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // which may be some nested context and not the declaration context.
23518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
23528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Context> context(context_arg->declaration_context());
23538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
23548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
23558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
2356c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
23578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
235843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
235943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
236043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
236143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
236280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
23635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Handle<Object> holder =
236480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org      context->Lookup(name, flags, &index, &attributes, &binding_flags);
236543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
236643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (attributes != ABSENT) {
2367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The name was declared before; check for conflicting re-declarations.
2368ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // Note: this is actually inconsistent with what happens for globals (where
2369ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    // we silently ignore such declarations).
237043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
237143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Functions are not read-only.
237243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
23734edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org      return ThrowRedeclarationError(isolate, name);
237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
237543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
237643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Initialize it if necessary.
237743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (*initial_value != NULL) {
237843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (index >= 0) {
2379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(holder.is_identical_to(context));
2380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (((attributes & READ_ONLY) == 0) ||
2381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            context->get(index)->IsTheHole()) {
2382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          context->set(index, *initial_value);
238343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
238443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
2385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Slow case: The property is in the context extension object of a
238646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        // function context or the global object of a native context.
2387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Handle<JSObject> object = Handle<JSObject>::cast(holder);
23888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        RETURN_FAILURE_ON_EXCEPTION(
2389ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            isolate,
2390486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
239343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
239443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
23957c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // The property is not in the function context. It needs to be
2396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // "declared" in the function context's extension context or as a
2397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // property of the the global object.
2398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<JSObject> object;
23999fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    if (context->has_extension()) {
2400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object = Handle<JSObject>(JSObject::cast(context->extension()));
24017c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    } else {
2402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Context extension objects are allocated lazily.
2403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(context->IsFunctionContext());
2404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object = isolate->factory()->NewJSObject(
2405ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->context_extension_function());
2406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      context->set_extension(*object);
24077c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    }
2408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(*object != NULL);
24097c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
24107c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // Declare the property by setting it to the initial value if provided,
24117c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
24127c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // constant declarations).
2413fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    ASSERT(!JSReceiver::HasOwnProperty(object, name));
2414ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> value(isolate->heap()->undefined_value(), isolate);
24157c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    if (*initial_value != NULL) value = initial_value;
24163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Declaring a const context slot is a conflicting declaration if
24173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // there is a callback with that name in a prototype. It is
24183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // allowed to introduce const variables in
24193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // JSContextExtensionObjects. They are treated specially in
24203a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // SetProperty and no setters are invoked for those since they are
24213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // not real JSObjects.
24223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    if (initial_value->IsTheHole() &&
2423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        !object->IsJSContextExtensionObject()) {
2424394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate);
24253484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      object->Lookup(name, &lookup);
2426753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      if (lookup.IsPropertyCallbacks()) {
24274edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org        return ThrowRedeclarationError(isolate, name);
24283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      }
24293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
2430ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    if (object->IsJSGlobalObject()) {
2431ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Define own property on the global object.
24328496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_ON_EXCEPTION(isolate,
2433fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org         JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, mode));
2434ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    } else {
24358f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      RETURN_FAILURE_ON_EXCEPTION(isolate,
2436486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org         JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
2437ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
24387c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
24397c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
2440ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
244143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
244243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
244343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2444a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
2445528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
24469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // args[0] == name
24471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // args[1] == language_mode
24489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // args[2] == value (optional)
244943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Determine if we need to assign to the variable if it already
245143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // exists (based on the number of arguments).
24529ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
24539ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  bool assign = args.length() == 3;
245443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2455f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2456486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
245743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
245843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // According to ECMA-262, section 12.2, page 62, the property must
245943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not be deletable.
246043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes = DONT_DELETE;
246143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2462fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // Lookup the property as own on the global object. If it isn't
24632abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // there, there is a property with this name in the prototype chain.
24642abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  // We follow Safari and Firefox behavior and only set the property
2465fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // if there is an explicit initialization value that we have
24663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // to assign to the property.
2467ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Note that objects can have hidden prototypes, so we need to traverse
2468fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // the whole chain of hidden prototypes to do an 'own' lookup.
2469394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult lookup(isolate);
2470fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  isolate->context()->global_object()->LookupOwn(name, &lookup, true);
24718e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (lookup.IsInterceptor()) {
2472381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    Handle<JSObject> holder(lookup.holder());
24738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    PropertyAttributes intercepted =
24741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        JSReceiver::GetPropertyAttributes(holder, name);
24758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
24768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      // Found an interceptor that's not read only.
24778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (assign) {
2478528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
24798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        Handle<Object> result;
24808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
24818f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            isolate, result,
24828f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            JSObject::SetPropertyForResult(
24838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                holder, &lookup, name, value, attributes, strict_mode));
2484528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        return *result;
24858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      } else {
24868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        return isolate->heap()->undefined_value();
2487ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org      }
24882abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    }
248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
249043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24919ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  if (assign) {
2492528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2493528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<GlobalObject> global(isolate->context()->global_object());
24948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Object> result;
24958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
24968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        isolate, result,
24978f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
2498528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return *result;
24999ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
2500ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
250143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
250243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
250343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2504a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_InitializeConstGlobal) {
250579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
250643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // All constants are declared with an initial value. The name
250743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of the constant is the first argument and the initial value
250843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is the second.
250943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(args.length() == 2);
2510f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
25118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
251243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
251343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the current global object from top.
251446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  GlobalObject* global = isolate->context()->global_object();
251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
251643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // According to ECMA-262, section 12.2, page 62, the property must
251743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // not be deletable. Since it's a const, it must be READ_ONLY too.
251843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes =
251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
252043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2521fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // Lookup the property as own on the global object. If it isn't
252243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // there, we add the property and take special precautions to always
2523fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // add it even in case of callbacks in the prototype chain (this rules
2524fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // out using SetProperty). We use SetOwnPropertyIgnoreAttributes instead
2525394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult lookup(isolate);
2526fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  global->LookupOwn(name, &lookup);
2527753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (!lookup.IsFound()) {
25284a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    HandleScope handle_scope(isolate);
25294a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    Handle<GlobalObject> global(isolate->context()->global_object());
25308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(
25314a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        isolate,
2532fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        JSObject::SetOwnPropertyIgnoreAttributes(global, name, value,
2533fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                                 attributes));
25344a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    return *value;
253543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
253643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
253743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!lookup.IsReadOnly()) {
253843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Restore global object from context (in case of GC) and continue
2539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // with setting the value.
2540ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope handle_scope(isolate);
254146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Handle<GlobalObject> global(isolate->context()->global_object());
254243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2543496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // BUG 1213575: Handle the case where we have to set a read-only
254443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // property through an interceptor and only do it if it's
254543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // uninitialized, e.g. the hole. Nirk...
2546486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // Passing sloppy mode because the property is writable.
25478f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(
2548f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        isolate,
2549486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
255043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
255143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
255243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Set the value, but only if we're assigning the initial value to a
255443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // constant. For now, we determine this by checking if the
255543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // current value is the hole.
2556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Strict mode handling not needed (const is disallowed in strict mode).
2557de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  if (lookup.IsField()) {
255843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    FixedArray* properties = global->properties();
2559e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    int index = lookup.GetFieldIndex().outobject_array_index();
2560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
256143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      properties->set(index, *value);
256243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
2563de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  } else if (lookup.IsNormal()) {
2564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
2565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        !lookup.IsReadOnly()) {
2566e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      HandleScope scope(isolate);
2567e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
256843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
256943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
257043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Ignore re-initialization of constants that have already been
2571fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // assigned a constant value.
2572fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
257343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
257443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
257543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Use the set value as the result of the operation.
257643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
257743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
257843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
257943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2580a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_InitializeConstContextSlot) {
2581ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
258243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
258343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
258543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(!value->IsTheHole());
258646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Initializations are always done in a function or native context.
25878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
25888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Context> context(context_arg->declaration_context());
25898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
259043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
259143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
2593ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  ContextLookupFlags flags = FOLLOW_CHAINS;
259480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
25955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Handle<Object> holder =
259680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org      context->Lookup(name, flags, &index, &attributes, &binding_flags);
259743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
259843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= 0) {
2599c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(holder->IsContext());
2600c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Property was found in a context.  Perform the assignment if we
2601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // found some non-constant or an uninitialized constant.
2602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<Context> context = Handle<Context>::cast(holder);
2603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
2604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      context->set(index, *value);
260543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
260643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
260743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
260843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The property could not be found, we introduce it as a property of the
2610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // global object.
2611ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  if (attributes == ABSENT) {
2612ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<JSObject> global = Handle<JSObject>(
261346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->context()->global_object());
26149ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Strict mode not needed (const disallowed in strict mode).
26158f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(
2616ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
2617486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
2618ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    return *value;
2619ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
262043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The property was present in some function's context extension object,
2622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // as a property on the subject of a with, or as a property of the global
2623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object.
2624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // In most situations, eval-introduced consts should still be present in
2626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the context extension object.  However, because declaration and
2627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // initialization are separate, the property might have been deleted
2628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // before we reach the initialization point.
2629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Example:
2631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //    function f() { eval("delete x; const x;"); }
2633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //
2634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // In that case, the initialization behaves like a normal assignment.
2635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<JSObject> object = Handle<JSObject>::cast(holder);
263643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (*object == context->extension()) {
2638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // This is the property that was introduced by the const declaration.
2639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Set it if it hasn't been set before.  NOTE: We cannot use
2640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // GetProperty() to get the current value as it 'unholes' the value.
2641394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    LookupResult lookup(isolate);
2642fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    object->LookupOwnRealNamedProperty(name, &lookup);
264305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    ASSERT(lookup.IsFound());  // the property was declared
2644ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
2645ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
2646de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    if (lookup.IsField()) {
2647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FixedArray* properties = object->properties();
2648e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      FieldIndex index = lookup.GetFieldIndex();
2649e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      ASSERT(!index.is_inobject());
2650e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if (properties->get(index.outobject_array_index())->IsTheHole()) {
2651e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        properties->set(index.outobject_array_index(), *value);
2652ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
2653de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    } else if (lookup.IsNormal()) {
2654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
2655e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        JSObject::SetNormalizedProperty(object, &lookup, value);
2656ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
2657ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    } else {
2658ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      // We should not reach here. Any real, named property should be
2659ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      // either a field or a dictionary slot.
2660ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      UNREACHABLE();
266143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
266243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
2663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The property was found on some other object.  Set it if it is not a
2664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // read-only property.
2665ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    if ((attributes & READ_ONLY) == 0) {
26669ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      // Strict mode not needed (const disallowed in strict mode).
26678f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      RETURN_FAILURE_ON_EXCEPTION(
2668ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate,
2669486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
2670ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
267143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
2672ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
267343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
267443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
267543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
267643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2677a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
2678ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2679911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  ASSERT(args.length() == 2);
2680f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
26816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(properties, 1);
2682a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // Conservative upper limit to prevent fuzz tests from going OOM.
2683a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(properties <= 100000);
2684f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
2685f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
2686911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  }
2687911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  return *object;
2688911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org}
2689911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
2690911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
2691a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_RegExpExec) {
2692ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
26937be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  ASSERT(args.length() == 4);
2694f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2695f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
269668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // Due to the way the JS calls are constructed this must be less than the
26977be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // length of a string, i.e. it is always a Smi.  We check anyway for security.
26986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 2);
2699f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
270068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  RUNTIME_ASSERT(index >= 0);
270168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  RUNTIME_ASSERT(index <= subject->length());
2702ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->regexp_entry_runtime()->Increment();
2703a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Handle<Object> result;
2704a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2705a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      isolate, result,
2706a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      RegExpImpl::Exec(regexp, subject, index, last_match_info));
2707a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return *result;
270843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
270943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
271043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2711a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_RegExpConstructResult) {
27129e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  HandleScope handle_scope(isolate);
2713b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  ASSERT(args.length() == 3);
27149e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(size, 0);
27159e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
27168496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
27178496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
27189e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
27199e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
27209e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<JSObject> object =
27219e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
27229e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(object);
27239e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  array->set_elements(*elements);
27249e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  array->set_length(Smi::FromInt(size));
2725b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // Write in-object properties after the length of the array.
27268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
27278496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
27289e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return *array;
2729b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
2730b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2731b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2732a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
27334a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  HandleScope scope(isolate);
273425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(args.length() == 5);
27354a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
27364a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2737efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  // If source is the empty string we set it to "(?:)" instead as
2738efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org  // suggested by ECMA-262, 5th, section 15.10.4.1.
27394a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (source->length() == 0) source = isolate->factory()->query_colon_string();
274025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
27414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
27424a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (!global->IsTrue()) global = isolate->factory()->false_value();
274325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
27444a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
27454a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
274625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
27474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
27484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
274925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
275025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Map* map = regexp->map();
275125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Object* constructor = map->constructor();
275225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  if (constructor->IsJSFunction() &&
275325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      JSFunction::cast(constructor)->initial_map() == map) {
275425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // If we still have the original map, set in-object properties directly.
27554a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
27560ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // Both true and false are immovable immortal objects so no need for write
27570ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // barrier.
27580ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    regexp->InObjectPropertyAtPut(
27594a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
27600ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    regexp->InObjectPropertyAtPut(
27614a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
27620ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    regexp->InObjectPropertyAtPut(
27634a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
27646bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org    regexp->InObjectPropertyAtPut(
27656bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org        JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
27664a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    return *regexp;
276725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
276825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
2769ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Map has changed, so use generic, but slower, method.
277025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  PropertyAttributes final =
277125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
277225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  PropertyAttributes writable =
277325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
27744a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Handle<Object> zero(Smi::FromInt(0), isolate);
27754a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Factory* factory = isolate->factory();
2776fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  JSObject::SetOwnPropertyIgnoreAttributes(
27778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      regexp, factory->source_string(), source, final).Check();
2778fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  JSObject::SetOwnPropertyIgnoreAttributes(
27798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      regexp, factory->global_string(), global, final).Check();
2780fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  JSObject::SetOwnPropertyIgnoreAttributes(
27818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      regexp, factory->ignore_case_string(), ignoreCase, final).Check();
2782fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  JSObject::SetOwnPropertyIgnoreAttributes(
27838496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      regexp, factory->multiline_string(), multiline, final).Check();
2784fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  JSObject::SetOwnPropertyIgnoreAttributes(
27858496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      regexp, factory->last_index_string(), zero, writable).Check();
27864a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  return *regexp;
278725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
278825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
278925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
2790a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
2791ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2792ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 1);
2793f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
27943484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Object* length = prototype->length();
27953484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
27963484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
2797ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // This is necessary to enable fast checks for absence of elements
2798ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // on Array.prototype and below.
2799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  prototype->set_elements(isolate->heap()->empty_fixed_array());
2800ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return Smi::FromInt(0);
2801ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
2802ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2803ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2804a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgstatic void InstallBuiltin(Isolate* isolate,
2805a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                           Handle<JSObject> holder,
2806a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                           const char* name,
2807a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                           Builtins::Name builtin_name) {
28084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
2809ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Code> code(isolate->builtins()->builtin(builtin_name));
2810ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSFunction> optimized =
28113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      isolate->factory()->NewFunctionWithoutPrototype(key, code);
2812f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  optimized->shared()->DontAdaptArguments();
28138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT).Assert();
2814f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
2815f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2816f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2817a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
2818ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
2819a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  ASSERT(args.length() == 0);
2820a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  Handle<JSObject> holder =
2821a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
2822f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
28237979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
28247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
28257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
28267979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
28277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
28287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
28297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
2830f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2831f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  return *holder;
2832f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
2833f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2834f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
2835a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
283679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2837e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(args.length() == 1);
2838e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2839e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!callable->IsJSFunction()) {
2840e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    HandleScope scope(isolate);
28412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> delegate;
28422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
28432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, delegate,
28442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Execution::TryGetFunctionDelegate(
28452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            isolate, Handle<JSReceiver>(callable)));
2846e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    callable = JSFunction::cast(*delegate);
2847e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
2848e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JSFunction* function = JSFunction::cast(callable);
2849e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  SharedFunctionInfo* shared = function->shared();
2850486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
2851e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
2852e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2853e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2854a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
285579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
28564668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  ASSERT(args.length() == 1);
2857f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
285805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
285905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (!callable->IsJSFunction()) {
286005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    HandleScope scope(isolate);
28612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> delegate;
28622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
28632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, delegate,
28642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Execution::TryGetFunctionDelegate(
28652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            isolate, Handle<JSReceiver>(callable)));
286605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    callable = JSFunction::cast(*delegate);
286705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
286805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  JSFunction* function = JSFunction::cast(callable);
286905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
28704668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  SharedFunctionInfo* shared = function->shared();
2871486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (shared->native() || shared->strict_mode() == STRICT) {
28724668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    return isolate->heap()->undefined_value();
28734668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  }
28744668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  // Returns undefined for strict or native functions, or
28754668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  // the associated global receiver for "normal" functions.
28764668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
287746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* native_context =
287846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      function->context()->global_object()->native_context();
287946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return native_context->global_object()->global_receiver();
2880357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
2881357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
2882357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
2883a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_MaterializeRegExpLiteral) {
2884ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
288543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 4);
2886f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
28878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 1);
28888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
28898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
289043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
289141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Get the RegExp function from the context in the literals array.
289241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // This is the RegExp function from the context in which the
289341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // function was created.  We do not use the RegExp function from the
289446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // current native context because this might be the RegExp function
289541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // from another context which we should not have access to.
28969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<JSFunction> constructor =
2897236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      Handle<JSFunction>(
289846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
289943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the regular expression literal.
29002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> regexp;
29012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
29022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, regexp,
29032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  literals->set(index, *regexp);
290543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *regexp;
290643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
290843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2909a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionGetName) {
291079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
291143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2913f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
291443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return f->shared()->name();
291543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
291643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
291743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2918a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionSetName) {
291979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
2920236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  ASSERT(args.length() == 2);
2921236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
2922f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
2923f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, name, 1);
2924236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  f->shared()->set_name(name);
2925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
2926236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
2927236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
2928236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
2929a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
293079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
29317c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 1);
2932f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
29337c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(
29347c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      f->shared()->name_should_print_as_anonymous());
29357c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
29367c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
29377c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
2938a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
293979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
29407c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  ASSERT(args.length() == 1);
2941f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
29427c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  f->shared()->set_name_should_print_as_anonymous(true);
29437c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->undefined_value();
29447c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
29457c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
29467c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
2947a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
294879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
294957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ASSERT(args.length() == 1);
295057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
295157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  return isolate->heap()->ToBoolean(f->shared()->is_generator());
295257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
295357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
295457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
2955a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
295679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
29574111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  ASSERT(args.length() == 1);
29584111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
2959f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
2960a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(f->RemovePrototype());
29614111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
2962ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
29634111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
29644111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
29654111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
2966a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionGetScript) {
2967ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
296843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
296943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2970f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2971ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
2972ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!script->IsScript()) return isolate->heap()->undefined_value();
297343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return *Script::GetWrapper(Handle<Script>::cast(script));
297543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
297643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
297743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2978a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
297978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  HandleScope scope(isolate);
298043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
298143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2982f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
298378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  Handle<SharedFunctionInfo> shared(f->shared());
298478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  return *shared->GetSourceCode();
298543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
298643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
298743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2988a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
298979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
299043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
299143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2992f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
299343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos = fun->shared()->start_position();
299443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(pos);
299543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
299643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
299743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2998a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
299979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
30002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ASSERT(args.length() == 2);
30012abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
3002f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(Code, code, 0);
30032abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
30042abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
30052abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  RUNTIME_ASSERT(0 <= offset && offset < code->Size());
30062abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
30072abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  Address pc = code->address() + offset;
3008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return Smi::FromInt(code->SourcePosition(pc));
30092abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
30102abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
30112abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
3012a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
301379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
301443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
301543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3016f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
3017f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, name, 1);
301843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  fun->SetInstanceClassName(name);
3019ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
302043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
302143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
302243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3023a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionSetLength) {
302479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
302543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
302643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3027f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
3028f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(length, 1);
3029a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
3030a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                 (length & 0xC0000000) == 0x0);
3031f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  fun->shared()->set_length(length);
3032f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return isolate->heap()->undefined_value();
303343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
303443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
303543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3036a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
3037ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  HandleScope scope(isolate);
303843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
303943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3040ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
3041ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
3042eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  RUNTIME_ASSERT(fun->should_have_prototype());
3043ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  Accessors::FunctionSetPrototype(fun, value);
304443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return args[0];  // return TOS
304543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
304643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
304743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3048a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
304979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
305037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  ASSERT(args.length() == 1);
305137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
3052f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
30537c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
305437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
305537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
3056ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
3057a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
305879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
30592bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  ASSERT(args.length() == 1);
30602bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
3061f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
30627c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  return isolate->heap()->ToBoolean(f->IsBuiltin());
30632bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com}
30642bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
306537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
3066a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetCode) {
3067ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
306843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
306943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3070f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
3071f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
307243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<SharedFunctionInfo> target_shared(target->shared());
30747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<SharedFunctionInfo> source_shared(source->shared());
30753484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(!source_shared->bound());
307643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30774954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
3078a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    return isolate->heap()->exception();
307943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
308043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3081906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // Mark both, the source and the target, as un-flushable because the
3082906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // shared unoptimized code makes them impossible to enqueue in a list.
3083906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  ASSERT(target_shared->code()->gc_metadata() == NULL);
3084906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  ASSERT(source_shared->code()->gc_metadata() == NULL);
3085906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  target_shared->set_dont_flush(true);
3086906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  source_shared->set_dont_flush(true);
3087906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
30887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Set the code, scope info, formal parameter count, and the length
3089c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // of the target shared function info.
30909768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  target_shared->ReplaceCode(source_shared->code());
30917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_scope_info(source_shared->scope_info());
30927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_length(source_shared->length());
3093a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  target_shared->set_feedback_vector(source_shared->feedback_vector());
30947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target_shared->set_formal_parameter_count(
30957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      source_shared->formal_parameter_count());
3096c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  target_shared->set_script(source_shared->script());
3097c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  target_shared->set_start_position_and_type(
3098c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      source_shared->start_position_and_type());
3099c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  target_shared->set_end_position(source_shared->end_position());
3100c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  bool was_native = target_shared->native();
3101c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  target_shared->set_compiler_hints(source_shared->compiler_hints());
3102c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  target_shared->set_native(was_native);
31033484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  target_shared->set_profiler_ticks(source_shared->profiler_ticks());
31047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
31057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Set the code of the target function.
31067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target->ReplaceCode(source_shared->code());
310789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  ASSERT(target->next_function_link()->IsUndefined());
31087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
31097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Make sure we get a fresh copy of the literal vector to avoid cross
31107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // context contamination.
31117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<Context> context(source->context());
31127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  int number_of_literals = source->NumberOfLiterals();
31137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<FixedArray> literals =
31147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
31157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (number_of_literals > 0) {
311646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    literals->set(JSFunction::kLiteralNativeContextIndex,
311746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                  context->native_context());
31187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
311943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  target->set_context(*context);
31207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  target->set_literals(*literals);
31217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
3122355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (isolate->logger()->is_logging_code_events() ||
3123f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      isolate->cpu_profiler()->is_profiling()) {
31247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    isolate->logger()->LogExistingFunction(
31257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        source_shared, Handle<Code>(source_shared->code()));
31267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
31277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
312843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *target;
312943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
313043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3132a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_CreateJSGeneratorObject) {
3133057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  HandleScope scope(isolate);
3134e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(args.length() == 0);
313577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
3136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JavaScriptFrameIterator it(isolate);
3137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  JavaScriptFrame* frame = it.frame();
3138057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<JSFunction> function(frame->function());
3139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  RUNTIME_ASSERT(function->shared()->is_generator());
3140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3141057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<JSGeneratorObject> generator;
3142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (frame->IsConstructor()) {
3143057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    generator = handle(JSGeneratorObject::cast(frame->receiver()));
3144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
3145057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    generator = isolate->factory()->NewJSGeneratorObject(function);
3146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
3147057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  generator->set_function(*function);
314877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  generator->set_context(Context::cast(frame->context()));
3149ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  generator->set_receiver(frame->receiver());
3150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  generator->set_continuation(0);
3151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  generator->set_operand_stack(isolate->heap()->empty_fixed_array());
315257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  generator->set_stack_handler_index(-1);
3153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3154057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return *generator;
3155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
3156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3158a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_SuspendJSGeneratorObject) {
3159e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope handle_scope(isolate);
316077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  ASSERT(args.length() == 1);
3161e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
316277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
316377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  JavaScriptFrameIterator stack_iterator(isolate);
3164f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  JavaScriptFrame* frame = stack_iterator.frame();
3165169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
3166169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT_EQ(frame->function(), generator_object->function());
31671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
31681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // The caller should have saved the context and continuation already.
31691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
31701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT_LT(0, generator_object->continuation());
317177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
3172f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // We expect there to be at least two values on the operand stack: the return
3173f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // value of the yield expression, and the argument to this runtime call.
3174f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // Neither of those should be saved.
3175f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int operands_count = frame->ComputeOperandsCount();
31761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT_GE(operands_count, 2);
3177f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  operands_count -= 2;
317877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
3179f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (operands_count == 0) {
31801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // Although it's semantically harmless to call this function with an
31811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // operands_count of zero, it is also unnecessary.
318277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    ASSERT_EQ(generator_object->operand_stack(),
318377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org              isolate->heap()->empty_fixed_array());
318457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    ASSERT_EQ(generator_object->stack_handler_index(), -1);
318577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // If there are no operands on the stack, there shouldn't be a handler
3186ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    // active either.
318777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    ASSERT(!frame->HasHandler());
318877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  } else {
318957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    int stack_handler_index = -1;
3190e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<FixedArray> operand_stack =
3191e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        isolate->factory()->NewFixedArray(operands_count);
3192e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    frame->SaveOperandStack(*operand_stack, &stack_handler_index);
3193e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    generator_object->set_operand_stack(*operand_stack);
319457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    generator_object->set_stack_handler_index(stack_handler_index);
319577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
319677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
31971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return isolate->heap()->undefined_value();
319877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org}
319977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
320077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
3201ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Note that this function is the slow path for resuming generators.  It is only
3202ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// called if the suspended activation had operands on the stack, stack handlers
3203ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// needing rewinding, or if the resume should throw an exception.  The fast path
3204ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
32058a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
32068a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// called in any case, as it needs to reconstruct the stack frame and make space
32078a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org// for arguments and operands.
3208a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_ResumeJSGeneratorObject) {
320979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
3210ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(args.length() == 3);
3211f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
3212f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  CONVERT_ARG_CHECKED(Object, value, 1);
3213ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
3214ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  JavaScriptFrameIterator stack_iterator(isolate);
3215f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  JavaScriptFrame* frame = stack_iterator.frame();
3216ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3217ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT_EQ(frame->function(), generator_object->function());
3218594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(frame->function()->is_compiled());
3219ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3220e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
3221e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
3222ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3223ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Address pc = generator_object->function()->code()->instruction_start();
3224ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  int offset = generator_object->continuation();
3225ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(offset > 0);
3226ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  frame->set_pc(pc + offset);
32272904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (FLAG_enable_ool_constant_pool) {
32282904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    frame->set_constant_pool(
32292904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        generator_object->function()->code()->constant_pool());
32302904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
3231ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
3232ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3233f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  FixedArray* operand_stack = generator_object->operand_stack();
3234f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int operands_count = operand_stack->length();
3235f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (operands_count != 0) {
323657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    frame->RestoreOperandStack(operand_stack,
323757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                               generator_object->stack_handler_index());
3238f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
323957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    generator_object->set_stack_handler_index(-1);
3240ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
3241ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3242ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  JSGeneratorObject::ResumeMode resume_mode =
3243ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
3244ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  switch (resume_mode) {
32458a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org    case JSGeneratorObject::NEXT:
3246f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      return value;
3247ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    case JSGeneratorObject::THROW:
3248f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      return isolate->Throw(value);
3249ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
3250ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3251ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  UNREACHABLE();
3252ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return isolate->ThrowIllegalOperation();
3253ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3254ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3255ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3256a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_ThrowGeneratorStateError) {
3257ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HandleScope scope(isolate);
3258ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(args.length() == 1);
3259ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
3260ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  int continuation = generator->continuation();
3261f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
3262ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      "generator_finished" : "generator_running";
3263ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
3264ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Handle<Object> error = isolate->factory()->NewError(message, argv);
3265ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return isolate->Throw(*error);
3266ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3267ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3268ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3269a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ObjectFreeze) {
3270528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
3271a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(args.length() == 1);
3272528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
3273196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
3274196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  // %ObjectFreeze is a fast path and these cases are handled elsewhere.
3275196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
3276196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                 !object->map()->is_observed() &&
3277196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                 !object->IsJSProxy());
3278196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
3279255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<Object> result;
3280255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
3281528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return *result;
3282a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
3283a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3284a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3285a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_StringCharCodeAt) {
32869e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  HandleScope handle_scope(isolate);
328743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
328843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
3290de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
329143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Flatten the string.  If someone wants to get a char at an index
32931af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // in a cons string, it is likely that more indices will be
32941af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // accessed.
32959e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  subject = String::Flatten(subject);
32960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
32971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (i >= static_cast<uint32_t>(subject->length())) {
3298ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->nan_value();
329974e4e5ea6d118c13967c54fe92c7782ebdcb6eb7kasperl@chromium.org  }
33001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
33011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  return Smi::FromInt(subject->Get(i));
33020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
33030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
33040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3305a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CharFromCode) {
33069e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  HandleScope handlescope(isolate);
330743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
33089e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (args[0]->IsNumber()) {
33098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
33108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    code &= 0xffff;
33119e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
33129e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  }
33139e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return isolate->heap()->empty_string();
331443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
331543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
331625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
331725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgclass FixedArrayBuilder {
331825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org public:
3319ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
3320ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
3321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        length_(0),
3322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        has_non_smi_elements_(false) {
332325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // Require a non-zero initial size. Ensures that doubling the size to
332425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // extend the array will work.
332525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(initial_capacity > 0);
332625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
332725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
332825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
332925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      : array_(backing_store),
3330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        length_(0),
3331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        has_non_smi_elements_(false) {
333225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // Require a non-zero initial size. Ensures that doubling the size to
333325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    // extend the array will work.
333425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(backing_store->length() > 0);
333525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
333625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
333725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  bool HasCapacity(int elements) {
333825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int length = array_->length();
333925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int required_length = length_ + elements;
334025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return (length >= required_length);
334125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
334225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
334325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void EnsureCapacity(int elements) {
334425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int length = array_->length();
334525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int required_length = length_ + elements;
334625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (length < required_length) {
334725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      int new_length = length;
334825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      do {
334925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org        new_length *= 2;
335025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      } while (new_length < required_length);
335125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      Handle<FixedArray> extended_array =
3352ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
335325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      array_->CopyTo(0, *extended_array, 0, length_);
335425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      array_ = extended_array;
335525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    }
335625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
335725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
335825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void Add(Object* value) {
3359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(!value->IsSmi());
336025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(length_ < capacity());
336125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_->set(length_, value);
336225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    length_++;
3363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    has_non_smi_elements_ = true;
336425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
336525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
336625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void Add(Smi* value) {
3367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(value->IsSmi());
336825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(length_ < capacity());
336925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_->set(length_, value);
337025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    length_++;
337125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
337225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
337325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Handle<FixedArray> array() {
337425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return array_;
337525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
337625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
337725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int length() {
337825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return length_;
337925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
338025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
338125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int capacity() {
338225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return array_->length();
338325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
338425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
338525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
3386fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    JSArray::SetContent(target_array, array_);
338725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    target_array->set_length(Smi::FromInt(length_));
338825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    return target_array;
338925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
339025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
339178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
339225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org private:
339325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  Handle<FixedArray> array_;
339425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int length_;
3395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_non_smi_elements_;
339625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org};
339725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
339825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
3399bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Forward declarations.
340025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgconst int kStringBuilderConcatHelperLengthBits = 11;
340125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgconst int kStringBuilderConcatHelperPositionBits = 19;
3402bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3403bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgtemplate <typename schar>
3404bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic inline void StringBuilderConcatHelper(String*,
3405bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                             schar*,
3406bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                             FixedArray*,
3407bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                             int);
3408bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
340925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgtypedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
341025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    StringBuilderSubstringLength;
341125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.orgtypedef BitField<int,
341225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                 kStringBuilderConcatHelperLengthBits,
341325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                 kStringBuilderConcatHelperPositionBits>
341425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    StringBuilderSubstringPosition;
341525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
3416bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3417bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgclass ReplacementStringBuilder {
3418bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org public:
3419ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ReplacementStringBuilder(Heap* heap,
3420ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           Handle<String> subject,
3421ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           int estimated_part_count)
3422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : heap_(heap),
3423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        array_builder_(heap->isolate(), estimated_part_count),
342425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org        subject_(subject),
3425bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        character_count_(0),
3426b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        is_ascii_(subject->IsOneByteRepresentation()) {
3427bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Require a non-zero initial size. Ensures that doubling the size to
3428bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // extend the array will work.
3429bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(estimated_part_count > 0);
3430bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3431bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
343225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  static inline void AddSubjectSlice(FixedArrayBuilder* builder,
343325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                     int from,
343425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                     int to) {
3435bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(from >= 0);
3436bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int length = to - from;
3437bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(length > 0);
3438bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (StringBuilderSubstringLength::is_valid(length) &&
3439bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        StringBuilderSubstringPosition::is_valid(from)) {
3440bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int encoded_slice = StringBuilderSubstringLength::encode(length) |
3441bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          StringBuilderSubstringPosition::encode(from);
344225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      builder->Add(Smi::FromInt(encoded_slice));
3443bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else {
3444c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      // Otherwise encode as two smis.
344525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      builder->Add(Smi::FromInt(-length));
344625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      builder->Add(Smi::FromInt(from));
3447bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
344825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
344925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
345025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
345125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void EnsureCapacity(int elements) {
345225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_builder_.EnsureCapacity(elements);
345325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
345425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
345525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
345625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  void AddSubjectSlice(int from, int to) {
345725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    AddSubjectSlice(&array_builder_, from, to);
345825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    IncrementCharacterCount(to - from);
3459bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3460bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3461bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3462bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void AddString(Handle<String> string) {
3463bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int length = string->length();
3464bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(length > 0);
3465bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    AddElement(*string);
34668e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (!string->IsOneByteRepresentation()) {
3467bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      is_ascii_ = false;
3468bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3469bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    IncrementCharacterCount(length);
3470bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3471bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3472bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3473255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  MaybeHandle<String> ToString() {
3474255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Isolate* isolate = heap_->isolate();
347525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (array_builder_.length() == 0) {
3476255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      return isolate->factory()->empty_string();
3477bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3478bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3479bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    Handle<String> joined_string;
3480bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (is_ascii_) {
3481255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      Handle<SeqOneByteString> seq;
3482255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
3483255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          isolate, seq,
3484255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          isolate->factory()->NewRawOneByteString(character_count_),
3485255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          String);
3486255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
348779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
348859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      uint8_t* char_buffer = seq->GetChars();
3489bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      StringBuilderConcatHelper(*subject_,
3490bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                char_buffer,
349125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                *array_builder_.array(),
349225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                array_builder_.length());
349304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      joined_string = Handle<String>::cast(seq);
3494bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else {
3495bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      // Non-ASCII.
3496255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      Handle<SeqTwoByteString> seq;
3497255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
3498255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          isolate, seq,
3499255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          isolate->factory()->NewRawTwoByteString(character_count_),
3500255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          String);
3501255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
350279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
3503bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      uc16* char_buffer = seq->GetChars();
3504bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      StringBuilderConcatHelper(*subject_,
3505bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                char_buffer,
350625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                *array_builder_.array(),
350725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org                                array_builder_.length());
350804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      joined_string = Handle<String>::cast(seq);
3509bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3510bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return joined_string;
3511bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3512bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3513bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3514bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void IncrementCharacterCount(int by) {
35150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if (character_count_ > String::kMaxLength - by) {
3516b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      STATIC_ASSERT(String::kMaxLength < kMaxInt);
3517b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      character_count_ = kMaxInt;
3518b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org    } else {
3519b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      character_count_ += by;
3520bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3521bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3522bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
352325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org private:
3524bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void AddElement(Object* element) {
3525bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ASSERT(element->IsSmi() || element->IsString());
352625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    ASSERT(array_builder_.capacity() > array_builder_.length());
352725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    array_builder_.Add(element);
3528bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3529bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3530ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap_;
353125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  FixedArrayBuilder array_builder_;
3532bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  Handle<String> subject_;
3533bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int character_count_;
3534bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  bool is_ascii_;
3535bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org};
3536bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3537bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3538bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgclass CompiledReplacement {
3539bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org public:
35407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  explicit CompiledReplacement(Zone* zone)
3541355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
3542bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3543355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Return whether the replacement is simple.
3544355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool Compile(Handle<String> replacement,
3545bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org               int capture_count,
3546bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org               int subject_length);
3547bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3548355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Use Apply only if Compile returned false.
3549bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  void Apply(ReplacementStringBuilder* builder,
3550bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org             int match_from,
3551bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org             int match_to,
3552355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org             int32_t* match);
3553bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3554bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Number of distinct parts of the replacement pattern.
3555bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int parts() {
3556bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return parts_.length();
3557bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3558e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
35597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone() const { return zone_; }
35607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
3561bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org private:
3562bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  enum PartType {
3563bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    SUBJECT_PREFIX = 1,
3564bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    SUBJECT_SUFFIX,
3565bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    SUBJECT_CAPTURE,
3566bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    REPLACEMENT_SUBSTRING,
3567bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    REPLACEMENT_STRING,
3568bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3569bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    NUMBER_OF_PART_TYPES
3570bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  };
3571bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3572bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  struct ReplacementPart {
3573bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectMatch() {
3574bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_CAPTURE, 0);
3575bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3576bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectCapture(int capture_index) {
3577bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_CAPTURE, capture_index);
3578bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3579bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectPrefix() {
3580bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_PREFIX, 0);
3581bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3582bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart SubjectSuffix(int subject_length) {
3583bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(SUBJECT_SUFFIX, subject_length);
3584bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3585bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart ReplacementString() {
3586bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(REPLACEMENT_STRING, 0);
3587bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3588bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    static inline ReplacementPart ReplacementSubString(int from, int to) {
3589bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      ASSERT(from >= 0);
3590bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      ASSERT(to > from);
3591bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return ReplacementPart(-from, to);
3592bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3593bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3594bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // If tag <= 0 then it is the negation of a start index of a substring of
3595bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // the replacement pattern, otherwise it's a value from PartType.
3596bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ReplacementPart(int tag, int data)
3597bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        : tag(tag), data(data) {
3598bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      // Must be non-positive or a PartType value.
3599bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      ASSERT(tag < NUMBER_OF_PART_TYPES);
3600bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3601bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Either a value of PartType or a non-positive number that is
3602bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // the negation of an index into the replacement string.
3603bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int tag;
3604bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // The data value's interpretation depends on the value of tag:
3605bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == SUBJECT_PREFIX ||
3606bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == SUBJECT_SUFFIX:  data is unused.
3607bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == SUBJECT_CAPTURE: data is the number of the capture.
3608bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == REPLACEMENT_SUBSTRING ||
3609bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag == REPLACEMENT_STRING:    data is index into array of substrings
3610bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //                               of the replacement string.
3611bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // tag <= 0: Temporary representation of the substring of the replacement
3612bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //           string ranging over -tag .. data.
3613bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
3614bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    //           substring objects.
3615bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int data;
3616bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  };
3617bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3618bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  template<typename Char>
3619355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
3620355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               Vector<Char> characters,
3621355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               int capture_count,
3622355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               int subject_length,
3623355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               Zone* zone) {
3624bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int length = characters.length();
3625bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int last = 0;
3626bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    for (int i = 0; i < length; i++) {
3627bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      Char c = characters[i];
3628bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      if (c == '$') {
3629bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int next_index = i + 1;
3630bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (next_index == length) {  // No next character!
3631bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3632bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3633bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        Char c2 = characters[next_index];
3634bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        switch (c2) {
3635bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '$':
3636bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
3637bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            // There is a substring before. Include the first "$".
36387028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
36397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       zone);
3640bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            last = next_index + 1;  // Continue after the second "$".
3641bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          } else {
3642bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            // Let the next substring start with the second "$".
3643bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            last = next_index;
3644bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3645bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3646bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3647bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '`':
3648bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
36497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3650bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
36517028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          parts->Add(ReplacementPart::SubjectPrefix(), zone);
3652bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3653bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          last = i + 1;
3654bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3655bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '\'':
3656bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
36577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3658bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
36597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
3660bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3661bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          last = i + 1;
3662bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3663bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '&':
3664bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (i > last) {
36657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3666bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
36677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          parts->Add(ReplacementPart::SubjectMatch(), zone);
3668bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3669bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          last = i + 1;
3670bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3671bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '0':
3672bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '1':
3673bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '2':
3674bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '3':
3675bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '4':
3676bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '5':
3677bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '6':
3678bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '7':
3679bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '8':
3680bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        case '9': {
3681bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          int capture_ref = c2 - '0';
3682bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (capture_ref > capture_count) {
3683bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            i = next_index;
3684bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            continue;
3685bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3686bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          int second_digit_index = next_index + 1;
3687bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (second_digit_index < length) {
3688bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            // Peek ahead to see if we have two digits.
3689bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            Char c3 = characters[second_digit_index];
3690bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            if ('0' <= c3 && c3 <= '9') {  // Double digits.
3691bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org              int double_digit_ref = capture_ref * 10 + c3 - '0';
3692bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org              if (double_digit_ref <= capture_count) {
3693bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                next_index = second_digit_index;
3694bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                capture_ref = double_digit_ref;
3695bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org              }
3696bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            }
3697bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3698bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          if (capture_ref > 0) {
3699bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            if (i > last) {
37007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org              parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3701bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            }
370271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org            ASSERT(capture_ref <= capture_count);
37037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
3704bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            last = next_index + 1;
3705bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
3706bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3707bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3708bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3709bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        default:
3710bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          i = next_index;
3711bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          break;
3712bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3713bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3714bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3715bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (length > last) {
3716bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      if (last == 0) {
3717355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // Replacement is simple.  Do not use Apply to do the replacement.
371855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        return true;
3719bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      } else {
37207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
3721bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3722bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
372355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    return false;
3724bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3725bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3726bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ZoneList<ReplacementPart> parts_;
3727bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ZoneList<Handle<String> > replacement_substrings_;
37287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone_;
3729bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org};
3730bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3731bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3732355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgbool CompiledReplacement::Compile(Handle<String> replacement,
3733bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                  int capture_count,
3734bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                  int subject_length) {
3735ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  {
373679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
3737ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    String::FlatContent content = replacement->GetFlatContent();
3738ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    ASSERT(content.IsFlat());
3739355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    bool simple = false;
3740ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (content.IsAscii()) {
3741355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      simple = ParseReplacementPattern(&parts_,
374259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                       content.ToOneByteVector(),
3743355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       capture_count,
3744355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       subject_length,
3745355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       zone());
3746ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    } else {
3747ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      ASSERT(content.IsTwoByte());
3748355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      simple = ParseReplacementPattern(&parts_,
3749355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       content.ToUC16Vector(),
3750355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       capture_count,
3751355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       subject_length,
3752355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                       zone());
3753ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    }
3754355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (simple) return true;
3755bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3756355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
3757ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = replacement->GetIsolate();
3758c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Find substrings of replacement string and create them as String objects.
3759bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int substring_index = 0;
3760bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  for (int i = 0, n = parts_.length(); i < n; i++) {
3761bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int tag = parts_[i].tag;
3762bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (tag <= 0) {  // A replacement string slice.
3763bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int from = -tag;
3764bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int to = parts_[i].data;
3765ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      replacement_substrings_.Add(
37667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          isolate->factory()->NewSubString(replacement, from, to), zone());
3767bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      parts_[i].tag = REPLACEMENT_SUBSTRING;
3768bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      parts_[i].data = substring_index;
3769bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      substring_index++;
3770bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    } else if (tag == REPLACEMENT_STRING) {
37717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      replacement_substrings_.Add(replacement, zone());
3772bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      parts_[i].data = substring_index;
3773bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      substring_index++;
3774bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3775bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3776355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  return false;
3777bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3778bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3779bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3780bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgvoid CompiledReplacement::Apply(ReplacementStringBuilder* builder,
3781bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                int match_from,
3782bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org                                int match_to,
3783355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                int32_t* match) {
3784355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT_LT(0, parts_.length());
3785bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  for (int i = 0, n = parts_.length(); i < n; i++) {
3786bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ReplacementPart part = parts_[i];
3787bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    switch (part.tag) {
3788bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case SUBJECT_PREFIX:
3789bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (match_from > 0) builder->AddSubjectSlice(0, match_from);
3790bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3791bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case SUBJECT_SUFFIX: {
3792bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int subject_length = part.data;
3793bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (match_to < subject_length) {
3794bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          builder->AddSubjectSlice(match_to, subject_length);
3795bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3796bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3797bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3798bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case SUBJECT_CAPTURE: {
3799bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int capture = part.data;
3800355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        int from = match[capture * 2];
3801355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        int to = match[capture * 2 + 1];
3802bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        if (from >= 0 && to > from) {
3803bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          builder->AddSubjectSlice(from, to);
3804bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
3805bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3806bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3807bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case REPLACEMENT_SUBSTRING:
3808bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      case REPLACEMENT_STRING:
3809bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        builder->AddString(replacement_substrings_[part.data]);
3810bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        break;
3811bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      default:
3812bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        UNREACHABLE();
3813bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3814bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3815bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3816bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3817bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
381859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgvoid FindAsciiStringIndices(Vector<const uint8_t> subject,
381955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            char pattern,
382055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            ZoneList<int>* indices,
38217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            unsigned int limit,
38227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            Zone* zone) {
382355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(limit > 0);
382455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Collect indices of pattern in subject using memchr.
382555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Stop after finding at most limit values.
382659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const uint8_t* subject_start = subject.start();
382759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const uint8_t* subject_end = subject_start + subject.length();
382859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const uint8_t* pos = subject_start;
382955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  while (limit > 0) {
383059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    pos = reinterpret_cast<const uint8_t*>(
383155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        memchr(pos, pattern, subject_end - pos));
383255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (pos == NULL) return;
38337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    indices->Add(static_cast<int>(pos - subject_start), zone);
383455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    pos++;
383555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    limit--;
383655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
383755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
383855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
383955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
384049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgvoid FindTwoByteStringIndices(const Vector<const uc16> subject,
384149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              uc16 pattern,
384249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              ZoneList<int>* indices,
384349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              unsigned int limit,
384449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                              Zone* zone) {
384549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  ASSERT(limit > 0);
384649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  const uc16* subject_start = subject.start();
384749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  const uc16* subject_end = subject_start + subject.length();
384849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
384949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    if (*pos == pattern) {
385049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      indices->Add(static_cast<int>(pos - subject_start), zone);
385149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      limit--;
385249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
385349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
385449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
385549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
385649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
385755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgtemplate <typename SubjectChar, typename PatternChar>
385855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgvoid FindStringIndices(Isolate* isolate,
385955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       Vector<const SubjectChar> subject,
386055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       Vector<const PatternChar> pattern,
386155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       ZoneList<int>* indices,
38627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       unsigned int limit,
38637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       Zone* zone) {
386455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(limit > 0);
386555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Collect indices of pattern in subject.
386655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Stop after finding at most limit values.
386755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int pattern_length = pattern.length();
386855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int index = 0;
386955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
387055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  while (limit > 0) {
387155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    index = search.Search(subject, index);
387255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (index < 0) return;
38737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    indices->Add(index, zone);
387455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    index += pattern_length;
387555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    limit--;
387655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
387755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
387855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
387955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
388055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgvoid FindStringIndicesDispatch(Isolate* isolate,
388155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                               String* subject,
388255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                               String* pattern,
388355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                               ZoneList<int>* indices,
38847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                               unsigned int limit,
38857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                               Zone* zone) {
388655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  {
388779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
388855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    String::FlatContent subject_content = subject->GetFlatContent();
388955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    String::FlatContent pattern_content = pattern->GetFlatContent();
389055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    ASSERT(subject_content.IsFlat());
389155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    ASSERT(pattern_content.IsFlat());
389255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (subject_content.IsAscii()) {
389359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
389455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      if (pattern_content.IsAscii()) {
389559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        Vector<const uint8_t> pattern_vector =
389659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            pattern_content.ToOneByteVector();
389755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        if (pattern_vector.length() == 1) {
389855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org          FindAsciiStringIndices(subject_vector,
389955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                                 pattern_vector[0],
390055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                                 indices,
39017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                 limit,
39027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                                 zone);
390355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        } else {
390455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org          FindStringIndices(isolate,
390555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            subject_vector,
390655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            pattern_vector,
390755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                            indices,
39087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            limit,
39097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                            zone);
391055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        }
391155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      } else {
391255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org        FindStringIndices(isolate,
391355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          subject_vector,
391455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          pattern_content.ToUC16Vector(),
391555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          indices,
39167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                          limit,
39177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                          zone);
391855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      }
391955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    } else {
392055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (pattern_content.IsAscii()) {
392259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        Vector<const uint8_t> pattern_vector =
392359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org            pattern_content.ToOneByteVector();
392449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        if (pattern_vector.length() == 1) {
392549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindTwoByteStringIndices(subject_vector,
392649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   pattern_vector[0],
392749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   indices,
392849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   limit,
392949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   zone);
393049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        } else {
393149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindStringIndices(isolate,
393249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            subject_vector,
393349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            pattern_vector,
393449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            indices,
393549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            limit,
393649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            zone);
393749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        }
393855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      } else {
393949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
394049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        if (pattern_vector.length() == 1) {
394149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindTwoByteStringIndices(subject_vector,
394249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   pattern_vector[0],
394349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   indices,
394449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   limit,
394549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                   zone);
394649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        } else {
394749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org          FindStringIndices(isolate,
394849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            subject_vector,
394949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            pattern_vector,
395049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            indices,
395149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            limit,
395249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                            zone);
395349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        }
395455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      }
395555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
395655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
395755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
395855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
395955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
396055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgtemplate<typename ResultSeqString>
3961a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
396255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    Isolate* isolate,
396355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    Handle<String> subject,
396455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    Handle<JSRegExp> pattern_regexp,
3965efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org    Handle<String> replacement,
3966355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSArray> last_match_info) {
396755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(subject->IsFlat());
396855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT(replacement->IsFlat());
396955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3970c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
3971c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneList<int> indices(8, zone_scope.zone());
397255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
397355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  String* pattern =
397455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
397555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int subject_len = subject->length();
397655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int pattern_len = pattern->length();
397755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int replacement_len = replacement->length();
397855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3979355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  FindStringIndicesDispatch(
3980c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
398155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
398255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int matches = indices.length();
39838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (matches == 0) return *subject;
398455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
3985400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  // Detect integer overflow.
3986400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  int64_t result_len_64 =
3987400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      (static_cast<int64_t>(replacement_len) -
3988400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org       static_cast<int64_t>(pattern_len)) *
3989400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      static_cast<int64_t>(matches) +
3990400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org      static_cast<int64_t>(subject_len);
3991b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  int result_len;
3992b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
3993b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org    STATIC_ASSERT(String::kMaxLength < kMaxInt);
3994b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org    result_len = kMaxInt;  // Provoke exception.
3995b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  } else {
3996b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org    result_len = static_cast<int>(result_len_64);
3997a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  }
3998400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org
399955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int subject_pos = 0;
400055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  int result_pos = 0;
400155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
4002255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  MaybeHandle<SeqString> maybe_res;
400355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  if (ResultSeqString::kHasAsciiEncoding) {
4004255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    maybe_res = isolate->factory()->NewRawOneByteString(result_len);
400555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  } else {
4006255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
400755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
4008255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<SeqString> untyped_res;
4009255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
4010255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
401155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
401255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  for (int i = 0; i < matches; i++) {
401355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    // Copy non-matched subject content.
401455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (subject_pos < indices.at(i)) {
401555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      String::WriteToFlat(*subject,
401655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          result->GetChars() + result_pos,
401755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          subject_pos,
401855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          indices.at(i));
401955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      result_pos += indices.at(i) - subject_pos;
402055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
402155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
402255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    // Replace match.
402355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    if (replacement_len > 0) {
402455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      String::WriteToFlat(*replacement,
402555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          result->GetChars() + result_pos,
402655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          0,
402755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                          replacement_len);
402855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org      result_pos += replacement_len;
402955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
403055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
403155ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    subject_pos = indices.at(i) + pattern_len;
403255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
403355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Add remaining subject content at the end.
403455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  if (subject_pos < subject_len) {
403555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    String::WriteToFlat(*subject,
403655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                        result->GetChars() + result_pos,
403755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                        subject_pos,
403855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                        subject_len);
403955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
4040efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
4041355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int32_t match_indices[] = { indices.at(matches - 1),
4042355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                              indices.at(matches - 1) + pattern_len };
4043355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
4044efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
404555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  return *result;
404655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org}
404755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
4048bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4049a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
4050ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
4051355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> subject,
4052355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSRegExp> regexp,
4053355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> replacement,
4054355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSArray> last_match_info) {
4055bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(subject->IsFlat());
4056bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(replacement->IsFlat());
4057bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4058355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int capture_count = regexp->CaptureCount();
4059355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int subject_length = subject->length();
4060bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4061bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // CompiledReplacement uses zone allocation.
4062c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
4063c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  CompiledReplacement compiled_replacement(zone_scope.zone());
4064355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool simple_replace = compiled_replacement.Compile(replacement,
4065355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                     capture_count,
4066355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                     subject_length);
4067bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
406855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Shortcut for simple non-regexp global replacements
40698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
4070f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (subject->HasOnlyOneByteChars() &&
4071f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        replacement->HasOnlyOneByteChars()) {
40728432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
4073355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, replacement, last_match_info);
4074355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else {
40758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
4076355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, replacement, last_match_info);
407755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
407855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
407955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
40808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4081a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
4082355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4083355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int32_t* current_match = global_cache.FetchNext();
4084355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (current_match == NULL) {
4085a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    if (global_cache.HasException()) return isolate->heap()->exception();
40868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    return *subject;
4087355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
4088355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4089bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Guessing the number of parts that the final result string is built
4090bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // from. Global regexps can match any number of times, so we guess
4091bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // conservatively.
40928432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
4093ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ReplacementStringBuilder builder(isolate->heap(),
4094355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                   subject,
4095ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                   expected_parts);
4096bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
40976141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // Number of parts added by compiled replacement plus preceeding
40986141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // string and possibly suffix after last match.  It is possible for
40996141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // all components to use two elements when encoded as two smis.
41006141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
4101355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4102355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int prev = 0;
4103355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4104bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  do {
4105bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    builder.EnsureCapacity(parts_added_per_loop);
4106bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4107355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int start = current_match[0];
4108355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int end = current_match[1];
4109bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4110bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (prev < start) {
4111bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      builder.AddSubjectSlice(prev, start);
4112bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
4113471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
4114355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (simple_replace) {
4115355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      builder.AddString(replacement);
4116355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    } else {
4117355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      compiled_replacement.Apply(&builder,
4118355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                 start,
4119355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                 end,
4120355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                 current_match);
4121355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
4122bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    prev = end;
4123bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4124355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    current_match = global_cache.FetchNext();
4125355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  } while (current_match != NULL);
4126bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4127a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
4128bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4129355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (prev < subject_length) {
4130355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    builder.EnsureCapacity(2);
4131355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    builder.AddSubjectSlice(prev, subject_length);
4132bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
4133bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4134355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(last_match_info,
4135355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               subject,
4136355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               capture_count,
4137355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               global_cache.LastSuccessfulMatch());
4138355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4139255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<String> result;
4140255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
41417010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  return *result;
4142bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
4143bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4144bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
41454a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.comtemplate <typename ResultSeqString>
4146a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
4147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
4148355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> subject,
4149355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSRegExp> regexp,
4150355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<JSArray> last_match_info) {
41514a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  ASSERT(subject->IsFlat());
41524a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
415355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  // Shortcut for simple non-regexp global replacements
41548432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (regexp->TypeTag() == JSRegExp::ATOM) {
4155fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Handle<String> empty_string = isolate->factory()->empty_string();
415659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (subject->IsOneByteRepresentation()) {
41578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
41588432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org          isolate, subject, regexp, empty_string, last_match_info);
415955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    } else {
41608432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
41618432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org          isolate, subject, regexp, empty_string, last_match_info);
416255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
416355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
416455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
41658432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4166a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
416708eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4168355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int32_t* current_match = global_cache.FetchNext();
4169355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (current_match == NULL) {
4170a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    if (global_cache.HasException()) return isolate->heap()->exception();
41718432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    return *subject;
41724a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
41734a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
4174355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int start = current_match[0];
4175355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int end = current_match[1];
4176355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int capture_count = regexp->CaptureCount();
4177355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int subject_length = subject->length();
4178efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
4179355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int new_length = subject_length - (end - start);
4180355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (new_length == 0) return isolate->heap()->empty_string();
4181efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org
41824a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  Handle<ResultSeqString> answer;
41834a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  if (ResultSeqString::kHasAsciiEncoding) {
4184ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    answer = Handle<ResultSeqString>::cast(
4185255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
41864a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  } else {
4187ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    answer = Handle<ResultSeqString>::cast(
4188255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
41894a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
41904a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
4191355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int prev = 0;
41924a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int position = 0;
41934a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
41944a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  do {
4195355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    start = current_match[0];
4196355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    end = current_match[1];
41974a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    if (prev < start) {
41984a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      // Add substring subject[prev;start] to answer string.
41998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
42004a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com      position += start - prev;
42014a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    }
42024a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    prev = end;
42034a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
4204355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    current_match = global_cache.FetchNext();
4205355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  } while (current_match != NULL);
4206355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4207a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
4208355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4209355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(last_match_info,
4210355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               subject,
4211355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               capture_count,
4212355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               global_cache.LastSuccessfulMatch());
4213355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4214355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (prev < subject_length) {
42154a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    // Add substring subject[prev;length] to answer string.
4216355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    String::WriteToFlat(
4217355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        *subject, answer->GetChars() + position, prev, subject_length);
4218355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    position += subject_length - prev;
42194a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
42204a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
4221355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (position == 0) return isolate->heap()->empty_string();
42224a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
42234a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  // Shorten string and fill
42244a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int string_size = ResultSeqString::SizeFor(position);
42254a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int allocated_string_size = ResultSeqString::SizeFor(new_length);
42264a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  int delta = allocated_string_size - string_size;
42274a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
42284a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  answer->set_length(position);
42294a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  if (delta == 0) return *answer;
42304a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
42314a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  Address end_of_string = answer->address() + string_size;
42325697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  Heap* heap = isolate->heap();
423363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
423463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // The trimming is performed on a newly allocated object, which is on a
423563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // fresly allocated page or on an already swept page. Hence, the sweeper
423663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // thread can not get confused with the filler creation. No synchronization
423763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // needed.
42385697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  heap->CreateFillerObjectAt(end_of_string, delta);
42395697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
42404a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  return *answer;
42414a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com}
42424a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
42434a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
4244a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
4245355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  HandleScope scope(isolate);
42466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 4);
4247471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
4248355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4249355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
4250355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4251355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
4252355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4253f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(regexp->GetFlags().is_global());
4254a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
4255d922884ea003c46279731a1528135f57788e9128yangguo@chromium.org
42569e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  subject = String::Flatten(subject);
4257bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
42584a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  if (replacement->length() == 0) {
4259f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (subject->HasOnlyOneByteChars()) {
42608432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
4261355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, last_match_info);
42624a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    } else {
42638432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
4264355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          isolate, subject, regexp, last_match_info);
42654a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com    }
42664a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com  }
42674a2e25edf994c4e3ff22fea6d432839192666139erik.corry@gmail.com
42689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  replacement = String::Flatten(replacement);
42698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
42708432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  return StringReplaceGlobalRegExpWithString(
4271355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      isolate, subject, regexp, replacement, last_match_info);
4272bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
4273bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4274bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
4275255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org// This may return an empty MaybeHandle if an exception is thrown or
4276255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org// we abort due to reaching the recursion limit.
4277255043f8054e713a64509c707cfabadd42344683machenbach@chromium.orgMaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
4278255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org                                                   Handle<String> subject,
4279255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org                                                   Handle<String> search,
4280255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org                                                   Handle<String> replace,
4281255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org                                                   bool* found,
4282255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org                                                   int recursion_limit) {
4283a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  StackLimitCheck stackLimitCheck(isolate);
4284a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
4285a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    return MaybeHandle<String>();
4286a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  }
4287255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  recursion_limit--;
42882efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  if (subject->IsConsString()) {
42892efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    ConsString* cons = ConsString::cast(*subject);
42902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> first = Handle<String>(cons->first());
42912efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> second = Handle<String>(cons->second());
4292255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Handle<String> new_first;
4293255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (!StringReplaceOneCharWithString(
4294255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            isolate, first, search, replace, found, recursion_limit)
4295255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            .ToHandle(&new_first)) {
4296255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      return MaybeHandle<String>();
4297255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    }
42987010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    if (*found) return isolate->factory()->NewConsString(new_first, second);
42992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
4300255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Handle<String> new_second;
4301255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (!StringReplaceOneCharWithString(
4302255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            isolate, second, search, replace, found, recursion_limit)
4303255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            .ToHandle(&new_second)) {
4304255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      return MaybeHandle<String>();
4305255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    }
43067010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    if (*found) return isolate->factory()->NewConsString(first, new_second);
43072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
43082efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    return subject;
43092efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  } else {
4310de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    int index = Runtime::StringMatch(isolate, subject, search, 0);
43112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    if (index == -1) return subject;
43122efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    *found = true;
43132efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
4314255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Handle<String> cons1;
4315255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
4316255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate, cons1,
4317255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate->factory()->NewConsString(first, replace),
4318255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        String);
43192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    Handle<String> second =
43202efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        isolate->factory()->NewSubString(subject, index + 1, subject->length());
43212efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    return isolate->factory()->NewConsString(cons1, second);
43222efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  }
43232efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org}
43242efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
43252efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
4326a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
43272efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  HandleScope scope(isolate);
43286e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 3);
4329f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4330f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
4331f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
43322efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
43332efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // If the cons string tree is too deep, we simply abort the recursion and
43342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // retry with a flattened subject string.
43352efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  const int kRecursionLimit = 0x1000;
43362efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  bool found = false;
4337255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<String> result;
4338255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  if (StringReplaceOneCharWithString(
4339255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          isolate, subject, search, replace, &found, kRecursionLimit)
4340255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          .ToHandle(&result)) {
4341255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    return *result;
4342255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  }
4343a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (isolate->has_pending_exception()) return isolate->heap()->exception();
4344255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
43459e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  subject = String::Flatten(subject);
4346255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4347255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate, result,
4348255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      StringReplaceOneCharWithString(
4349255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          isolate, subject, search, replace, &found, kRecursionLimit));
4350255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  return *result;
43512efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org}
43522efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
43532efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
43547c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org// Perform string match of pattern on subject, starting at start index.
43557c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org// Caller must ensure that 0 <= start_index <= sub->length(),
4356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// and should check that pat->length() + start_index <= sub->length().
4357ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint Runtime::StringMatch(Isolate* isolate,
4358ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                         Handle<String> sub,
43597c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                         Handle<String> pat,
43607c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                         int start_index) {
43617c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  ASSERT(0 <= start_index);
4362bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(start_index <= sub->length());
43637c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
4364c3e50d815532238589ae8c2f65b6467e4adae811ager@chromium.org  int pattern_length = pat->length();
43657c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  if (pattern_length == 0) return start_index;
43667c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
4367bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int subject_length = sub->length();
43687c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  if (start_index + pattern_length > subject_length) return -1;
43697c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
43709e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  sub = String::Flatten(sub);
43719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  pat = String::Flatten(pat);
43727c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
437379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
437432d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  // Extract flattened substrings of cons strings before determining asciiness.
4375ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent seq_sub = sub->GetFlatContent();
4376ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent seq_pat = pat->GetFlatContent();
437732d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
43787c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // dispatch on type of strings
4379ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (seq_pat.IsAscii()) {
438059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
4381ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (seq_sub.IsAscii()) {
4382ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return SearchString(isolate,
438359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                          seq_sub.ToOneByteVector(),
4384ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                          pat_vector,
4385ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                          start_index);
438643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
4387ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return SearchString(isolate,
4388ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                        seq_sub.ToUC16Vector(),
4389ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        pat_vector,
4390ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        start_index);
439143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4392ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
4393ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (seq_sub.IsAscii()) {
4394ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return SearchString(isolate,
439559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                        seq_sub.ToOneByteVector(),
4396ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        pat_vector,
4397ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                        start_index);
43987c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
4399ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return SearchString(isolate,
4400ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                      seq_sub.ToUC16Vector(),
4401ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                      pat_vector,
4402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                      start_index);
440341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org}
440441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
440541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
4406a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringIndexOf) {
44076e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
440841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  ASSERT(args.length() == 3);
440941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
4410f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4411f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
44128496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
44137c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
441441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  uint32_t start_index;
441530ce411529579186181838984710b0b0980857aaricow@chromium.org  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
441641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
4417870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
44182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int position = Runtime::StringMatch(isolate, sub, pat, start_index);
44197c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  return Smi::FromInt(position);
442043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
442143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
442243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4423b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.orgtemplate <typename schar, typename pchar>
44242ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.orgstatic int StringMatchBackwards(Vector<const schar> subject,
44252ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org                                Vector<const pchar> pattern,
4426b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                int idx) {
44272ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  int pattern_length = pattern.length();
44282ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  ASSERT(pattern_length >= 1);
44292ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  ASSERT(idx + pattern_length <= subject.length());
4430b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4431b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
44322ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    for (int i = 0; i < pattern_length; i++) {
44332ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org      uc16 c = pattern[i];
443459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      if (c > String::kMaxOneByteCharCode) {
4435b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org        return -1;
4436b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      }
4437b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4438b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4439b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
44402ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  pchar pattern_first_char = pattern[0];
4441b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  for (int i = idx; i >= 0; i--) {
44422ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    if (subject[i] != pattern_first_char) continue;
4443b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    int j = 1;
44442ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    while (j < pattern_length) {
44452ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org      if (pattern[j] != subject[i+j]) {
4446b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org        break;
4447b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      }
4448b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      j++;
4449b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
44502ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org    if (j == pattern_length) {
4451b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org      return i;
4452b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4453b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4454b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  return -1;
4455b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org}
4456b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4457e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
4458a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
44596e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
446043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
446143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4462f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4463f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
44648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
446543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
446643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t start_index;
446730ce411529579186181838984710b0b0980857aaricow@chromium.org  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
446843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4469b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  uint32_t pat_length = pat->length();
4470bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  uint32_t sub_length = sub->length();
447143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4472b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  if (start_index + pat_length > sub_length) {
4473b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    start_index = sub_length - pat_length;
4474bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  }
447543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4476b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  if (pat_length == 0) {
4477b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    return Smi::FromInt(start_index);
4478b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4479b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
44809e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  sub = String::Flatten(sub);
44819e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  pat = String::Flatten(pat);
4482b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4483ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  int position = -1;
448479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4485b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4486ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent sub_content = sub->GetFlatContent();
4487ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent pat_content = pat->GetFlatContent();
4488b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4489ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (pat_content.IsAscii()) {
449059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
4491ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (sub_content.IsAscii()) {
449259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      position = StringMatchBackwards(sub_content.ToOneByteVector(),
4493b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4494b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4495b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    } else {
4496ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      position = StringMatchBackwards(sub_content.ToUC16Vector(),
4497b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4498b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4499b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4500b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  } else {
4501ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
4502ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (sub_content.IsAscii()) {
450359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      position = StringMatchBackwards(sub_content.ToOneByteVector(),
4504b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4505b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4506b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    } else {
4507ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      position = StringMatchBackwards(sub_content.ToUC16Vector(),
4508b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      pat_vector,
4509b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org                                      start_index);
4510b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org    }
4511b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  }
4512b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org
4513b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org  return Smi::FromInt(position);
451443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
451543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
451643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4517a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
45182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope handle_scope(isolate);
451943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
452043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
45222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
452343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
4525bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int str1_length = str1->length();
4526bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int str2_length = str2->length();
452743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
452843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Decide trivial cases without flattening.
452943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (str1_length == 0) {
453043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (str2_length == 0) return Smi::FromInt(0);  // Equal.
453143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Smi::FromInt(-str2_length);
453243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
453343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (str2_length == 0) return Smi::FromInt(str1_length);
453443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
453543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
453643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int end = str1_length < str2_length ? str1_length : str2_length;
453743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
453843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No need to flatten if we are going to find the answer on the first
453943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // character.  At this point we know there is at least one character
454043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in each string, due to the trivial case handling above.
4541bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int d = str1->Get(0) - str2->Get(0);
454243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (d != 0) return Smi::FromInt(d);
454343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  str1 = String::Flatten(str1);
45452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  str2 = String::Flatten(str2);
454643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_gc;
45482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  String::FlatContent flat1 = str1->GetFlatContent();
45492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  String::FlatContent flat2 = str2->GetFlatContent();
455043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
455143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < end; i++) {
45522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (flat1.Get(i) != flat2.Get(i)) {
45532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
45542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
455543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
455643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
455743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(str1_length - str2_length);
455843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
455943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
456043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4561a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_SubString) {
45624954674151afa960af66efb4831df06bde727333yangguo@chromium.org  HandleScope scope(isolate);
456343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
456443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45654954674151afa960af66efb4831df06bde727333yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
45666141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  int start, end;
45676141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // We have a fast integer-only case here to avoid a conversion to double in
45686141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  // the common case where from and to are Smis.
45696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (args[1]->IsSmi() && args[2]->IsSmi()) {
45706d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_SMI_ARG_CHECKED(from_number, 1);
45716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_SMI_ARG_CHECKED(to_number, 2);
45726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    start = from_number;
45736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    end = to_number;
45746141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  } else {
45756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
45766d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
4577ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    start = FastD2IChecked(from_number);
4578ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    end = FastD2IChecked(to_number);
45796141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
458043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(end >= start);
458143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(start >= 0);
45824954674151afa960af66efb4831df06bde727333yangguo@chromium.org  RUNTIME_ASSERT(end <= string->length());
4583ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->sub_string_runtime()->Increment();
45844954674151afa960af66efb4831df06bde727333yangguo@chromium.org
45854954674151afa960af66efb4831df06bde727333yangguo@chromium.org  return *isolate->factory()->NewSubString(string, start, end);
458643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
458743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
458843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4589a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringMatch) {
45906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope handles(isolate);
45918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 3);
459241826e77311db718135ef6517b846933dfd275f3ager@chromium.org
4593f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4594f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4595f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
459641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
4597a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
4598a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
4599355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4600a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
4601471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
4602355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int capture_count = regexp->CaptureCount();
4603d922884ea003c46279731a1528135f57788e9128yangguo@chromium.org
4604c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
4605c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneList<int> offsets(8, zone_scope.zone());
4606355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4607355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  while (true) {
4608355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int32_t* match = global_cache.FetchNext();
4609355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (match == NULL) break;
4610c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    offsets.Add(match[0], zone_scope.zone());  // start
4611c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    offsets.Add(match[1], zone_scope.zone());  // end
4612355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
4613355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4614a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
4615355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4616355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (offsets.length() == 0) {
4617355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // Not a single match.
4618355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    return isolate->heap()->null_value();
4619355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
4620355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4621355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  RegExpImpl::SetLastMatchInfo(regexp_info,
4622355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               subject,
4623355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               capture_count,
4624355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                               global_cache.LastSuccessfulMatch());
4625355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
462641826e77311db718135ef6517b846933dfd275f3ager@chromium.org  int matches = offsets.length() / 2;
4627ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
4628355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Handle<String> substring =
4629355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
463004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  elements->set(0, *substring);
4631355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  for (int i = 1; i < matches; i++) {
4632355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    HandleScope temp_scope(isolate);
463341826e77311db718135ef6517b846933dfd275f3ager@chromium.org    int from = offsets.at(i * 2);
463441826e77311db718135ef6517b846933dfd275f3ager@chromium.org    int to = offsets.at(i * 2 + 1);
4635355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    Handle<String> substring =
4636355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        isolate->factory()->NewProperSubString(subject, from, to);
463704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    elements->set(i, *substring);
463841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  }
4639ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
464041826e77311db718135ef6517b846933dfd275f3ager@chromium.org  result->set_length(Smi::FromInt(matches));
464141826e77311db718135ef6517b846933dfd275f3ager@chromium.org  return *result;
464241826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
464341826e77311db718135ef6517b846933dfd275f3ager@chromium.org
464441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
464508eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
464608eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org// separate last match info.  See comment on that function.
4647355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgtemplate<bool has_capture>
4648a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic Object* SearchRegExpMultiple(
464908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Isolate* isolate,
465008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Handle<String> subject,
465108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Handle<JSRegExp> regexp,
465208eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    Handle<JSArray> last_match_array,
465378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    Handle<JSArray> result_array) {
465408eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  ASSERT(subject->IsFlat());
4655355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
465608eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
465708eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  int capture_count = regexp->CaptureCount();
465808eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  int subject_length = subject->length();
465908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
466078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  static const int kMinLengthToCache = 0x1000;
466178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
466278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  if (subject_length > kMinLengthToCache) {
466378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    Handle<Object> cached_answer(RegExpResultsCache::Lookup(
466478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        isolate->heap(),
466578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        *subject,
466678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        regexp->data(),
466709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
466878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (*cached_answer != Smi::FromInt(0)) {
466978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Handle<FixedArray> cached_fixed_array =
467078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          Handle<FixedArray>(FixedArray::cast(*cached_answer));
467178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // The cache FixedArray is a COW-array and can therefore be reused.
4672fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      JSArray::SetContent(result_array, cached_fixed_array);
467378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // The actual length of the result array is stored in the last element of
467478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // the backing store (the backing FixedArray may have a larger capacity).
467578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Object* cached_fixed_array_last_element =
467678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          cached_fixed_array->get(cached_fixed_array->length() - 1);
467778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
467878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      result_array->set_length(js_array_length);
467978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      RegExpImpl::SetLastMatchInfo(
468078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org          last_match_array, subject, capture_count, NULL);
468178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      return *result_array;
468278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
468378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
468478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
468578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4686a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
468778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
4688a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  // Ensured in Runtime_RegExpExecMultiple.
4689a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  ASSERT(result_array->HasFastObjectElements());
4690a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  Handle<FixedArray> result_elements(
4691a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      FixedArray::cast(result_array->elements()));
4692a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  if (result_elements->length() < 16) {
469378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
469478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
469578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
469678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  FixedArrayBuilder builder(result_elements);
469778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
469808eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  // Position to search from.
4699355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  int match_start = -1;
470008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  int match_end = 0;
470108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  bool first = true;
470208eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4703355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  // Two smis before and after the match, for very long strings.
4704355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  static const int kMaxBuilderEntriesPerRegExpMatch = 5;
4705355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4706355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  while (true) {
4707355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int32_t* current_match = global_cache.FetchNext();
4708355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (current_match == NULL) break;
4709355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    match_start = current_match[0];
471078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
4711355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (match_end < match_start) {
471278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      ReplacementStringBuilder::AddSubjectSlice(&builder,
4713355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                match_end,
4714355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                match_start);
4715355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
4716355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    match_end = current_match[1];
4717355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    {
4718355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      // Avoid accumulating new handles inside loop.
4719355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      HandleScope temp_scope(isolate);
4720355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      Handle<String> match;
4721355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (!first) {
4722355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        match = isolate->factory()->NewProperSubString(subject,
4723355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                       match_start,
4724355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                       match_end);
4725355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      } else {
4726355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        match = isolate->factory()->NewSubString(subject,
4727355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                 match_start,
4728355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                 match_end);
472908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org        first = false;
473008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org      }
473108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4732355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (has_capture) {
4733355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // Arguments array to replace function is match, captures, index and
4734355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // subject, i.e., 3 + capture count in total.
4735355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        Handle<FixedArray> elements =
4736355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            isolate->factory()->NewFixedArray(3 + capture_count);
4737355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4738355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        elements->set(0, *match);
4739355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        for (int i = 1; i <= capture_count; i++) {
4740355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          int start = current_match[i * 2];
4741355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          if (start >= 0) {
4742355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            int end = current_match[i * 2 + 1];
4743355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            ASSERT(start <= end);
4744355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            Handle<String> substring =
4745355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                isolate->factory()->NewSubString(subject, start, end);
4746355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            elements->set(i, *substring);
4747355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          } else {
4748355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            ASSERT(current_match[i * 2 + 1] < 0);
4749355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org            elements->set(i, isolate->heap()->undefined_value());
4750355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          }
475108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org        }
4752355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        elements->set(capture_count + 1, Smi::FromInt(match_start));
4753355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        elements->set(capture_count + 2, *subject);
475478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
4755355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      } else {
475678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        builder.Add(*match);
475708eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org      }
4758355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
4759355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
476008eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4761a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (global_cache.HasException()) return isolate->heap()->exception();
476208eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4763355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  if (match_start >= 0) {
4764355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    // Finished matching, with at least one match.
4765355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (match_end < subject_length) {
476678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      ReplacementStringBuilder::AddSubjectSlice(&builder,
4767355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                match_end,
4768355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                                subject_length);
476908eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org    }
4770355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
4771355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    RegExpImpl::SetLastMatchInfo(
4772355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        last_match_array, subject, capture_count, NULL);
4773355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
477478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    if (subject_length > kMinLengthToCache) {
477578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // Store the length of the result array into the last element of the
477678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // backing FixedArray.
477778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      builder.EnsureCapacity(1);
477878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      Handle<FixedArray> fixed_array = builder.array();
477978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      fixed_array->set(fixed_array->length() - 1,
478078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                       Smi::FromInt(builder.length()));
478178502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // Cache the result and turn the FixedArray into a COW array.
47829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      RegExpResultsCache::Enter(isolate,
47839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                subject,
47849fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                handle(regexp->data(), isolate),
47859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                fixed_array,
478678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
478778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    }
478878502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return *builder.ToJSArray(result_array);
4789355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  } else {
479078502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return isolate->heap()->null_value();  // No matches at all.
479108eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org  }
479208eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org}
479308eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
479408eb1967df423ad4c0e5ef188273b508921d43f9yangguo@chromium.org
4795efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org// This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
4796efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org// lastMatchInfoOverride to maintain the last match info, so we don't need to
4797efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org// set any other last match array info.
4798a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
4799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handles(isolate);
48006e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 4);
480125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
4802f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
4803f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
4804f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
4805f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
4806a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
4807a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(result_array->HasFastObjectElements());
480825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
48099e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  subject = String::Flatten(subject);
4810a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(regexp->GetFlags().is_global());
481125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
481225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  if (regexp->CaptureCount() == 0) {
481378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return SearchRegExpMultiple<false>(
481478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        isolate, subject, regexp, last_match_info, result_array);
481525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  } else {
481678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org    return SearchRegExpMultiple<true>(
481778502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org        isolate, subject, regexp, last_match_info, result_array);
481825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
481925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
482025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
482125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
4822a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToRadixString) {
4823e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
482443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
48256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(radix, 1);
4826c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  RUNTIME_ASSERT(2 <= radix && radix <= 36);
482743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4828eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Fast case where the result is a one character string.
4829c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  if (args[0]->IsSmi()) {
48306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int value = args.smi_at(0);
4831eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    if (value >= 0 && value < radix) {
4832eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      // Character array used for conversion.
4833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
4834e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return *isolate->factory()->
4835ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          LookupSingleCharacterStringFromCode(kCharTable[value]);
4836eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
4837eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
4838eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
4839eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Slow case.
48406d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
484177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(value)) {
4842e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return isolate->heap()->nan_string();
484343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
484477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isinf(value)) {
484543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (value < 0) {
4846e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return isolate->heap()->minus_infinity_string();
484743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
4848e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return isolate->heap()->infinity_string();
484943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
485043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToRadixCString(value, radix);
48518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
485243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4853e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *result;
485443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
485543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
485643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4857a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToFixed) {
4858e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
485943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
486043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
48626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4863ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  int f = FastD2IChecked(f_number);
4864a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // See DoubleToFixedCString for these constants:
4865a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(f >= 0 && f <= 20);
4866a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(!Double(value).IsSpecial());
486743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToFixedCString(value, f);
48688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
486943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4870e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *result;
487143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
487243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
487343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4874a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToExponential) {
4875e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
487643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
487743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48786d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
48796d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4880ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  int f = FastD2IChecked(f_number);
488143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(f >= -1 && f <= 20);
4882a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(!Double(value).IsSpecial());
488343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToExponentialCString(value, f);
48848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
488543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4886e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *result;
488743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
488843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
488943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4890a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToPrecision) {
4891e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
489243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
489343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48946d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
48956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4896ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  int f = FastD2IChecked(f_number);
489743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(f >= 1 && f <= 21);
4898a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(!Double(value).IsSpecial());
489943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* str = DoubleToPrecisionCString(value, f);
49008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
490143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  DeleteArray(str);
4902e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *result;
490343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
490443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
490543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4906a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsValidSmi) {
4907e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  SealHandleScope shs(isolate);
4908662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  ASSERT(args.length() == 1);
4909662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
4910662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
49118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return isolate->heap()->ToBoolean(Smi::IsValid(number));
4912662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
4913662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
4914662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
491543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns a single character string where first character equals
491643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// string->Get(index).
49179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
4918bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (index < static_cast<uint32_t>(string->length())) {
49199e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Factory* factory = string->GetIsolate()->factory();
49209e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return factory->LookupSingleCharacterStringFromCode(
49219e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        String::Flatten(string)->Get(index));
492243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
49239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return Execution::CharAt(string, index);
492443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
492543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
492643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4927202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
4928202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                                Handle<Object> object,
4929202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                                uint32_t index) {
493043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle [] indexing on Strings
493143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsString()) {
49329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
49339b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    if (!result->IsUndefined()) return result;
493443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
493543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
493643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle [] indexing on String objects
493743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsStringObjectWithCharacterAt(index)) {
49389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<JSValue> js_value = Handle<JSValue>::cast(object);
49399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> result =
49409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        GetCharAt(Handle<String>(String::cast(js_value->value())), index);
49419b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    if (!result->IsUndefined()) return result;
494243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
494343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49444452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  Handle<Object> result;
494543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
49464452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    Handle<Object> proto(object->GetPrototype(isolate), isolate);
49479b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    return Object::GetElement(isolate, proto, index);
49484452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  } else {
49499b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    return Object::GetElement(isolate, object, index);
495043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
495143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
495243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
495343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMUST_USE_RESULT
49552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgstatic MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
49560cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (key->IsName()) {
49570cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    return Handle<Name>::cast(key);
49580cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  } else {
49592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> converted;
49602ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
49612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, converted, Execution::ToString(isolate, key), Name);
49620cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    return Handle<Name>::cast(converted);
49630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
49640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
49650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
49660cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
49679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
49689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                               Handle<JSReceiver> object,
49699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                               Handle<Object> key) {
4970e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Check if the given key is an array index.
4971e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  uint32_t index;
4972e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (key->ToArrayIndex(&index)) {
49739e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
4974e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
4975e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
4976e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Convert the key to a name - possibly by calling back into JavaScript.
49772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Name> name;
49782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
4979e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
49809e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
4981e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
4982e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
49839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
4984202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
4985202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                               Handle<Object> object,
4986202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                               Handle<Object> key) {
498743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsUndefined() || object->IsNull()) {
49889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> args[2] = { key, object };
49892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return isolate->Throw<Object>(
49902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate->factory()->NewTypeError("non_object_property_load",
49912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                         HandleVector(args, 2)));
499243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
499343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
499443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the given key is an array index.
499543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
499630ce411529579186181838984710b0b0980857aaricow@chromium.org  if (key->ToArrayIndex(&index)) {
49972f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    return GetElementOrCharAt(isolate, object, index);
499843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
499943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5000750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Convert the key to a name - possibly by calling back into JavaScript.
50012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Name> name;
50022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
500343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // Check if the name is trivially convertible to an index and get
500543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the element if so.
500643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
50072f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    return GetElementOrCharAt(isolate, object, index);
500843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
50092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    return Object::GetProperty(object, name);
501043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
501143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
501243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
501343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5014a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetProperty) {
50152f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HandleScope scope(isolate);
501643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
501743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50188496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
50198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5020202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> result;
5021202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5022202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, result,
5023202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Runtime::GetObjectProperty(isolate, object, key));
50242f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return *result;
502543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
502643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
502743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5028750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
5029a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
5030865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  HandleScope scope(isolate);
50317c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  ASSERT(args.length() == 2);
50327c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
5033865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
5034865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
5035865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
50365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Fast cases for getting named properties of the receiver JSObject
50378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // itself.
50388bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  //
5039fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // The global proxy objects has to be excluded since LookupOwn on
50403291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // the global proxy object can return a valid result even though the
50418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // global proxy object never has properties.  This is the case
50428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // because the global proxy object forwards everything to its hidden
5043fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // prototype including own lookups.
50448bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  //
50458bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // Additionally, we need to make sure that we do not cache results
50468bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  // for objects that require access checks.
5047865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  if (receiver_obj->IsJSObject()) {
5048865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    if (!receiver_obj->IsJSGlobalProxy() &&
5049865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        !receiver_obj->IsAccessCheckNeeded() &&
5050865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        key_obj->IsName()) {
5051865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      DisallowHeapAllocation no_allocation;
5052865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
5053865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      Handle<Name> key = Handle<Name>::cast(key_obj);
5054c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      if (receiver->HasFastProperties()) {
5055c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Attempt to use lookup cache.
5056a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        Handle<Map> receiver_map(receiver->map(), isolate);
5057c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
5058e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        int index = keyed_lookup_cache->Lookup(receiver_map, key);
5059e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        if (index != -1) {
506057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          // Doubles are not cached, so raw read the value.
5061e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          Object* value = receiver->RawFastPropertyAt(
5062e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org              FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
5063c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          return value->IsTheHole()
5064c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              ? isolate->heap()->undefined_value()
5065c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              : value;
5066c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
5067c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Lookup cache miss.  Perform lookup and update the cache if
5068c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // appropriate.
5069c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        LookupResult result(isolate);
5070fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        receiver->LookupOwn(key, &result);
5071de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org        if (result.IsField()) {
5072e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          FieldIndex field_index = result.GetFieldIndex();
507357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          // Do not track double fields in the keyed lookup cache. Reading
507457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          // double values requires boxing.
5075bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org          if (!result.representation().IsDouble()) {
5076e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            keyed_lookup_cache->Update(receiver_map, key,
5077e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                field_index.GetKeyedLookupCacheIndex());
507857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          }
5079865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org          AllowHeapAllocation allow_allocation;
5080e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          return *JSObject::FastPropertyAt(receiver, result.representation(),
5081e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                           field_index);
5082c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
5083c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      } else {
5084c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Attempt dictionary lookup.
5085750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        NameDictionary* dictionary = receiver->property_dictionary();
5086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int entry = dictionary->FindEntry(key);
5087750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        if ((entry != NameDictionary::kNotFound) &&
5088c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            (dictionary->DetailsAt(entry).type() == NORMAL)) {
5089c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          Object* value = dictionary->ValueAt(entry);
5090c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (!receiver->IsGlobalObject()) return value;
5091b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          value = PropertyCell::cast(value)->value();
5092c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (!value->IsTheHole()) return value;
5093c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          // If value is the hole do the general lookup.
5094c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
50955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
5096865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) {
5097750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      // JSObject without a name key. If the key is a Smi, check for a
5098c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // definite out-of-bounds access to elements, which is a strong indicator
5099c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // that subsequent accesses will also call the runtime. Proactively
5100830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
5101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // doubles for those future calls in the case that the elements would
5102c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // become FAST_DOUBLE_ELEMENTS.
5103865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
5104c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ElementsKind elements_kind = js_object->GetElementsKind();
5105fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (IsFastDoubleElementsKind(elements_kind)) {
5106865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        Handle<Smi> key = Handle<Smi>::cast(key_obj);
5107865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        if (key->value() >= js_object->elements()->length()) {
5108830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          if (IsFastHoleyElementsKind(elements_kind)) {
5109830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            elements_kind = FAST_HOLEY_ELEMENTS;
5110830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          } else {
5111830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            elements_kind = FAST_ELEMENTS;
5112830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          }
51139e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org          RETURN_FAILURE_ON_EXCEPTION(
51149e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org              isolate, TransitionElements(js_object, elements_kind, isolate));
5115c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
5116fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      } else {
5117fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5118fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org               !IsFastElementsKind(elements_kind));
51195a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
51207c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    }
5121865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
51220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    // Fast case for string indexing using [] with a smi index.
5123865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<String> str = Handle<String>::cast(receiver_obj);
51246d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int index = args.smi_at(1);
512583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    if (index >= 0 && index < str->length()) {
51268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return *GetCharAt(str, index);
512783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
51287c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
51295a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
51305a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Fall back to GetObjectProperty.
5131202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> result;
5132202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5133202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, result,
5134865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
51352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return *result;
51367c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org}
51377c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
5138bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
5139bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.comstatic bool IsValidAccessor(Handle<Object> obj) {
5140bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
5141bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
5142bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
5143bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
514483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Implements part of 8.12.9 DefineOwnProperty.
514583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// There are 3 cases that lead here:
514683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 4b - define a new accessor property.
514783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Steps 9c & 12 - replace an existing data property with an accessor property.
514883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 12 - update an existing accessor property with an accessor or generic
514983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org//           descriptor.
5150a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) {
5151ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
51526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 5);
5153f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5154bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  RUNTIME_ASSERT(!obj->IsNull());
5155750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5156bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
5157bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  RUNTIME_ASSERT(IsValidAccessor(getter));
5158bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
5159bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  RUNTIME_ASSERT(IsValidAccessor(setter));
5160f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(unchecked, 4);
51615c838251403b0be9a882540f1922577abba4c872ager@chromium.org  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
51625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
51637ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
516488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  bool fast = obj->HasFastProperties();
5165b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  // DefineAccessor checks access rights.
516688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  JSObject::DefineAccessor(obj, name, getter, setter, attr);
51678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
516888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  if (fast) JSObject::TransformToFastProperties(obj, 0);
5169bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  return isolate->heap()->undefined_value();
51705c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
51715c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5172e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
517383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Implements part of 8.12.9 DefineOwnProperty.
517483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// There are 3 cases that lead here:
517583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 4a - define a new data property.
517683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Steps 9b & 12 - replace an existing accessor property with a data property.
517783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Step 12 - update an existing data property with a data or generic
517883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org//           descriptor.
5179a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
5180ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
51816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 4);
5182f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
5183750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5184bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
5185f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(unchecked, 3);
51865c838251403b0be9a882540f1922577abba4c872ager@chromium.org  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
51872c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
51882c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
5189b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  // Check access rights if needed.
5190b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  if (js_object->IsAccessCheckNeeded() &&
5191b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org      !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
5192b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org    return isolate->heap()->undefined_value();
5193b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  }
5194b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
5195e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  LookupResult lookup(isolate);
5196fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  js_object->LookupOwnRealNamedProperty(name, &lookup);
51975c838251403b0be9a882540f1922577abba4c872ager@chromium.org
51985c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Take special care when attributes are different and there is already
51995c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // a property. For simplicity we normalize the property which enables us
52005c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // to not worry about changing the instance_descriptor and creating a new
52015c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // map. The current version of SetObjectProperty does not handle attributes
52025c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // correctly in the case where a property is a field and is reset with
52035c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // new attributes.
5204e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  if (lookup.IsFound() &&
5205e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
52065c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // New attributes - normalize to avoid writing to instance descriptor
5207d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    if (js_object->IsJSGlobalProxy()) {
5208d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      // Since the result is a property, the prototype will exist so
5209d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      // we don't have to check for null.
5210d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com      js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
521183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    }
5212e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
5213e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (attr != lookup.GetAttributes() ||
5214e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        (lookup.IsPropertyCallbacks() &&
5215e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org         !lookup.GetCallbackObject()->IsAccessorInfo())) {
5216e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
5217e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    }
5218e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
52195c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Use IgnoreAttributes version since a readonly property may be
52205c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // overridden and SetProperty does not allow this.
52218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Object> result;
52228f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
52238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        isolate, result,
5224fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        JSObject::SetOwnPropertyIgnoreAttributes(
5225e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            js_object, name, obj_value, attr,
5226e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            Object::OPTIMAL_REPRESENTATION,
5227e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            ALLOW_AS_CONSTANT,
5228e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5229e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            JSReceiver::MAY_BE_STORE_FROM_KEYED,
5230e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            JSObject::DONT_FORCE_FIELD));
52314a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    return *result;
52325c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
52332c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
52348f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Object> result;
52358f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
52368f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, result,
5237c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      Runtime::ForceSetObjectProperty(
5238c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org          js_object, name, obj_value, attr,
5239c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org          JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
5240e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return *result;
52415c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
52425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
52435c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5244e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org// Return property without being observable by accessors or interceptors.
5245a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetDataProperty) {
52462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope scope(isolate);
5247e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 2);
5248e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
52502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return *JSObject::GetDataProperty(object, key);
5251e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
5252e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
5253e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
52548f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
52558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                               Handle<Object> object,
52568f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                               Handle<Object> key,
52578f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                               Handle<Object> value,
52588f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                               PropertyAttributes attr,
52598f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                               StrictMode strict_mode) {
5260ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
52619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
526243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsUndefined() || object->IsNull()) {
52639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Handle<Object> args[2] = { key, object };
526443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> error =
5265ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("non_object_property_store",
5266ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         HandleVector(args, 2));
52678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return isolate->Throw<Object>(error);
526843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
526943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (object->IsJSProxy()) {
52712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> name_object;
52722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (key->IsSymbol()) {
52732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      name_object = key;
52742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    } else {
52752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
52762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          isolate, name_object, Execution::ToString(isolate, key), Object);
52772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
5278528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Name> name = Handle<Name>::cast(name_object);
5279e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
5280e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                   attr,
5281e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                   strict_mode);
5282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
5283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
528443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the object isn't a JavaScript object, we ignore the store.
5285e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  if (!object->IsJSObject()) return value;
528643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
52889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
528943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the given key is an array index.
529043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
529130ce411529579186181838984710b0b0980857aaricow@chromium.org  if (key->ToArrayIndex(&index)) {
529243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
529343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // of a string using [] notation.  We need to support this too in
529443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // JavaScript.
529543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // In the case of a String object we just need to redirect the assignment to
529643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // the underlying string if the index is in range.  Since the underlying
529743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // string does nothing with the assignment then we can ignore such
529843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // assignments.
52999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (js_object->IsStringObjectWithCharacterAt(index)) {
5300e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      return value;
53019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
530243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
530349ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(js_object);
53045c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    if (js_object->HasExternalArrayElements() ||
53055c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org        js_object->HasFixedTypedArrayElements()) {
5306b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (!value->IsNumber() && !value->IsUndefined()) {
53072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        ASSIGN_RETURN_ON_EXCEPTION(
53082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            isolate, value, Execution::ToNumber(isolate, value), Object);
5309b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
5310b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
53119e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org
53129e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    MaybeHandle<Object> result = JSObject::SetElement(
53139e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        js_object, index, value, attr, strict_mode, true, set_mode);
531449ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(js_object);
53159e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org
5316e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    return result.is_null() ? result : value;
531743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
531843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5319750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
5320750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name = Handle<Name>::cast(key);
5321750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (name->AsArrayIndex(&index)) {
5322b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (js_object->HasExternalArrayElements()) {
5323b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        if (!value->IsNumber() && !value->IsUndefined()) {
53242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION(
53252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org              isolate, value, Execution::ToNumber(isolate, value), Object);
5326b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        }
5327b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      }
53289e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      return JSObject::SetElement(js_object, index, value, attr,
53299e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                  strict_mode, true, set_mode);
533043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
53319e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5332e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
533343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
533443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
533543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
533643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call-back into JavaScript to convert the key to a string.
53372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> converted;
53382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
53392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, converted, Execution::ToString(isolate, key), Object);
534043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> name = Handle<String>::cast(converted);
534143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
534243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
53439e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return JSObject::SetElement(js_object, index, value, attr,
53449e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                strict_mode, true, set_mode);
534543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
5346e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
534743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
534843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
534943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
535043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5351c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgMaybeHandle<Object> Runtime::ForceSetObjectProperty(
5352c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    Handle<JSObject> js_object,
5353c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    Handle<Object> key,
5354c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    Handle<Object> value,
5355c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    PropertyAttributes attr,
5356c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    JSReceiver::StoreFromKeyed store_from_keyed) {
53578f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Isolate* isolate = js_object->GetIsolate();
535865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Check if the given key is an array index.
535965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  uint32_t index;
536030ce411529579186181838984710b0b0980857aaricow@chromium.org  if (key->ToArrayIndex(&index)) {
536165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
536265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // of a string using [] notation.  We need to support this too in
536365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // JavaScript.
536465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // In the case of a String object we just need to redirect the assignment to
536565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // the underlying string if the index is in range.  Since the underlying
536665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // string does nothing with the assignment then we can ignore such
536765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // assignments.
536865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    if (js_object->IsStringObjectWithCharacterAt(index)) {
5369e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      return value;
537065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    }
537165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
53729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return JSObject::SetElement(js_object, index, value, attr,
53739e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                SLOPPY, false, DEFINE_PROPERTY);
537465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
537565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
5376750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
5377750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name = Handle<Name>::cast(key);
5378750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (name->AsArrayIndex(&index)) {
53799e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      return JSObject::SetElement(js_object, index, value, attr,
53809e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                  SLOPPY, false, DEFINE_PROPERTY);
538165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    } else {
53829e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5383fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      return JSObject::SetOwnPropertyIgnoreAttributes(
5384c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org          js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
5385c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org          ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5386c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org          store_from_keyed);
538765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    }
538865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
538965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
539065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Call-back into JavaScript to convert the key to a string.
53912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> converted;
53922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
53932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, converted, Execution::ToString(isolate, key), Object);
539465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  Handle<String> name = Handle<String>::cast(converted);
539565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
539665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  if (name->AsArrayIndex(&index)) {
53979e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return JSObject::SetElement(js_object, index, value, attr,
53989e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                SLOPPY, false, DEFINE_PROPERTY);
539965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  } else {
5400fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    return JSObject::SetOwnPropertyIgnoreAttributes(
5401c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org        js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
5402c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org        ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5403c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org        store_from_keyed);
540465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
540565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
540665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
540765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
54089e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
54099e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                                  Handle<JSReceiver> receiver,
54109e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                                  Handle<Object> key,
54119e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                                  JSReceiver::DeleteMode mode) {
5412e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  // Check if the given key is an array index.
5413e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  uint32_t index;
5414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (key->ToArrayIndex(&index)) {
5415e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // In Firefox/SpiderMonkey, Safari and Opera you can access the
5416e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // characters of a string using [] notation.  In the case of a
5417e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // String object we just need to redirect the deletion to the
5418e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // underlying string if the index is in range.  Since the
5419e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // underlying string does nothing with the deletion, we can ignore
5420e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // such deletions.
542184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (receiver->IsStringObjectWithCharacterAt(index)) {
54229e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      return isolate->factory()->true_value();
5423e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    }
5424e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
54259e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return JSReceiver::DeleteElement(receiver, index, mode);
5426e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
5427e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5428750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Name> name;
5429750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (key->IsName()) {
5430750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = Handle<Name>::cast(key);
5431e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  } else {
5432e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org    // Call-back into JavaScript to convert the key to a string.
54332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> converted;
54342ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
54352ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, converted, Execution::ToString(isolate, key), Object);
5436750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    name = Handle<String>::cast(converted);
5437e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
5438e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
54399e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
54409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return JSReceiver::DeleteProperty(receiver, name, mode);
5441e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org}
5442e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5443e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
5444a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
5445bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  HandleScope scope(isolate);
5446bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  RUNTIME_ASSERT(args.length() == 3);
5447bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org
5448bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5449bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
5450bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5451a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(key->IsUniqueName());
5452bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  return *JSObject::SetHiddenProperty(object, key, value);
5453bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org}
5454bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org
5455bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org
5456a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetProperty) {
5457e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  HandleScope scope(isolate);
54589ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
545943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5460e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5461e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5462e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
54636d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
54649ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  RUNTIME_ASSERT(
54659ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
546643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute attributes.
54679ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  PropertyAttributes attributes =
54689ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      static_cast<PropertyAttributes>(unchecked_attributes);
54699ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
5470486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode strict_mode = SLOPPY;
54719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  if (args.length() == 5) {
5472486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 4);
5473486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    strict_mode = strict_mode_arg;
547443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
54759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
54768f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Object> result;
54778f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
54788f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, result,
54798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      Runtime::SetObjectProperty(
54808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          isolate, object, key, value, attributes, strict_mode));
5481e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return *result;
548243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
548343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
548443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5485a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
548694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HandleScope scope(isolate);
548794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  RUNTIME_ASSERT(args.length() == 2);
548894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
548994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
549094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  JSObject::TransitionElementsKind(array, map->elements_kind());
549194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  return *array;
549294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
549394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
549494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
5495d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org// Set the native flag on the function.
54966fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org// This is used to decide if we should transform null and undefined
54976fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org// into the global object when doing call and apply.
5498a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetNativeFlag) {
549979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
55006fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  RUNTIME_ASSERT(args.length() == 1);
55016fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
5502e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  CONVERT_ARG_CHECKED(Object, object, 0);
55036fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
55046fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  if (object->IsJSFunction()) {
5505e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    JSFunction* func = JSFunction::cast(object);
5506d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    func->shared()->set_native(true);
55076fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  }
55086fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org  return isolate->heap()->undefined_value();
55096fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org}
55106fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
55116fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org
5512a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
55130cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  SealHandleScope shs(isolate);
55140cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  RUNTIME_ASSERT(args.length() == 1);
55158496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
55160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
55170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (object->IsJSFunction()) {
55180cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    JSFunction* func = JSFunction::cast(*object);
55190cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    func->shared()->set_inline_builtin(true);
55200cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
55210cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  return isolate->heap()->undefined_value();
55220cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
55230cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
55240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
5525a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
55266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
5527c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  RUNTIME_ASSERT(args.length() == 5);
5528f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(store_index, 1);
55308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5531f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
5532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
5533c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5534bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Object* raw_literal_cell = literals->get(literal_index);
5535bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  JSArray* boilerplate = NULL;
5536bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (raw_literal_cell->IsAllocationSite()) {
5537bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
5538bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    boilerplate = JSArray::cast(site->transition_info());
5539bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else {
5540bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    boilerplate = JSArray::cast(raw_literal_cell);
5541bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
5542bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<JSArray> boilerplate_object(boilerplate);
5543c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ElementsKind elements_kind = object->GetElementsKind();
5544830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(IsFastElementsKind(elements_kind));
5545c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Smis should never trigger transitions.
5546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!value->IsSmi());
5547c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (value->IsNumber()) {
5549830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastSmiElementsKind(elements_kind));
5550830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5551830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        ? FAST_HOLEY_DOUBLE_ELEMENTS
5552830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        : FAST_DOUBLE_ELEMENTS;
5553830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (IsMoreGeneralElementsKindTransition(
5554830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            boilerplate_object->GetElementsKind(),
5555830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            transitioned_kind)) {
5556830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5557830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    }
5558830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    JSObject::TransitionElementsKind(object, transitioned_kind);
5559830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
55607d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
5561c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    HeapNumber* number = HeapNumber::cast(*value);
5562c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    double_array->set(store_index, number->Number());
5563c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  } else {
55641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    if (!IsFastObjectElementsKind(elements_kind)) {
55651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
55661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          ? FAST_HOLEY_ELEMENTS
55671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          : FAST_ELEMENTS;
55681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      JSObject::TransitionElementsKind(object, transitioned_kind);
55691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      ElementsKind boilerplate_elements_kind =
55701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          boilerplate_object->GetElementsKind();
55711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
55721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              transitioned_kind)) {
55731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
55741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
55757d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    }
55767d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    FixedArray* object_array = FixedArray::cast(object->elements());
5577c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    object_array->set(store_index, *value);
5578c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
5579c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return *object;
5580c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
5581c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
5582c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
558388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// Check whether debugger and is about to step into the callback that is passed
558488d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// to a built-in function such as Array.forEach.
5585a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
55868496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
5587d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
558881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    return isolate->heap()->false_value();
558981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  }
559088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  CONVERT_ARG_CHECKED(Object, callback, 0);
559188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // We do not step into the callback if it's a builtin or not even a function.
55928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return isolate->heap()->ToBoolean(
55938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
559488d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org}
559588d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
559688d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
559788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// Set one shot breakpoints for the callback function that is passed to a
559888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org// built-in function such as Array.forEach to enable stepping into the callback.
5599a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
56008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
560188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  Debug* debug = isolate->debug();
560299aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  if (!debug->IsStepping()) return isolate->heap()->undefined_value();
56035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
560488d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  HandleScope scope(isolate);
560588d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // When leaving the callback, step out has been activated, but not performed
560688d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // if we do not leave the builtin.  To be able to step into the callback
560788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  // again, we need to clear the step out at this point.
560888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  debug->ClearStepOut();
56095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  debug->FloodWithOneShot(callback);
5610865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return isolate->heap()->undefined_value();
5611865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org}
5612865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
5613865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
5614a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org// The argument is a closure that is kept until the epilogue is called.
5615a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org// On exception, the closure is called, which returns the promise if the
5616a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org// exception is considered uncaught, or undefined otherwise.
5617a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
5618a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ASSERT(args.length() == 1);
5619865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  HandleScope scope(isolate);
5620a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
5621a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  isolate->debug()->PromiseHandlePrologue(promise_getter);
5622a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return isolate->heap()->undefined_value();
5623a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}
5624a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
5625a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
5626a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
5627a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ASSERT(args.length() == 0);
5628a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  SealHandleScope shs(isolate);
5629a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  isolate->debug()->PromiseHandleEpilogue();
563099aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  return isolate->heap()->undefined_value();
563188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org}
563288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
563388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
5634fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Set an own property, even if it is READ_ONLY.  If the property does not
563543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// exist, it will be added with attributes NONE.
5636a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
56374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  HandleScope scope(isolate);
563841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
56394a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
56404a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
56414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
564241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Compute attributes.
564341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  PropertyAttributes attributes = NONE;
564441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  if (args.length() == 4) {
5645f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
564641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    // Only attribute bits should be set.
564741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    RUNTIME_ASSERT(
564841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org        (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
564941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    attributes = static_cast<PropertyAttributes>(unchecked_value);
565041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  }
56518f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Object> result;
56528f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
56538f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, result,
5654fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSObject::SetOwnPropertyIgnoreAttributes(
56558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          object, name, value, attributes));
56564a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  return *result;
565743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
565843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
565943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5660a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DeleteProperty) {
5661ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  HandleScope scope(isolate);
566249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  ASSERT(args.length() == 3);
5663ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5664ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5665f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
5666486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
5667ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
56689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
56699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
56709e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result,
56719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      JSReceiver::DeleteProperty(object, key, delete_mode));
5672ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
567343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
567443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
567543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5676fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgstatic Object* HasOwnPropertyImplementation(Isolate* isolate,
5677fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                            Handle<JSObject> object,
5678fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                            Handle<Name> key) {
5679fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (JSReceiver::HasOwnProperty(object, key)) {
5680528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate->heap()->true_value();
5681528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
56829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Handle hidden prototypes.  If there's a hidden prototype above this thing
56839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // then we have to check it for properties, because they are supposed to
56849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // look like they are on this object.
568509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> proto(object->GetPrototype(), isolate);
56869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  if (proto->IsJSObject() &&
56879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org      Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
5688fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    return HasOwnPropertyImplementation(isolate,
5689fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                        Handle<JSObject>::cast(proto),
5690fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                        key);
56919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  }
56928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5693ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->false_value();
56949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}
56959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
56969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
5697fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_HasOwnProperty) {
56980fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  HandleScope scope(isolate);
569943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
57008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
57010fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
570243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  uint32_t index;
57047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  const bool key_is_array_index = key->AsArrayIndex(&index);
57057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
570643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Only JS objects can have properties.
57070fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  if (object->IsJSObject()) {
57080fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org    Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
57097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Fast case: either the key is a real named property or it is not
57107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // an array index and there are no interceptors or hidden
57117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // prototypes.
57120fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org    if (JSObject::HasRealNamedProperty(js_obj, key)) {
5713169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      ASSERT(!isolate->has_scheduled_exception());
5714e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      return isolate->heap()->true_value();
5715169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    } else {
57168496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5717169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
57180fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org    Map* map = js_obj->map();
57197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    if (!key_is_array_index &&
57207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        !map->has_named_interceptor() &&
57217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
57227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      return isolate->heap()->false_value();
57237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
57247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Slow case.
5725fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    return HasOwnPropertyImplementation(isolate,
5726fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                        Handle<JSObject>(js_obj),
5727fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                        Handle<Name>(key));
57280fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  } else if (object->IsString() && key_is_array_index) {
572943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Well, there is one exception:  Handle [] on strings.
57300fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org    Handle<String> string = Handle<String>::cast(object);
57317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    if (index < static_cast<uint32_t>(string->length())) {
57327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      return isolate->heap()->true_value();
573343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
573443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5735ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->false_value();
573643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
573743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
573843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5739a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_HasProperty) {
5740528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
574143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
5742528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5743528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
574443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5745528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bool result = JSReceiver::HasProperty(receiver, key);
57468496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5747a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (isolate->has_pending_exception()) return isolate->heap()->exception();
5748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return isolate->heap()->ToBoolean(result);
574943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
575043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
575143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5752a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_HasElement) {
5753528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
575443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
5755528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5756f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 1);
575743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5758528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bool result = JSReceiver::HasElement(receiver, index);
57598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return isolate->heap()->ToBoolean(result);
576143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
576243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
576343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5764a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
5765381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  HandleScope scope(isolate);
576643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
576743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5768381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5769381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
577043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  PropertyAttributes att = JSReceiver::GetOwnPropertyAttributes(object, key);
5772169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (att == ABSENT || (att & DONT_ENUM) != 0) {
57738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5774169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    return isolate->heap()->false_value();
5775169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
5776169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(!isolate->has_scheduled_exception());
5777169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return isolate->heap()->true_value();
577843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
577943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
578043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5781a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetPropertyNames) {
5782ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
578343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
5784f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5785202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<JSArray> result;
57862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
57872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  isolate->counters()->for_in()->Increment();
57882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<FixedArray> elements;
57892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
57909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate, elements,
57919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
57922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return *isolate->factory()->NewJSArrayWithElements(elements);
579343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
579443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
579543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
579643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns either a FixedArray as Runtime_GetPropertyNames,
579743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// or, if the given object has an enum cache that contains
579843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// all enumerable properties of the object and its prototypes
579943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// have none, the map of the object. This is used to speed up
580043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the check for deletions during a for-in.
5801a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
580279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
580343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
580443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5805f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
580643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
580743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (raw_object->IsSimpleEnum()) return raw_object->map();
580843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5809ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5810394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<JSReceiver> object(raw_object);
5811202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<FixedArray> content;
5812202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
58139fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate, content,
58149fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
581543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
581643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Test again, since cache may have been built by preceding call.
581743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsSimpleEnum()) return object->map();
581843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
581943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *content;
582043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
582143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
582243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5823fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Find the length of the prototype chain that is to be handled as one. If a
5824b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// prototype object is hidden it is to be viewed as part of the the object it
5825b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// is prototype for.
5826fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgstatic int OwnPrototypeChainLength(JSObject* obj) {
5827b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int count = 1;
5828b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Object* proto = obj->GetPrototype();
5829b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  while (proto->IsJSObject() &&
5830b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org         JSObject::cast(proto)->map()->is_hidden_prototype()) {
5831b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    count++;
5832b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    proto = JSObject::cast(proto)->GetPrototype();
5833b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5834b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return count;
5835b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5836b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5837b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5838fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Return the names of the own named properties.
5839b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5840034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org// args[1]: PropertyAttributes as int
5841fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
5842ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5843f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  ASSERT(args.length() == 2);
5844b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (!args[0]->IsJSObject()) {
5845ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
5846b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5847f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5848034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(filter_value, 1);
5849034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
5850b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5851b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Skip the global proxy as it has no properties and always delegates to the
5852b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // real global object.
5853b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->IsJSGlobalProxy()) {
5854b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Only collect names if access is permitted.
5855b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (obj->IsAccessCheckNeeded() &&
5856c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        !isolate->MayNamedAccess(
5857c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org            obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5858c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
58598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5860ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArray(0);
5861b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5862b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
5863b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5864b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5865b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Find the number of objects making up this.
5866fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  int length = OwnPrototypeChainLength(*obj);
5867b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5868fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // Find the number of own properties for each of the objects.
5869fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  ScopedVector<int> own_property_count(length);
5870b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int total_property_count = 0;
5871b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Handle<JSObject> jsproto = obj;
5872b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (int i = 0; i < length; i++) {
5873b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Only collect names if access is permitted.
5874b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (jsproto->IsAccessCheckNeeded() &&
5875c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        !isolate->MayNamedAccess(
5876c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org            jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5877c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
58788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5879ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArray(0);
5880b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5881b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    int n;
5882fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    n = jsproto->NumberOfOwnProperties(filter);
5883fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    own_property_count[i] = n;
5884b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    total_property_count += n;
5885b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (i < length - 1) {
5886b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5887b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5888b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5889b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5890b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Allocate an array with storage for all the property names.
5891ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> names =
5892ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFixedArray(total_property_count);
5893b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5894b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Get the property names.
5895b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  jsproto = obj;
58967c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  int next_copy_index = 0;
58970f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  int hidden_strings = 0;
5898b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  for (int i = 0; i < length; i++) {
5899fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
59000f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (i > 0) {
59010f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Names from hidden prototypes may already have been added
59020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // for inherited function template instances. Count the duplicates
59030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // and stub them out; the final copy pass at the end ignores holes.
59040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      for (int j = next_copy_index;
5905fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org           j < next_copy_index + own_property_count[i];
59060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org           j++) {
59070f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        Object* name_from_hidden_proto = names->get(j);
59080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        for (int k = 0; k < next_copy_index; k++) {
59090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          if (names->get(k) != isolate->heap()->hidden_string()) {
59100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            Object* name = names->get(k);
59110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            if (name_from_hidden_proto == name) {
59120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org              names->set(j, isolate->heap()->hidden_string());
59130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org              hidden_strings++;
59140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org              break;
59150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            }
59160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          }
59170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        }
59180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      }
59190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
5920fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    next_copy_index += own_property_count[i];
5921486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
5922486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // Hidden properties only show up if the filter does not skip strings.
5923381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
59240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      hidden_strings++;
5925b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5926b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    if (i < length - 1) {
5927b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5928b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
5929b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5930b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
59310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Filter out name of hidden properties object and
59320f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // hidden prototype duplicates.
59330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if (hidden_strings > 0) {
5934b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    Handle<FixedArray> old_names = names;
5935ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    names = isolate->factory()->NewFixedArray(
59360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        names->length() - hidden_strings);
5937b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    int dest_pos = 0;
5938b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    for (int i = 0; i < total_property_count; i++) {
5939b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      Object* name = old_names->get(i);
59404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (name == isolate->heap()->hidden_string()) {
59410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        hidden_strings--;
5942b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org        continue;
5943b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      }
5944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      names->set(dest_pos++, name);
5945b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    }
59460f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    ASSERT_EQ(0, hidden_strings);
5947b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5948b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5949ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(names);
5950b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5951b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5952b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5953fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Return the names of the own indexed properties.
5954b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5955fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
5956ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5957b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5958b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (!args[0]->IsJSObject()) {
5959ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
5960b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5961f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5962b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5963fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
5964ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
5965fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
5966ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(names);
5967b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5968b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5969b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5970b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return information on whether an object has a named or indexed interceptor.
5971b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5972a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
5973ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5974b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5975b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (!args[0]->IsJSObject()) {
5976b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Smi::FromInt(0);
5977b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
5978f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5979b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5980b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int result = 0;
5981b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasNamedInterceptor()) result |= 2;
5982b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasIndexedInterceptor()) result |= 1;
5983b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5984b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return Smi::FromInt(result);
5985b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
5986b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5987b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5988b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return property names from named interceptor.
5989b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
5990a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
5991ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
5992b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
5993f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5994b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5995b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasNamedInterceptor()) {
59963484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Handle<JSObject> result;
59979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
59989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return *result;
59999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
6000b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
6001ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
6002b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
6003b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6004b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6005b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Return element names from indexed interceptor.
6006b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// args[0]: object
6007a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
6008ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
6009b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  ASSERT(args.length() == 1);
6010f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
6011b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6012b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (obj->HasIndexedInterceptor()) {
60133484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Handle<JSObject> result;
60149fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
60159fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return *result;
60169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
6017b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
6018ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
6019b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
6020b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6021b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
6022fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_OwnKeys) {
60236e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
60248496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
6025f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
60262bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Handle<JSObject> object(raw_object);
6027496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
6028496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  if (object->IsJSGlobalProxy()) {
60296500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org    // Do access checks before going to the global object.
60306500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org    if (object->IsAccessCheckNeeded() &&
6031c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        !isolate->MayNamedAccess(
6032c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org            object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
6033c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
60348496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
6035ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArray(0);
60366500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org    }
60376500178338c947ac2fbfaa247656a2c09aaa5f59ricow@chromium.org
603809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> proto(object->GetPrototype(), isolate);
6039496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    // If proxy is detached we simply return an empty array.
6040ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
6041496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    object = Handle<JSObject>::cast(proto);
6042496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  }
6043496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
6044202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<FixedArray> contents;
6045202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
60469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate, contents,
6047fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
6048394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
60492bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // Some fast paths through GetKeysInFixedArrayFor reuse a cached
60502bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // property array and since the result is mutable we have to create
60512bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // a fresh clone on each invocation.
6052c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  int length = contents->length();
6053ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
6054c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  for (int i = 0; i < length; i++) {
6055c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    Object* entry = contents->get(i);
6056c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    if (entry->IsString()) {
6057c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      copy->set(i, entry);
6058c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    } else {
6059c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      ASSERT(entry->IsNumber());
6060ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      HandleScope scope(isolate);
6061ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<Object> entry_handle(entry, isolate);
6062ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<Object> entry_str =
6063ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->factory()->NumberToString(entry_handle);
6064c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      copy->set(i, *entry_str);
6065c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    }
6066c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
6067ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(copy);
60682bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com}
60692bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
60702bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
6071a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
607279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
607343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
60748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
607543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
607643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the frame holding the arguments.
607774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate);
607843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  it.AdvanceToArgumentsFrame();
607943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JavaScriptFrame* frame = it.frame();
608043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
608143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the actual number of provided arguments.
60824d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  const uint32_t n = frame->ComputeParametersCount();
608343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
608443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Try to convert the key to an index. If successful and within
608543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // index return the the argument from the frame.
608643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
60878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (raw_key->ToArrayIndex(&index) && index < n) {
608843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return frame->GetParameter(index);
608943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
609043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60915b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  HandleScope scope(isolate);
60928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (raw_key->IsSymbol()) {
6093750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    // Lookup in the initial Object.prototype object.
60942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> result;
60952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
60962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, result,
60978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        Object::GetProperty(isolate->initial_object_prototype(),
60988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                            Handle<Symbol>::cast(raw_key)));
60995b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    return *result;
6100750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
6101750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
610243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert the key to a string.
61032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> converted;
61042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
61058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, converted, Execution::ToString(isolate, raw_key));
610643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<String> key = Handle<String>::cast(converted);
610743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
610843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Try to convert the string key into an array index.
610943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (key->AsArrayIndex(&index)) {
611043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (index < n) {
611143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return frame->GetParameter(index);
611243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
61134452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      Handle<Object> initial_prototype(isolate->initial_object_prototype());
6114202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Handle<Object> result;
6115202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6116202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          isolate, result,
6117202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          Object::GetElement(isolate, initial_prototype, index));
61184452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      return *result;
611943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
612043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
612143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
612243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle special arguments properties.
61232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (String::Equals(isolate->factory()->length_string(), key)) {
61242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return Smi::FromInt(n);
61252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
61262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (String::Equals(isolate->factory()->callee_string(), key)) {
6127169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    JSFunction* function = frame->function();
6128486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (function->shared()->strict_mode() == STRICT) {
6129ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->Throw(*isolate->factory()->NewTypeError(
6130ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
6131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
6132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return function;
6133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
613443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
613543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Lookup in the initial Object.prototype object.
61362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
61372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
61382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
61392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object::GetProperty(isolate->initial_object_prototype(), key));
61405b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  return *result;
614143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
614243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
614343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6144a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ToFastProperties) {
6145528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
6146061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  ASSERT(args.length() == 1);
6147528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6148528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsJSObject() && !object->IsGlobalObject()) {
6149528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0);
6150528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6151528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return *object;
6152061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org}
6153061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
6154061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
6155a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ToBool) {
615679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
615743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
61588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, object, 0);
615943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61608496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return isolate->heap()->ToBoolean(object->BooleanValue());
616143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
616243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
616343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
616443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
616543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Possible optimizations: put the type string into the oddballs.
6166a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Typeof) {
616779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
61688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
61698496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
61704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (obj->IsNumber()) return isolate->heap()->number_string();
617143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  HeapObject* heap_obj = HeapObject::cast(obj);
617243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
617343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // typeof an undetectable object is 'undefined'
6174ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (heap_obj->map()->is_undetectable()) {
61754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->heap()->undefined_string();
6176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
617743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
617843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  InstanceType instance_type = heap_obj->map()->instance_type();
617943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (instance_type < FIRST_NONSTRING_TYPE) {
61804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->heap()->string_string();
618143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
618243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
618343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (instance_type) {
618443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case ODDBALL_TYPE:
618543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
61864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        return isolate->heap()->boolean_string();
618743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
618843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (heap_obj->IsNull()) {
61894acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        return FLAG_harmony_typeof
61904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            ? isolate->heap()->null_string()
61914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org            : isolate->heap()->object_string();
619243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
619343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(heap_obj->IsUndefined());
61944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->heap()->undefined_string();
6195f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    case SYMBOL_TYPE:
6196f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      return isolate->heap()->symbol_string();
6197c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org    case JS_FUNCTION_TYPE:
619834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    case JS_FUNCTION_PROXY_TYPE:
61994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->heap()->function_string();
620043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
620143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // For any kind of object not handled above, the spec rule for
620243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // host objects gives that it is okay to return "object"
62034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return isolate->heap()->object_string();
620443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
620543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
620643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
620743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
620859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgstatic bool AreDigits(const uint8_t*s, int from, int to) {
620925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  for (int i = from; i < to; i++) {
621025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (s[i] < '0' || s[i] > '9') return false;
621125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
621225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
621325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  return true;
621425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
621525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
621625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
621759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgstatic int ParseDecimalInteger(const uint8_t*s, int from, int to) {
621825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(to - from < 10);  // Overflow is not possible.
621925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  ASSERT(from < to);
622025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  int d = s[from] - '0';
622125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
622225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  for (int i = from + 1; i < to; i++) {
622325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    d = 10 * d + (s[i] - '0');
622425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
622525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
622625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  return d;
622725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org}
622825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
622925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
6230a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringToNumber) {
62312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope handle_scope(isolate);
623243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
62332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
62342ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  subject = String::Flatten(subject);
623525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
623625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  // Fast case: short integer or some sorts of junk values.
6237fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (subject->IsSeqOneByteString()) {
62382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    int len = subject->length();
623925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (len == 0) return Smi::FromInt(0);
624025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
62412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    DisallowHeapAllocation no_gc;
62422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
624325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    bool minus = (data[0] == '-');
624425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    int start_pos = (minus ? 1 : 0);
624525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
624625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (start_pos == len) {
6247ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->heap()->nan_value();
624825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    } else if (data[start_pos] > '9') {
624925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      // Fast check for a junk value. A valid string may start from a
62502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
62512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // or the 'I' character ('Infinity'). All of that have codes not greater
62522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // than '9' except 'I' and &nbsp;.
62536bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org      if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
6254ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return isolate->heap()->nan_value();
625525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      }
625625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
62572ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // The maximal/minimal smi has 10 digits. If the string has less digits
62582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // we know it will fit into the smi-data type.
625925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      int d = ParseDecimalInteger(data, start_pos, len);
626025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      if (minus) {
6261ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        if (d == 0) return isolate->heap()->minus_zero_value();
626225156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org        d = -d;
6263d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org      } else if (!subject->HasHashCode() &&
6264d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                 len <= String::kMaxArrayIndexSize &&
6265d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                 (len == 1 || data[0] != '0')) {
6266d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        // String hash is not calculated yet but all the data are present.
6267d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        // Update the hash field to speed up sequential convertions.
62685b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org        uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
6269d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org#ifdef DEBUG
6270d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        subject->Hash();  // Force hash calculation.
6271d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        ASSERT_EQ(static_cast<int>(subject->hash_field()),
6272d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org                  static_cast<int>(hash));
6273d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org#endif
6274d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org        subject->set_hash_field(hash);
627525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      }
627625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      return Smi::FromInt(d);
627725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    }
627825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  }
627925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
628025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org  // Slower case.
6281ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  int flags = ALLOW_HEX;
6282ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (FLAG_harmony_numeric_literals) {
6283ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // The current spec draft has not updated "ToNumber Applied to the String
6284ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
6285ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    flags |= ALLOW_OCTAL | ALLOW_BINARY;
6286ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
62872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
62882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return *isolate->factory()->NewNumber(StringToDouble(
62892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate->unicode_cache(), *subject, flags));
629043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
629143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
629243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6293a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NewString) {
62948496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  HandleScope scope(isolate);
62958496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 2);
629632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CONVERT_SMI_ARG_CHECKED(length, 0);
629732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
629832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  if (length == 0) return isolate->heap()->empty_string();
62998496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result;
630032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  if (is_one_byte) {
63018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
63028496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        isolate, result, isolate->factory()->NewRawOneByteString(length));
630332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  } else {
63048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
63058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        isolate, result, isolate->factory()->NewRawTwoByteString(length));
630643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
63078496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *result;
630832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
630943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
631043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6311a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TruncateString) {
6312f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
63138496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 2);
6314f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
631532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CONVERT_SMI_ARG_CHECKED(new_length, 1);
63163484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(new_length >= 0);
6317f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return *SeqString::Truncate(string, new_length);
631843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
631943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
632043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6321a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_URIEscape) {
63222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HandleScope scope(isolate);
63236e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
63242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
63259e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<String> string = String::Flatten(source);
6326a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(string->IsFlat());
6327255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<String> result;
6328255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6329255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate, result,
6330255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      string->IsOneByteRepresentationUnderneath()
6331255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            ? URIEscape::Escape<uint8_t>(isolate, source)
6332255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            : URIEscape::Escape<uc16>(isolate, source));
63332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  return *result;
633443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
633543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
633643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6337a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_URIUnescape) {
63382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HandleScope scope(isolate);
63396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
63402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
63419e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<String> string = String::Flatten(source);
6342a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  ASSERT(string->IsFlat());
6343255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<String> result;
6344255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6345255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate, result,
6346255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      string->IsOneByteRepresentationUnderneath()
6347255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            ? URIUnescape::Unescape<uint8_t>(isolate, source)
6348255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            : URIUnescape::Unescape<uc16>(isolate, source));
6349255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  return *result;
635043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
635143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
635243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6353a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_QuoteJSONString) {
6354f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HandleScope scope(isolate);
6355f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6356c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  ASSERT(args.length() == 1);
6357731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  Handle<Object> result;
6358731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6359731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
6360731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  return *result;
6361c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org}
6362c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
6363c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
6364a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
636572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  HandleScope scope(isolate);
63666e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
63678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
636872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  BasicJsonStringifier stringifier(isolate);
6369731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  Handle<Object> result;
6370731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
63718496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result, stringifier.Stringify(object));
6372731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  return *result;
637372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
637472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
637572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
6376a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringParseInt) {
63772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope handle_scope(isolate);
63788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 2);
63792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
63805b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
63812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
638243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  subject = String::Flatten(subject);
63842ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  double value;
6385870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
63862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  { DisallowHeapAllocation no_gc;
63872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    String::FlatContent flat = subject->GetFlatContent();
63882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
63892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // ECMA-262 section 15.1.2.3, empty string is NaN
63902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (flat.IsAscii()) {
63912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      value = StringToInt(
63922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          isolate->unicode_cache(), flat.ToOneByteVector(), radix);
63932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    } else {
63942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      value = StringToInt(
63952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          isolate->unicode_cache(), flat.ToUC16Vector(), radix);
63962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
63972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
63982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
63992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return *isolate->factory()->NewNumber(value);
640043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
640143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
640243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6403a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringParseFloat) {
64042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope shs(isolate);
64058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
64062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
640743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  subject = String::Flatten(subject);
64092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  double value = StringToDouble(
64102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
641143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return *isolate->factory()->NewNumber(value);
641343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
641443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
641543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6416a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgstatic inline bool ToUpperOverflows(uc32 character) {
6417a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // y with umlauts and the micro sign are the only characters that stop
6418a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // fitting into one-byte when converting to uppercase.
6419a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  static const uc32 yuml_code = 0xff;
6420a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  static const uc32 micro_code = 0xb5;
6421a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  return (character == yuml_code || character == micro_code);
6422a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org}
6423a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
6424a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
642543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentemplate <class Converter>
6426a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* ConvertCaseHelper(
6427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
6428ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    String* string,
6429ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    SeqString* result,
6430ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    int result_length,
6431303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    unibrow::Mapping<Converter, 128>* mapping) {
6432ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  DisallowHeapAllocation no_gc;
6433bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // We try this twice, once with the assumption that the result is no longer
6434bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // than the input and, if that assumption breaks, again with the exact
6435bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // length.  This may not be pretty, but it is nicer than what was here before
6436bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // and I hereby claim my vaffel-is.
6437bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  //
64382efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // NOTE: This assumes that the upper/lower case of an ASCII
64392efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // character is also ASCII.  This is currently the case, but it
644043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // might break in the future if we implement more context and locale
644143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // dependent upper/lower conversions.
644243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool has_changed_character = false;
644343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
644443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert all characters to upper case, assuming that they will fit
644543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // in the buffer
64464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  Access<ConsStringIteratorOp> op(
64474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      isolate->runtime_state()->string_iterator());
6448ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  StringCharacterStream stream(string, op.value());
6449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  unibrow::uchar chars[Converter::kMaxWidth];
645043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // We can assume that the string is not empty
64514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  uc32 current = stream.GetNext();
6452a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
6453ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  for (int i = 0; i < result_length;) {
64544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    bool has_next = stream.HasMore();
64554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uc32 next = has_next ? stream.GetNext() : 0;
645643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int char_length = mapping->get(current, next, chars);
645743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (char_length == 0) {
645843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // The case conversion of this character is the character itself.
6459bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      result->Set(i, current);
646043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      i++;
6461a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    } else if (char_length == 1 &&
6462a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org               (ignore_overflow || !ToUpperOverflows(current))) {
646343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Common case: converting the letter resulted in one character.
646443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ASSERT(static_cast<uc32>(chars[0]) != current);
6465bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      result->Set(i, chars[0]);
646643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      has_changed_character = true;
646743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      i++;
6468ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    } else if (result_length == string->length()) {
6469a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      bool overflows = ToUpperOverflows(current);
647043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // We've assumed that the result would be as long as the
647143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // input but here is a character that converts to several
647243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // characters.  No matter, we calculate the exact length
647343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // of the result and try the whole thing again.
647443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      //
647543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Note that this leaves room for optimization.  We could just
647643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // memcpy what we already have to the result string.  Also,
647743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // the result string is the last object allocated we could
647843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // "realloc" it and probably, in the vast majority of cases,
647943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // extend the existing string to be able to hold the full
648043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // result.
64817c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      int next_length = 0;
64827c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      if (has_next) {
64837c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        next_length = mapping->get(next, 0, chars);
64847c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        if (next_length == 0) next_length = 1;
64857c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      }
64867c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      int current_length = i + char_length + next_length;
64874cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      while (stream.HasMore()) {
64884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        current = stream.GetNext();
6489a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org        overflows |= ToUpperOverflows(current);
64907c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // NOTE: we use 0 as the next character here because, while
64917c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // the next character may affect what a character converts to,
64927c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // it does not in any case affect the length of what it convert
64937c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        // to.
649443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        int char_length = mapping->get(current, 0, chars);
649543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (char_length == 0) char_length = 1;
64967c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        current_length += char_length;
64977010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org        if (current_length > String::kMaxLength) {
64987010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org          AllowHeapAllocation allocate_error_and_return;
64997010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org          return isolate->ThrowInvalidStringLength();
6500bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
650143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
6502e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      // Try again with the real length.  Return signed if we need
6503a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      // to allocate a two-byte string for to uppercase.
6504a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
6505a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org                                             : Smi::FromInt(current_length);
650643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
650743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      for (int j = 0; j < char_length; j++) {
6508bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        result->Set(i, chars[j]);
650943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        i++;
651043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
651143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      has_changed_character = true;
651243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
651343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    current = next;
651443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
651543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (has_changed_character) {
651643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return result;
651743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
651843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we didn't actually change anything in doing the conversion
651943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // we simple return the result and let the converted string
652043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // become garbage; there is no reason to keep two identical strings
652143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // alive.
6522ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    return string;
652343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
652443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
652543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
652643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6527ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgnamespace {
6528ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6529303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
653046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgstatic const uintptr_t kAsciiMask = kOneInEveryByte << 7;
6531303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6532303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// Given a word and two range boundaries returns a word with high bit
6533303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// set in every byte iff the corresponding input byte was strictly in
6534303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// the range (m, n). All the other bits in the result are cleared.
6535303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// This function is only useful when it can be inlined and the
6536303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// boundaries are statically known.
6537303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// Requires: all bytes in the input word and the boundaries must be
65382efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// ASCII (less than 0x7F).
6539303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
6540303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Use strict inequalities since in edge cases the function could be
6541303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // further simplified.
654246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  ASSERT(0 < m && m < n);
6543303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Has high bit set in every w byte less than n.
6544303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6545303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Has high bit set in every w byte greater than m.
6546303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6547303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6548303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org}
6549303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6550303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6551e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org#ifdef DEBUG
6552e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgstatic bool CheckFastAsciiConvert(char* dst,
6553ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org                                  const char* src,
6554e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                  int length,
6555e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                  bool changed,
6556e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                  bool is_to_lower) {
6557e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  bool expected_changed = false;
6558e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  for (int i = 0; i < length; i++) {
6559e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (dst[i] == src[i]) continue;
6560e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    expected_changed = true;
6561e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (is_to_lower) {
6562e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT('A' <= src[i] && src[i] <= 'Z');
6563e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT(dst[i] == src[i] + ('a' - 'A'));
6564e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    } else {
6565e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT('a' <= src[i] && src[i] <= 'z');
6566e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      ASSERT(dst[i] == src[i] - ('a' - 'A'));
6567e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
6568e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
6569e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return (expected_changed == changed);
6570e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
6571e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org#endif
6572ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6573303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
6574e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgtemplate<class Converter>
6575e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgstatic bool FastAsciiConvert(char* dst,
6576ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org                             const char* src,
6577e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                             int length,
6578e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                             bool* changed_out) {
6579303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef DEBUG
6580303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    char* saved_dst = dst;
6581ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    const char* saved_src = src;
6582303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
6583e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  DisallowHeapAllocation no_gc;
6584e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // We rely on the distance between upper and lower case letters
6585e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // being a known power of 2.
6586e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  ASSERT('a' - 'A' == (1 << 5));
6587e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Boundaries for the range of input characters than require conversion.
6588e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6589e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6590e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  bool changed = false;
6591e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  uintptr_t or_acc = 0;
6592ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  const char* const limit = src + length;
6593303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#ifdef V8_HOST_CAN_READ_UNALIGNED
6594e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Process the prefix of the input that requires no conversion one
6595e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // (machine) word at a time.
6596e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  while (src <= limit - sizeof(uintptr_t)) {
6597ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6598e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    or_acc |= w;
6599e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (AsciiRangeMask(w, lo, hi) != 0) {
6600e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      changed = true;
6601e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      break;
6602303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
6603e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    *reinterpret_cast<uintptr_t*>(dst) = w;
6604e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    src += sizeof(uintptr_t);
6605e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    dst += sizeof(uintptr_t);
6606e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
6607e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Process the remainder of the input performing conversion when
6608e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // required one word at a time.
6609e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  while (src <= limit - sizeof(uintptr_t)) {
6610ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6611e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    or_acc |= w;
6612e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    uintptr_t m = AsciiRangeMask(w, lo, hi);
6613e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // The mask has high (7th) bit set in every byte that needs
6614e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // conversion and we know that the distance between cases is
6615e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // 1 << 5.
6616e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6617e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    src += sizeof(uintptr_t);
6618e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    dst += sizeof(uintptr_t);
6619303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
6620303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org#endif
6621e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Process the last few bytes of the input (or the whole input if
6622e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // unaligned access is not supported).
6623e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  while (src < limit) {
6624e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    char c = *src;
6625e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    or_acc |= c;
6626e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (lo < c && c < hi) {
6627e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      c ^= (1 << 5);
6628e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      changed = true;
6629e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
6630e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    *dst = c;
6631e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    ++src;
6632e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    ++dst;
6633e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
6634e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  if ((or_acc & kAsciiMask) != 0) {
6635e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    return false;
6636e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
6637ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6638e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  ASSERT(CheckFastAsciiConvert(
6639e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org             saved_dst, saved_src, length, changed, Converter::kIsToLower));
6640ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6641e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  *changed_out = changed;
6642e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return true;
6643e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
6644ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6645ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}  // namespace
6646bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6647ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6648e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgtemplate <class Converter>
6649a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* ConvertCase(
66508496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<String> s,
6651ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
6652e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    unibrow::Mapping<Converter, 128>* mapping) {
66539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  s = String::Flatten(s);
6654ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  int length = s->length();
6655bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Assume that the string is not empty; we need this assumption later
6656ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  if (length == 0) return *s;
6657ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
66582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Simpler handling of ASCII strings.
6659ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  //
66602efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // NOTE: This assumes that the upper/lower case of an ASCII
66612efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // character is also ASCII.  This is currently the case, but it
6662ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // might break in the future if we implement more context and locale
6663ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // dependent upper/lower conversions.
6664ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  if (s->IsOneByteRepresentationUnderneath()) {
6665255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // Same length as input.
6666ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    Handle<SeqOneByteString> result =
6667255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6668ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    DisallowHeapAllocation no_gc;
6669ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    String::FlatContent flat_content = s->GetFlatContent();
6670ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    ASSERT(flat_content.IsFlat());
66719ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org    bool has_changed_character = false;
6672e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    bool is_ascii = FastAsciiConvert<Converter>(
667346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        reinterpret_cast<char*>(result->GetChars()),
6674ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org        reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
667546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        length,
667646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        &has_changed_character);
667746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    // If not ASCII, we discard the result and take the 2 byte path.
66788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    if (is_ascii) return has_changed_character ? *result : *s;
667946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  }
6680bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6681255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<SeqString> result;  // Same length as input.
6682ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  if (s->IsOneByteRepresentation()) {
6683255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6684ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  } else {
6685255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
6686303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
6687b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
6688a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
6689a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (answer->IsException() || answer->IsString()) return answer;
6690ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
6691ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  ASSERT(answer->IsSmi());
6692ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  length = Smi::cast(answer)->value();
6693ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  if (s->IsOneByteRepresentation() && length > 0) {
6694255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6695255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate, result, isolate->factory()->NewRawOneByteString(length));
6696ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  } else {
6697ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    if (length < 0) length = -length;
6698255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6699255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        isolate, result, isolate->factory()->NewRawTwoByteString(length));
6700bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
6701ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return ConvertCaseHelper(isolate, *s, *result, length, mapping);
6702bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
6703bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6704bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
6705a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringToLowerCase) {
67068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  HandleScope scope(isolate);
67078496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
67088496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6709e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return ConvertCase(
67108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      s, isolate, isolate->runtime_state()->to_lower_mapping());
671143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
671243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
671343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6714a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringToUpperCase) {
67158496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  HandleScope scope(isolate);
67168496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
67178496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6718e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return ConvertCase(
67198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      s, isolate, isolate->runtime_state()->to_upper_mapping());
672043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
672143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6722ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6723a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringTrim) {
67244954674151afa960af66efb4831df06bde727333yangguo@chromium.org  HandleScope scope(isolate);
67259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  ASSERT(args.length() == 3);
67269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
67274954674151afa960af66efb4831df06bde727333yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6728f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
6729f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
67309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
67319e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  string = String::Flatten(string);
67324954674151afa960af66efb4831df06bde727333yangguo@chromium.org  int length = string->length();
67339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
67349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  int left = 0;
6735f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  UnicodeCache* unicode_cache = isolate->unicode_cache();
67369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (trimLeft) {
6737f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    while (left < length &&
6738f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org           unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
67399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      left++;
67409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
67419d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
67429d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
67439d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  int right = length;
67449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  if (trimRight) {
6745f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    while (right > left &&
6746f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org           unicode_cache->IsWhiteSpaceOrLineTerminator(
6747f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               string->Get(right - 1))) {
67489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com      right--;
67499d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
67509d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  }
67514954674151afa960af66efb4831df06bde727333yangguo@chromium.org
67524954674151afa960af66efb4831df06bde727333yangguo@chromium.org  return *isolate->factory()->NewSubString(string, left, right);
67539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
675443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6755ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6756a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringSplit) {
6757ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handle_scope(isolate);
67586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 3);
6759f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6760f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
6761086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
67623484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(limit > 0);
6763086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6764086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int subject_length = subject->length();
6765086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int pattern_length = pattern->length();
6766086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  RUNTIME_ASSERT(pattern_length > 0);
6767086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6768486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (limit == 0xffffffffu) {
676909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> cached_answer(
677009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        RegExpResultsCache::Lookup(isolate->heap(),
677109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                   *subject,
677209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                   *pattern,
677309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                   RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
677409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        isolate);
6775486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    if (*cached_answer != Smi::FromInt(0)) {
677678502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org      // The cache FixedArray is a COW-array and can therefore be reused.
6777486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      Handle<JSArray> result =
6778486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          isolate->factory()->NewJSArrayWithElements(
6779486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org              Handle<FixedArray>::cast(cached_answer));
6780486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      return *result;
6781486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    }
6782486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
6783486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6784086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // The limit can be very large (0xffffffffu), but since the pattern
6785086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // isn't empty, we can never create more parts than ~half the length
6786086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // of the subject.
6787086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
67889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  subject = String::Flatten(subject);
67899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  pattern = String::Flatten(pattern);
6790086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6791086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  static const int kMaxInitialListCapacity = 16;
6792086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6793c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneScope zone_scope(isolate->runtime_zone());
6794086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6795086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Find (up to limit) indices of separator and end-of-string in subject
6796086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
6797c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ZoneList<int> indices(initial_capacity, zone_scope.zone());
6798d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
67991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  FindStringIndicesDispatch(isolate, *subject, *pattern,
6800c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                            &indices, limit, zone_scope.zone());
6801d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6802086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  if (static_cast<uint32_t>(indices.length()) < limit) {
6803c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    indices.Add(subject_length, zone_scope.zone());
6804086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
6805086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6806d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // The list indices now contains the end of each part to create.
6807086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6808086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  // Create JSArray of substrings separated by separator.
6809086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int part_count = indices.length();
6810086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6811ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6812c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  JSObject::EnsureCanContainHeapObjectElements(result);
6813086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  result->set_length(Smi::FromInt(part_count));
6814086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6815830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ASSERT(result->HasFastObjectElements());
6816086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6817086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  if (part_count == 1 && indices.at(0) == subject_length) {
6818086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    FixedArray::cast(result->elements())->set(0, *subject);
6819086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    return *result;
6820086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
6821086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6822086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  Handle<FixedArray> elements(FixedArray::cast(result->elements()));
6823086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int part_start = 0;
6824086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  for (int i = 0; i < part_count; i++) {
6825c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    HandleScope local_loop_handle(isolate);
6826086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    int part_end = indices.at(i);
6827086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    Handle<String> substring =
682804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        isolate->factory()->NewProperSubString(subject, part_start, part_end);
6829086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    elements->set(i, *substring);
6830086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    part_start = part_end + pattern_length;
6831086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
6832086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6833486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (limit == 0xffffffffu) {
6834830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (result->HasFastObjectElements()) {
68359fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      RegExpResultsCache::Enter(isolate,
68369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                subject,
68379fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                pattern,
68389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                elements,
683978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                                RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
684055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    }
6841486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  }
6842486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6843086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  return *result;
6844086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
6845086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
6846086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
68472efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copies ASCII characters to the given fixed array looking up
6848ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// one-char strings in the cache. Gives up on the first char that is
6849ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// not in the cache and fills the remainder with smi zeros. Returns
6850ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// the length of the successfully copied prefix.
6851ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic int CopyCachedAsciiCharsToArray(Heap* heap,
685259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                       const uint8_t* chars,
6853ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                       FixedArray* elements,
6854ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                       int length) {
685579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
6856ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  FixedArray* ascii_cache = heap->single_character_string_cache();
6857ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Object* undefined = heap->undefined_value();
6858ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int i;
6859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6860ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (i = 0; i < length; ++i) {
6861ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Object* value = ascii_cache->get(chars[i]);
6862ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (value == undefined) break;
6863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    elements->set(i, value, mode);
6864ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6865ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (i < length) {
6866ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(Smi::FromInt(0) == 0);
6867ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    memset(elements->data_start() + i, 0, kPointerSize * (length - i));
6868ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6869ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#ifdef DEBUG
6870ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int j = 0; j < length; ++j) {
6871ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Object* element = elements->get(j);
6872ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(element == Smi::FromInt(0) ||
6873ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org           (element->IsString() && String::cast(element)->LooksValid()));
6874ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6875ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#endif
6876ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return i;
6877ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
6878ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6879ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6880ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Converts a String to JSArray.
6881ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For example, "foo" => ["f", "o", "o"].
6882a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringToArray) {
6883ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
6884beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  ASSERT(args.length() == 2);
6885f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6886beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
6887ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
68889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  s = String::Flatten(s);
6889beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
6890ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6891ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<FixedArray> elements;
6892ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  int position = 0;
68938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (s->IsFlat() && s->IsOneByteRepresentation()) {
6894ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    // Try using cached chars where possible.
68959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    elements = isolate->factory()->NewUninitializedFixedArray(length);
68969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
689779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
6898ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    String::FlatContent content = s->GetFlatContent();
6899ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (content.IsAscii()) {
690059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> chars = content.ToOneByteVector();
6901ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      // Note, this will initialize all elements (not only the prefix)
6902ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      // to prevent GC from seeing partially initialized array.
6903ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      position = CopyCachedAsciiCharsToArray(isolate->heap(),
6904ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                             chars.start(),
6905ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                             *elements,
6906ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                             length);
6907ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    } else {
6908ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      MemsetPointer(elements->data_start(),
6909ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                    isolate->heap()->undefined_value(),
6910ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                    length);
6911ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
6912ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
6913ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    elements = isolate->factory()->NewFixedArray(length);
6914ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  }
6915ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  for (int i = position; i < length; ++i) {
691609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> str =
69179e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
6918ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    elements->set(i, *str);
6919ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6920ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6921ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#ifdef DEBUG
6922ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int i = 0; i < length; ++i) {
6923ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(String::cast(elements->get(i))->length() == 1);
6924ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
6925ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#endif
6926ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6927ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(elements);
6928ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
6929ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6930ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
6931a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NewStringWrapper) {
693274dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  HandleScope scope(isolate);
6933d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  ASSERT(args.length() == 1);
693474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
693574dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  return *Object::ToObject(isolate, value).ToHandleChecked();
6936d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org}
6937d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6938d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
6939ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgbool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
6940d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
6941ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
6942d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  return char_length == 0;
6943d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org}
6944d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
6945d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
6946a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NumberToString) {
6947e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
694843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
69498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
695043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6951e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NumberToString(number);
695243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
695343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
695443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6955a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NumberToStringSkipCache) {
6956e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
6957357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  ASSERT(args.length() == 1);
69588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
6959357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
6960e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NumberToString(number, false);
6961357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
6962357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
6963357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
6964a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToInteger) {
6965e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
696643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
696743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69686d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6969e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(DoubleToInteger(number));
697043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
697143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
697243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6973a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
6974e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
697530ce411529579186181838984710b0b0980857aaricow@chromium.org  ASSERT(args.length() == 1);
697630ce411529579186181838984710b0b0980857aaricow@chromium.org
69776d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
697830ce411529579186181838984710b0b0980857aaricow@chromium.org  double double_value = DoubleToInteger(number);
697930ce411529579186181838984710b0b0980857aaricow@chromium.org  // Map both -0 and +0 to +0.
698030ce411529579186181838984710b0b0980857aaricow@chromium.org  if (double_value == 0) double_value = 0;
698130ce411529579186181838984710b0b0980857aaricow@chromium.org
6982e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(double_value);
698330ce411529579186181838984710b0b0980857aaricow@chromium.org}
698430ce411529579186181838984710b0b0980857aaricow@chromium.org
698530ce411529579186181838984710b0b0980857aaricow@chromium.org
6986a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
6987e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
698843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
698943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6990ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
6991e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromUint(number);
699243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
699343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
699443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6995a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
6996e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
699743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
699843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69996d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
7000e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
700143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
700243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
700343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7004870a0b67c822d289024711912e2512af01b66c3bager@chromium.org// Converts a Number to a Smi, if possible. Returns NaN if the number is not
7005870a0b67c822d289024711912e2512af01b66c3bager@chromium.org// a small integer.
7006a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NumberToSmi) {
700779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
7008870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  ASSERT(args.length() == 1);
70098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
7010870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  if (obj->IsSmi()) {
7011870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    return obj;
7012870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  }
7013870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  if (obj->IsHeapNumber()) {
7014870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    double value = HeapNumber::cast(obj)->value();
7015870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    int int_value = FastD2I(value);
7016870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
7017870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      return Smi::FromInt(int_value);
7018870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    }
7019870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  }
7020ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->nan_value();
7021870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
7022870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
702365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
7024a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_AllocateHeapNumber) {
7025e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
7026a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 0);
7027e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewHeapNumber(0);
7028a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7029a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7030a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7031a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberAdd) {
7032e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
703343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
703443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
70366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7037e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(x + y);
703843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
703943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
704043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7041a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberSub) {
7042e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
704343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
704443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70456d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
70466d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7047e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(x - y);
704843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
704943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
705043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7051a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberMul) {
7052e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
705343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
705443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70556d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
70566d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7057e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(x * y);
705843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
705943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
706043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7061a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
7062e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
706343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
706443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70656d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7066e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(-x);
70676a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org}
70686a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
70696a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
7070a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberDiv) {
7071e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
707243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
707343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
70756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7076e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(x / y);
707743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
707843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
707943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7080a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberMod) {
7081e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
708243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
708343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70846d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
70856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7086e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(modulo(x, y));
708743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
708843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
708943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7090a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberImul) {
7091e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
7092ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ASSERT(args.length() == 2);
7093ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
7094ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7095ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7096e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(x * y);
7097ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
7098ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
7099ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
7100a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_StringAdd) {
71014954674151afa960af66efb4831df06bde727333yangguo@chromium.org  HandleScope scope(isolate);
710243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
71034954674151afa960af66efb4831df06bde727333yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
71044954674151afa960af66efb4831df06bde727333yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
7105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->string_add_runtime()->Increment();
7106255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<String> result;
7107255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7108255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate, result, isolate->factory()->NewConsString(str1, str2));
71097010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  return *result;
711043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
711143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
711243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7113c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgtemplate <typename sinkchar>
71145a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgstatic inline void StringBuilderConcatHelper(String* special,
71155a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                             sinkchar* sink,
71165a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                             FixedArray* fixed_array,
71175a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                                             int array_length) {
71188496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  DisallowHeapAllocation no_gc;
71195a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  int position = 0;
71205a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  for (int i = 0; i < array_length; i++) {
71215a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Object* element = fixed_array->get(i);
71225a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    if (element->IsSmi()) {
7123c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      // Smi encoding of position and length.
7124bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int encoded_slice = Smi::cast(element)->value();
7125c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int pos;
7126c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int len;
7127c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      if (encoded_slice > 0) {
7128c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in one smi.
7129c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        pos = StringBuilderSubstringPosition::decode(encoded_slice);
7130c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        len = StringBuilderSubstringLength::decode(encoded_slice);
7131c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      } else {
7132c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in two smis.
7133c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        Object* obj = fixed_array->get(++i);
7134c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        ASSERT(obj->IsSmi());
7135c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        pos = Smi::cast(obj)->value();
7136c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        len = -encoded_slice;
7137c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      }
7138870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      String::WriteToFlat(special,
7139870a0b67c822d289024711912e2512af01b66c3bager@chromium.org                          sink + position,
7140870a0b67c822d289024711912e2512af01b66c3bager@chromium.org                          pos,
7141870a0b67c822d289024711912e2512af01b66c3bager@chromium.org                          pos + len);
71425a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      position += len;
71435a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    } else {
71445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      String* string = String::cast(element);
7145bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int element_length = string->length();
7146bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      String::WriteToFlat(string, sink + position, 0, element_length);
71475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      position += element_length;
71485a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    }
71495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
71505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
71515a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
71525a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
71538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org// Returns the result length of the concatenation.
71548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org// On illegal argument, -1 is returned.
71558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgstatic inline int StringBuilderConcatLength(int special_length,
71568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                            FixedArray* fixed_array,
71578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                            int array_length,
71588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                            bool* one_byte) {
71598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  DisallowHeapAllocation no_gc;
716043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int position = 0;
716143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < array_length; i++) {
7162c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    int increment = 0;
716343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* elt = fixed_array->get(i);
716443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (elt->IsSmi()) {
7165c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      // Smi encoding of position and length.
7166c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      int smi_value = Smi::cast(elt)->value();
7167c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      int pos;
7168c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      int len;
7169c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      if (smi_value > 0) {
7170c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in one smi.
7171c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        pos = StringBuilderSubstringPosition::decode(smi_value);
7172c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        len = StringBuilderSubstringLength::decode(smi_value);
7173c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      } else {
7174c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        // Position and length encoded in two smis.
7175c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        len = -smi_value;
7176c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        // Get the position and check that it is a positive smi.
7177c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        i++;
71788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        if (i >= array_length) return -1;
7179c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        Object* next_smi = fixed_array->get(i);
71808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        if (!next_smi->IsSmi()) return -1;
7181c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org        pos = Smi::cast(next_smi)->value();
71828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        if (pos < 0) return -1;
718343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
7184c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      ASSERT(pos >= 0);
7185c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      ASSERT(len >= 0);
71868496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (pos > special_length || len > special_length - pos) return -1;
7187c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org      increment = len;
718843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else if (elt->IsString()) {
718943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      String* element = String::cast(elt);
7190bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      int element_length = element->length();
71910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      increment = element_length;
71928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (*one_byte && !element->HasOnlyOneByteChars()) {
71938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        *one_byte = false;
71949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      }
719543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
71968496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return -1;
719743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
71980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if (increment > String::kMaxLength - position) {
71998496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return kMaxInt;  // Provoke throw on allocation.
72009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    }
72010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    position += increment;
720243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
72038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return position;
72048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org}
720543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
7207a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
72088496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  HandleScope scope(isolate);
72098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 3);
72108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
72118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
72128496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(array_length, 1);
72138496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
72148496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
7215f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  size_t actual_array_length = 0;
7216f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(
7217f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      TryNumberToSize(isolate, array->length(), &actual_array_length));
7218f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(array_length >= 0);
7219f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
7220f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
72218496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  // This assumption is used by the slice encoding in one or two smis.
72228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(Smi::kMaxValue >= String::kMaxLength);
72238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72243484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(array->HasFastElements());
72258496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  JSObject::EnsureCanContainHeapObjectElements(array);
72268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72278496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  int special_length = special->length();
72288496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (!array->HasFastObjectElements()) {
72298496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
72308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  }
72318496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72328496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  int length;
72338496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  bool one_byte = special->HasOnlyOneByteChars();
72348496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72358496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  { DisallowHeapAllocation no_gc;
72368496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    FixedArray* fixed_array = FixedArray::cast(array->elements());
72378496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    if (fixed_array->length() < array_length) {
72388496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      array_length = fixed_array->length();
7239303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
72408496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72418496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    if (array_length == 0) {
72428496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return isolate->heap()->empty_string();
72438496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    } else if (array_length == 1) {
72448496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Object* first = fixed_array->get(0);
72458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (first->IsString()) return first;
72468496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    }
72478496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    length = StringBuilderConcatLength(
72488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        special_length, fixed_array, array_length, &one_byte);
72498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  }
72508496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (length == -1) {
72528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
72538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  }
72548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
72558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (one_byte) {
72568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<SeqOneByteString> answer;
72578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
72588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        isolate, answer,
72598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        isolate->factory()->NewRawOneByteString(length));
7260c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    StringBuilderConcatHelper(*special,
72615a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              answer->GetChars(),
72628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                              FixedArray::cast(array->elements()),
72635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              array_length);
72648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *answer;
726543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
72668496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<SeqTwoByteString> answer;
72678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
72688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        isolate, answer,
72698496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        isolate->factory()->NewRawTwoByteString(length));
7270c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    StringBuilderConcatHelper(*special,
72715a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              answer->GetChars(),
72728496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                              FixedArray::cast(array->elements()),
72735a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              array_length);
72748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *answer;
727543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
727643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
727743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
727843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7279a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
72807010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  HandleScope scope(isolate);
728149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  ASSERT(args.length() == 3);
72827010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
72837010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
72848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(array_length, 1);
72857010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
72867010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  RUNTIME_ASSERT(array->HasFastObjectElements());
7287a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(array_length >= 0);
728849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
72897010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
729049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (fixed_array->length() < array_length) {
729149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    array_length = fixed_array->length();
729249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
729349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
729449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (array_length == 0) {
7295ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->empty_string();
729649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  } else if (array_length == 1) {
729749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    Object* first = fixed_array->get(0);
72987010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    RUNTIME_ASSERT(first->IsString());
72997010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    return first;
730049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
730149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
730249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int separator_length = separator->length();
7303a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(separator_length > 0);
730449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int max_nof_separators =
730549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org      (String::kMaxLength + separator_length - 1) / separator_length;
730649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  if (max_nof_separators < (array_length - 1)) {
73077010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    return isolate->ThrowInvalidStringLength();
730849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
730949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int length = (array_length - 1) * separator_length;
731049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  for (int i = 0; i < array_length; i++) {
731149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    Object* element_obj = fixed_array->get(i);
73127010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    RUNTIME_ASSERT(element_obj->IsString());
731349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String* element = String::cast(element_obj);
731449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    int increment = element->length();
731549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    if (increment > String::kMaxLength - length) {
7316b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      STATIC_ASSERT(String::kMaxLength < kMaxInt);
7317b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      length = kMaxInt;  // Provoke exception;
7318b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      break;
731949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    }
732049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    length += increment;
732149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
732249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
7323255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<SeqTwoByteString> answer;
7324255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7325255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate, answer,
7326255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate->factory()->NewRawTwoByteString(length));
73277010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org
73287010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  DisallowHeapAllocation no_gc;
732949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
733049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  uc16* sink = answer->GetChars();
733149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org#ifdef DEBUG
733249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  uc16* end = sink + length;
733349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org#endif
733449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
7335a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(fixed_array->get(0)->IsString());
733649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  String* first = String::cast(fixed_array->get(0));
7337a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  String* separator_raw = *separator;
733849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  int first_length = first->length();
733949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  String::WriteToFlat(first, sink, 0, first_length);
734049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  sink += first_length;
734149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
734249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  for (int i = 1; i < array_length; i++) {
734349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    ASSERT(sink + separator_length <= end);
7344a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    String::WriteToFlat(separator_raw, sink, 0, separator_length);
734549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    sink += separator_length;
734649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
7347a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    RUNTIME_ASSERT(fixed_array->get(i)->IsString());
734849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String* element = String::cast(fixed_array->get(i));
734949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    int element_length = element->length();
735049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    ASSERT(sink + element_length <= end);
735149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    String::WriteToFlat(element, sink, 0, element_length);
735249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    sink += element_length;
735349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
735449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  ASSERT(sink == end);
735549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
735659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Use %_FastAsciiArrayJoin instead.
735759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(!answer->IsOneByteRepresentation());
73587010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  return *answer;
735949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org}
736049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
73618e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgtemplate <typename Char>
73628e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgstatic void JoinSparseArrayWithSeparator(FixedArray* elements,
73638e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         int elements_length,
73648e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         uint32_t array_length,
73658e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         String* separator,
73668e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                         Vector<Char> buffer) {
7367731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  DisallowHeapAllocation no_gc;
73688e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int previous_separator_position = 0;
73698e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int separator_length = separator->length();
73708e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int cursor = 0;
73718e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  for (int i = 0; i < elements_length; i += 2) {
73728e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int position = NumberToInt32(elements->get(i));
73738e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    String* string = String::cast(elements->get(i + 1));
73748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int string_length = string->length();
73758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (string->length() > 0) {
73768e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      while (previous_separator_position < position) {
73778e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        String::WriteToFlat<Char>(separator, &buffer[cursor],
73788e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                  0, separator_length);
73798e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        cursor += separator_length;
73808e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        previous_separator_position++;
73818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      }
73828e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      String::WriteToFlat<Char>(string, &buffer[cursor],
73838e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                0, string_length);
73848e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      cursor += string->length();
73858e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
73868e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
73878e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (separator_length > 0) {
73888e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Array length must be representable as a signed 32-bit number,
73898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // otherwise the total string length would have been too large.
73908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
73918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    int last_array_index = static_cast<int>(array_length - 1);
73928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    while (previous_separator_position < last_array_index) {
73938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      String::WriteToFlat<Char>(separator, &buffer[cursor],
73948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                0, separator_length);
73958e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      cursor += separator_length;
73968e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      previous_separator_position++;
73978e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
73988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
73998e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ASSERT(cursor <= buffer.length());
74008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
74018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
74028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
7403a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
740457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HandleScope scope(isolate);
74058e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ASSERT(args.length() == 3);
7406731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
74078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
7408731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
74098e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // elements_array is fast-mode JSarray of alternating positions
74108e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // (increasing order) and strings.
7411a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
74128e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // array_length is length of original array (used to add separators);
74138e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // separator is string to put between elements. Assumed to be non-empty.
7414a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(array_length > 0);
74158e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
74168e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Find total length of join result.
74178e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int string_length = 0;
74188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  bool is_ascii = separator->IsOneByteRepresentation();
74198e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  bool overflow = false;
7420731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
7421a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
74228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
7423a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  FixedArray* elements = FixedArray::cast(elements_array->elements());
7424a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  for (int i = 0; i < elements_length; i += 2) {
7425a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    RUNTIME_ASSERT(elements->get(i)->IsNumber());
7426a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
7427a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    RUNTIME_ASSERT(position < array_length);
7428a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    RUNTIME_ASSERT(elements->get(i + 1)->IsString());
7429a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
7430731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
7431731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  { DisallowHeapAllocation no_gc;
7432731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    for (int i = 0; i < elements_length; i += 2) {
7433731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      String* string = String::cast(elements->get(i + 1));
7434731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      int length = string->length();
7435731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      if (is_ascii && !string->IsOneByteRepresentation()) {
7436731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        is_ascii = false;
7437731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      }
7438731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      if (length > String::kMaxLength ||
7439731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org          String::kMaxLength - length < string_length) {
7440731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        overflow = true;
7441731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        break;
7442731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      }
7443731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      string_length += length;
74448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
74458e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
7446731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
74478e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int separator_length = separator->length();
74488e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (!overflow && separator_length > 0) {
74498e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    if (array_length <= 0x7fffffffu) {
74508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      int separator_count = static_cast<int>(array_length) - 1;
745186b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org      int remaining_length = String::kMaxLength - string_length;
74528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      if ((remaining_length / separator_length) >= separator_count) {
74538e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        string_length += separator_length * (array_length - 1);
74548e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      } else {
74558e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        // Not room for the separators within the maximal string length.
74568e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org        overflow = true;
74578e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      }
74588e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    } else {
74598e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      // Nonempty separator and at least 2^31-1 separators necessary
74608e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      // means that the string is too large to create.
74618e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
74628e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      overflow = true;
74638e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    }
74648e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
74658e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (overflow) {
746657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // Throw an exception if the resulting string is too large. See
746757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // https://code.google.com/p/chromium/issues/detail?id=336820
746857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // for details.
74697010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    return isolate->ThrowInvalidStringLength();
74708e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
74718e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
74728e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (is_ascii) {
7473731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
7474731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        string_length).ToHandleChecked();
7475731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    JoinSparseArrayWithSeparator<uint8_t>(
7476731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        FixedArray::cast(elements_array->elements()),
7477731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        elements_length,
7478731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        array_length,
7479731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        *separator,
7480731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        Vector<uint8_t>(result->GetChars(), string_length));
7481731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    return *result;
74828e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  } else {
7483731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
7484731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        string_length).ToHandleChecked();
7485731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    JoinSparseArrayWithSeparator<uc16>(
7486731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        FixedArray::cast(elements_array->elements()),
7487731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        elements_length,
7488731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        array_length,
7489731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        *separator,
7490731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        Vector<uc16>(result->GetChars(), string_length));
7491731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    return *result;
74928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
74938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
74948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
749549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
7496a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberOr) {
7497e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
749843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
749943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
750043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
750143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7502e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(x | y);
750343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
750443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
750543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7506a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberAnd) {
7507e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
750843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
750943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
751143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7512e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(x & y);
751343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
751443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
751543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7516a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberXor) {
7517e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
751843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
751943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
752143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7522e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(x ^ y);
752343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
752443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7526a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberShl) {
7527e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
752843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
752943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
753043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
753143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7532e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
753343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
753443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
753543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7536a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberShr) {
7537e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
753843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
753943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
754043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
754143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7542e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
754343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
754443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
754543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7546a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberSar) {
7547e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
754843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
754943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
755043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
755143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7552e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumberFromInt(
7553e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      ArithmeticShiftRight(x, y & 0x1f));
755443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
755543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
755643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7557a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberEquals) {
755879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
755943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
756043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
75626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
756377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
756477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
756543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (x == y) return Smi::FromInt(EQUAL);
756643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* result;
756743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
756843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = Smi::FromInt(EQUAL);
756943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
757043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = Smi::FromInt(NOT_EQUAL);
757143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
757243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
757343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
757443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
757543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7576a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringEquals) {
75772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope handle_scope(isolate);
757843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
757943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
75812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
758243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  bool not_equal = !String::Equals(x, y);
75845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // This is slightly convoluted because the value that signifies
75855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // equality is 0 and inequality is 1 so we have to negate the result
75865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // from String::Equals.
75875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  ASSERT(not_equal == 0 || not_equal == 1);
7588d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  STATIC_ASSERT(EQUAL == 0);
7589d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  STATIC_ASSERT(NOT_EQUAL == 1);
75905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return Smi::FromInt(not_equal);
759143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
759243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
759343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7594a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NumberCompare) {
759579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
759643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
759743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
75996d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7600f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
7601f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
760243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (x == y) return Smi::FromInt(EQUAL);
760343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (isless(x, y)) return Smi::FromInt(LESS);
760443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(GREATER);
760543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
760643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
760743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
76089258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Compare two Smis as if they were converted to strings and then
76099258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// compared lexicographically.
7610a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
761179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
76129258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  ASSERT(args.length() == 2);
7613f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(x_value, 0);
7614f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(y_value, 1);
76159258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76169258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // If the integers are equal so are the string representations.
76179258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (x_value == y_value) return Smi::FromInt(EQUAL);
76189258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // If one of the integers is zero the normal integer order is the
76209258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // same as the lexicographic order of the string representations.
76213cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_value == 0 || y_value == 0)
76223cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    return Smi::FromInt(x_value < y_value ? LESS : GREATER);
76239258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // If only one of the integers is negative the negative number is
76259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // smallest because the char code of '-' is less than the char code
76269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // of any digit.  Otherwise, we make both values positive.
76273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
76283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
76293cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // architectures using 32-bit Smis.
76303cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  uint32_t x_scaled = x_value;
76313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  uint32_t y_scaled = y_value;
76329258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  if (x_value < 0 || y_value < 0) {
76339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    if (y_value >= 0) return Smi::FromInt(LESS);
76349258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org    if (x_value >= 0) return Smi::FromInt(GREATER);
76353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    x_scaled = -x_value;
76363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    y_scaled = -y_value;
76379258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
76389258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76393cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  static const uint32_t kPowersOf10[] = {
76403cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    1, 10, 100, 1000, 10*1000, 100*1000,
76413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    1000*1000, 10*1000*1000, 100*1000*1000,
76423cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    1000*1000*1000
76433cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  };
76443cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
76453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // If the integers have the same number of decimal digits they can be
76463cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // compared directly as the numeric order is the same as the
76473cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // lexicographic order.  If one integer has fewer digits, it is scaled
76483cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // by some power of 10 to have the same number of digits as the longer
76493cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // integer.  If the scaled integers are equal it means the shorter
76503cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // integer comes first in the lexicographic order.
7651ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
76523cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
76533cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int x_log2 = IntegerLog2(x_scaled);
76543cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int x_log10 = ((x_log2 + 1) * 1233) >> 12;
76553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  x_log10 -= x_scaled < kPowersOf10[x_log10];
7656ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
76573cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int y_log2 = IntegerLog2(y_scaled);
76583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int y_log10 = ((y_log2 + 1) * 1233) >> 12;
76593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  y_log10 -= y_scaled < kPowersOf10[y_log10];
76609258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  int tie = EQUAL;
76623cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
76633cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_log10 < y_log10) {
76643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // X has fewer digits.  We would like to simply scale up X but that
76653cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
76663cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // be scaled up to 9_000_000_000. So we scale up by the next
76673cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // smallest power and scale down Y to drop one digit. It is OK to
76683cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // drop one digit from the longer integer since the final digit is
76693cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // past the length of the shorter integer.
76703cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
76713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    y_scaled /= 10;
76723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    tie = LESS;
76733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  } else if (y_log10 < x_log10) {
76743cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
76753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    x_scaled /= 10;
76763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    tie = GREATER;
76779258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
76789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
76803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
76813cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  return Smi::FromInt(tie);
76829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
76839258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
76849258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
7685a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_StringCompare) {
76862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  HandleScope handle_scope(isolate);
76872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSERT(args.length() == 2);
76882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
76892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
76902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
76912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
76922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  isolate->counters()->string_compare_runtime()->Increment();
76932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
76942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // A few fast case tests before we flatten.
76952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
76962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (y->length() == 0) {
76972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (x->length() == 0) return Smi::FromInt(EQUAL);
76982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return Smi::FromInt(GREATER);
76992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  } else if (x->length() == 0) {
77002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return Smi::FromInt(LESS);
7701ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7702ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
77032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int d = x->Get(0) - y->Get(0);
77042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (d < 0) return Smi::FromInt(LESS);
77052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  else if (d > 0) return Smi::FromInt(GREATER);
7706ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
77072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Slow case.
77082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  x = String::Flatten(x);
77092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  y = String::Flatten(y);
7710ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
77112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_gc;
7712ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Object* equal_prefix_result = Smi::FromInt(EQUAL);
7713ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int prefix_length = x->length();
7714ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (y->length() < prefix_length) {
7715ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    prefix_length = y->length();
7716ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    equal_prefix_result = Smi::FromInt(GREATER);
7717ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else if (y->length() > prefix_length) {
7718ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    equal_prefix_result = Smi::FromInt(LESS);
7719ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7720ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int r;
7721ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent x_content = x->GetFlatContent();
7722ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent y_content = y->GetFlatContent();
7723ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (x_content.IsAscii()) {
772459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
7725ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (y_content.IsAscii()) {
772659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7727086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7728ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    } else {
7729ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      Vector<const uc16> y_chars = y_content.ToUC16Vector();
7730ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7731ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
7732ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7733ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    Vector<const uc16> x_chars = x_content.ToUC16Vector();
7734ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (y_content.IsAscii()) {
773559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7736ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7737ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    } else {
7738ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      Vector<const uc16> y_chars = y_content.ToUC16Vector();
7739ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7740ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
7741ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7742ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Object* result;
7743ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (r == 0) {
7744ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    result = equal_prefix_result;
7745ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7746ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7747ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7748ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return result;
7749ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7750ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7751ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
77522f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org#define RUNTIME_UNARY_MATH(Name, name)                                         \
7753a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Math##Name) {                           \
7754e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);                                                  \
7755f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(args.length() == 1);                                                  \
77562f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  isolate->counters()->math_##name()->Increment();                             \
7757f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
7758e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewHeapNumber(std::name(x));                     \
7759f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
7760f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
77612f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgRUNTIME_UNARY_MATH(Acos, acos)
77622f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgRUNTIME_UNARY_MATH(Asin, asin)
77632f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgRUNTIME_UNARY_MATH(Atan, atan)
7764285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgRUNTIME_UNARY_MATH(LogRT, log)
7765f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#undef RUNTIME_UNARY_MATH
7766f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7767f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7768a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DoubleHi) {
7769e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
777043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
77716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7772ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  uint64_t integer = double_to_uint64(x);
7773ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  integer = (integer >> 32) & 0xFFFFFFFFu;
7774e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
777543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
777643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
777743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7778a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DoubleLo) {
7779e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
778043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7781052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7782e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(
7783ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org      static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
778443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
778543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
778643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7787a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ConstructDouble) {
7788e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
7789ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  ASSERT(args.length() == 2);
7790ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
7791ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
7792ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
7793e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(uint64_to_double(result));
779443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
779543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
779643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7797ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const double kPiDividedBy4 = 0.78539816339744830962;
7798ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
7799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
7800a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MathAtan2) {
7801e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
780243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
7803ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_atan2()->Increment();
780443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78056d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
78066d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
780743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  double result;
780877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isinf(x) && std::isinf(y)) {
780943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Make sure that the result in case of two infinite arguments
781043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // is a multiple of Pi / 4. The sign of the result is determined
781143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // by the first argument (x) and the sign of the second argument
781243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // determines the multiplier: one or three.
781343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int multiplier = (x < 0) ? -1 : 1;
781443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (y < 0) multiplier *= 3;
781543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result = multiplier * kPiDividedBy4;
781643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
7817e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    result = std::atan2(x, y);
781843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
7819e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(result);
782043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
782143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
782243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7823aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MathExpRT) {
7824e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
782543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7826ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_exp()->Increment();
782743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
78291f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  lazily_initialize_fast_exp();
7830e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(fast_exp(x));
783143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
783243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
783343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7834aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MathFloorRT) {
7835e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
783643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7837ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_floor()->Increment();
783843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78396d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7840e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(std::floor(x));
784143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
784243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
784343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
784464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// Slow version of Math.pow.  We check for fast paths for special cases.
78453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org// Used if VFP3 is not available.
7846a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_MathPowSlow) {
7847e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
784843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
7849ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_pow()->Increment();
785043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
78516d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
78525aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // If the second argument is a smi, it is much faster to call the
78545aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // custom powi() function than the generic pow().
78555aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (args[1]->IsSmi()) {
78566d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int y = args.smi_at(1);
7857e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return *isolate->factory()->NewNumber(power_double_int(x, y));
78585aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
78595aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
78606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
78612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  double result = power_helper(x, y);
786277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(result)) return isolate->heap()->nan_value();
7863e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(result);
786443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
786543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7866e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
786764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// Fast version of Math.pow if we know that y is not an integer and y is not
78682efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// -0.5 or 0.5.  Used as slow case from full codegen.
7869a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_MathPow) {
7870e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
7871ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
787264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  isolate->counters()->math_pow()->Increment();
787364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
78746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
78756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7876ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (y == 0) {
78775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    return Smi::FromInt(1);
7878ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
787964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    double result = power_double_double(x, y);
788077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    if (std::isnan(result)) return isolate->heap()->nan_value();
7881e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return *isolate->factory()->NewNumber(result);
7882ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7883ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7884ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
788543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7886a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RoundNumber) {
7887e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
788843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7889f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
7890ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_round()->Increment();
789143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7892f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (!input->IsHeapNumber()) {
7893f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    ASSERT(input->IsSmi());
7894f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    return *input;
7895cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
7896cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7897f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
7898cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7899cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  double value = number->value();
7900cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  int exponent = number->get_exponent();
7901cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  int sign = number->get_sign();
7902cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7903160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (exponent < -1) {
7904160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    // Number in range ]-0.5..0.5[. These always round to +/-zero.
7905160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (sign) return isolate->heap()->minus_zero_value();
7906160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    return Smi::FromInt(0);
7907160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  }
7908160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
7909160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
7910160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
79112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // argument holds for 32-bit smis).
7912160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (!sign && exponent < kSmiValueSize - 2) {
7913cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    return Smi::FromInt(static_cast<int>(value + 0.5));
7914cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
7915cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7916cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  // If the magnitude is big enough, there's no place for fraction part. If we
7917cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  // try to add 0.5 to this number, 1.0 will be added instead.
7918cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  if (exponent >= 52) {
7919f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    return *number;
7920cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
7921cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
7922ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
7923cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
79244111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // Do not call NumberFromDouble() to avoid extra checks.
7925e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(std::floor(value + 0.5));
792643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
792743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
792843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7929aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MathSqrtRT) {
7930e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
793143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
7932ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->math_sqrt()->Increment();
793343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
79346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7935e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(fast_sqrt(x));
793643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
793743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
793843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7939a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MathFround) {
7940e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
7941f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(args.length() == 1);
7942f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7943f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7944f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  float xf = static_cast<float>(x);
7945e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(xf);
7946f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
7947f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7948f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7949a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateMakeDay) {
795079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
7951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(args.length() == 2);
7952f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
79536d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(year, 0);
79546d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(month, 1);
7955f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
7956a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  int days = isolate->date_cache()->DaysFromYearMonth(year, month);
7957a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(Smi::IsValid(days));
7958a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return Smi::FromInt(days);
7959f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
7960f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
7961f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
7962a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateSetValue) {
79634efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  HandleScope scope(isolate);
79644efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  ASSERT(args.length() == 3);
7965f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
79664efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
79674efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(time, 1);
79684efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CONVERT_SMI_ARG_CHECKED(is_utc, 2);
79694efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
79704efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  DateCache* date_cache = isolate->date_cache();
79714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
7972e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<Object> value;;
79734efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  bool is_value_nan = false;
797477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(time)) {
7975e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    value = isolate->factory()->nan_value();
79764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    is_value_nan = true;
79774efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  } else if (!is_utc &&
79784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org             (time < -DateCache::kMaxTimeBeforeUTCInMs ||
79794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org              time > DateCache::kMaxTimeBeforeUTCInMs)) {
7980e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    value = isolate->factory()->nan_value();
79814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    is_value_nan = true;
7982f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  } else {
79834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
79844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    if (time < -DateCache::kMaxTimeInMs ||
79854efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org        time > DateCache::kMaxTimeInMs) {
7986e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      value = isolate->factory()->nan_value();
79874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      is_value_nan = true;
79884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    } else  {
7989e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      value = isolate->factory()->NewNumber(DoubleToInteger(time));
79904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    }
7991f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  }
7992e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  date->SetValue(*value, is_value_nan);
7993e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *value;
7994ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7995ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7996ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
79973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewSloppyArguments) {
79987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  HandleScope scope(isolate);
79997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(args.length() == 3);
80007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
80027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Object** parameters = reinterpret_cast<Object**>(args[1]);
80038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(argument_count, 2);
80047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Handle<JSObject> result =
80067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      isolate->factory()->NewArgumentsObject(callee, argument_count);
80077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Allocate the elements if needed.
80087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int parameter_count = callee->shared()->formal_parameter_count();
80097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (argument_count > 0) {
80107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (parameter_count > 0) {
80117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      int mapped_count = Min(argument_count, parameter_count);
80127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<FixedArray> parameter_map =
80137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
80147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      parameter_map->set_map(
8015486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          isolate->heap()->sloppy_arguments_elements_map());
80167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
8017ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      Handle<Map> map = Map::Copy(handle(result->map()));
8018ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
80197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
8020ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      result->set_map(*map);
80217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      result->set_elements(*parameter_map);
80227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Store the context and the arguments array at the beginning of the
80247b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // parameter map.
80257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<Context> context(isolate->context());
80267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<FixedArray> arguments =
80277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
80287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      parameter_map->set(0, *context);
80297b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      parameter_map->set(1, *arguments);
80307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Loop over the actual parameters backwards.
80327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      int index = argument_count - 1;
80337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      while (index >= mapped_count) {
80347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // These go directly in the arguments array and have no
80357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // corresponding slot in the parameter map.
80367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        arguments->set(index, *(parameters - index - 1));
80377b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        --index;
80387b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
80397b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
8040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
80417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      while (index >= 0) {
80427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        // Detect duplicate names to the right in the parameter list.
8043c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        Handle<String> name(scope_info->ParameterName(index));
8044c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        int context_local_count = scope_info->ContextLocalCount();
80457b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        bool duplicate = false;
80467b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        for (int j = index + 1; j < parameter_count; ++j) {
8047c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          if (scope_info->ParameterName(j) == *name) {
80487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            duplicate = true;
80497b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            break;
80507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
80517b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
80527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        if (duplicate) {
80547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // This goes directly in the arguments array with a hole in the
80557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // parameter map.
80567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          arguments->set(index, *(parameters - index - 1));
80577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          parameter_map->set_the_hole(index + 2);
80587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        } else {
80597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // The context index goes in the parameter map with a hole in the
80607b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          // arguments array.
80617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          int context_index = -1;
8062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          for (int j = 0; j < context_local_count; ++j) {
8063c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            if (scope_info->ContextLocalName(j) == *name) {
80647b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org              context_index = j;
80657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org              break;
80667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            }
80677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
80687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          ASSERT(context_index >= 0);
80697b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          arguments->set_the_hole(index);
8070c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          parameter_map->set(index + 2, Smi::FromInt(
8071c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              Context::MIN_CONTEXT_SLOTS + context_index));
80727b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
80737b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        --index;
80757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
80767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
80777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // If there is no aliasing, the arguments object elements are not
80787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // special in any way.
80797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Handle<FixedArray> elements =
80807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
80817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      result->set_elements(*elements);
80827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      for (int i = 0; i < argument_count; ++i) {
80837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        elements->set(i, *(parameters - i - 1));
80847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
80857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
80867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
80877b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return *result;
80887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
80897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
80913ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewStrictArguments) {
80929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HandleScope scope(isolate);
809341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  ASSERT(args.length() == 3);
80949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
809541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  Object** parameters = reinterpret_cast<Object**>(args[1]);
80969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(length, 2);
809741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
80989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<JSObject> result =
80999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate->factory()->NewArgumentsObject(callee, length);
8100b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
81019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (length > 0) {
81029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> array =
81039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate->factory()->NewUninitializedFixedArray(length);
810479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
8105b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
81069fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    for (int i = 0; i < length; i++) {
81079fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org      array->set(i, *--parameters, mode);
81089fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    }
81099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    result->set_elements(*array);
811041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  }
81119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return *result;
811241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org}
811341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
811441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
8115a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewClosureFromStubFailure) {
8116662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HandleScope scope(isolate);
8117662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  ASSERT(args.length() == 1);
8118662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
8119662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Handle<Context> context(isolate->context());
8120662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  PretenureFlag pretenure_flag = NOT_TENURED;
81218496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
81228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      shared,  context, pretenure_flag);
8123662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
8124662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
8125662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
8126a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewClosure) {
8127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
812821b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  ASSERT(args.length() == 3);
8129f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
8130f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
8131f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
813243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // The caller ensures that we pretenure closures that are assigned
813421b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  // directly to properties.
813521b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
81368496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
81378496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      shared, context, pretenure_flag);
813843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
813943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8140c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
8141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Find the arguments of the JavaScript function invocation that called
8142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// into C++ code. Collect these in a newly allocated array of handles (possibly
8143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// prefixed by a number of empty handles).
8144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic SmartArrayPointer<Handle<Object> > GetCallerArguments(
8145c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    Isolate* isolate,
8146394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int prefix_argc,
8147a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    int* total_argc) {
8148c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // Find frame containing arguments passed to the caller.
8149c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  JavaScriptFrameIterator it(isolate);
8150c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  JavaScriptFrame* frame = it.frame();
8151c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  List<JSFunction*> functions(2);
8152c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  frame->GetFunctions(&functions);
8153c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (functions.length() > 1) {
8154659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int inlined_jsframe_index = functions.length() - 1;
8155659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JSFunction* inlined_function = functions[inlined_jsframe_index];
815657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    SlotRefValueBuilder slot_refs(
815757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        frame,
815857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        inlined_jsframe_index,
815957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        inlined_function->shared()->formal_parameter_count());
8160659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
816157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    int args_count = slot_refs.args_length();
8162c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
8163394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *total_argc = prefix_argc + args_count;
8164a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    SmartArrayPointer<Handle<Object> > param_data(
8165a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        NewArray<Handle<Object> >(*total_argc));
816657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    slot_refs.Prepare(isolate);
8167c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    for (int i = 0; i < args_count; i++) {
816857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      Handle<Object> val = slot_refs.GetNext(isolate, 0);
8169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      param_data[prefix_argc + i] = val;
8170c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
817157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    slot_refs.Finish(isolate);
8172659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
8173c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return param_data;
8174c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  } else {
8175c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    it.AdvanceToArgumentsFrame();
8176c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    frame = it.frame();
8177c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    int args_count = frame->ComputeParametersCount();
8178c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
8179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    *total_argc = prefix_argc + args_count;
8180a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    SmartArrayPointer<Handle<Object> > param_data(
8181a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        NewArray<Handle<Object> >(*total_argc));
8182c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    for (int i = 0; i < args_count; i++) {
818309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
8184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      param_data[prefix_argc + i] = val;
8185c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
8186c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return param_data;
8187c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
8188c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
8189c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
8190c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
8191a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
8192394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope scope(isolate);
8193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 4);
8194f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
819570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
819670ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
819770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
8198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8199394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // TODO(lrn): Create bound function in C++ code from premade shared info.
8200394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bound_function->shared()->set_bound(true);
8201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Get all arguments of calling function (Function.prototype.bind).
8202394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int argc = 0;
8203c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  SmartArrayPointer<Handle<Object> > arguments =
8204c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      GetCallerArguments(isolate, 0, &argc);
8205394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Don't count the this-arg.
8206394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (argc > 0) {
820770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org    RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
8208394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    argc--;
8209394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
821070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org    RUNTIME_ASSERT(this_object->IsUndefined());
8211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Initialize array of bindings (function, this, and any existing arguments
8213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // if the function was already bound).
8214394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArray> new_bindings;
8215394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int i;
8216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
8217394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<FixedArray> old_bindings(
8218394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        JSFunction::cast(*bindee)->function_bindings());
82193484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
8220394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings =
8221394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        isolate->factory()->NewFixedArray(old_bindings->length() + argc);
822209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
822309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                            isolate);
8224394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    i = 0;
8225394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    for (int n = old_bindings->length(); i < n; i++) {
8226394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      new_bindings->set(i, old_bindings->get(i));
8227394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
8228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
8229394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
8230394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings = isolate->factory()->NewFixedArray(array_size);
8231394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
823270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org    new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
8233394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    i = 2;
8234394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8235394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Copy arguments, skipping the first which is "this_arg".
8236394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (int j = 0; j < argc; j++, i++) {
8237394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    new_bindings->set(i, *arguments[j + 1]);
8238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
823964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  new_bindings->set_map_no_write_barrier(
824064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      isolate->heap()->fixed_cow_array_map());
8241394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  bound_function->set_function_bindings(*new_bindings);
8242394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
824370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  // Update length. Have to remove the prototype first so that map migration
824470ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  // is happy about the number of fields.
824570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  RUNTIME_ASSERT(bound_function->RemovePrototype());
824670ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  Handle<Map> bound_function_map(
824770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      isolate->native_context()->bound_function_map());
824870ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  JSObject::MigrateToMap(bound_function, bound_function_map);
82494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> length_string = isolate->factory()->length_string();
8250394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PropertyAttributes attr =
8251394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
825270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  RETURN_FAILURE_ON_EXCEPTION(
825370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      isolate,
825470ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      JSObject::SetOwnPropertyIgnoreAttributes(bound_function, length_string,
825570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org                                               new_length, attr));
8256394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return *bound_function;
8257394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
8258394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8259394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8260a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
8261394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  HandleScope handles(isolate);
8262394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
8263f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
8264394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (callable->IsJSFunction()) {
8265394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
8266394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (function->shared()->bound()) {
8267394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray> bindings(function->function_bindings());
82683484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
8269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      return *isolate->factory()->NewJSArrayWithElements(bindings);
8270394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
8271394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8272394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return isolate->heap()->undefined_value();
8273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
8274394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8275394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8276a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
8277ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8278394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(args.length() == 1);
8279d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // First argument is a function to use as a constructor.
8280f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8281394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  RUNTIME_ASSERT(function->shared()->bound());
8282394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // The argument is a bound function. Extract its bound arguments
8284394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // and callable.
8285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<FixedArray> bound_args =
8286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
8287394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
8288394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Object> bound_function(
828909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
829009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      isolate);
8291394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(!bound_function->IsJSFunction() ||
8292394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com         !Handle<JSFunction>::cast(bound_function)->shared()->bound());
8293ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
8294c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  int total_argc = 0;
8295a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  SmartArrayPointer<Handle<Object> > param_data =
8296c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      GetCallerArguments(isolate, bound_argc, &total_argc);
8297d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  for (int i = 0; i < bound_argc; i++) {
8298394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    param_data[i] = Handle<Object>(bound_args->get(
829909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        JSFunction::kBoundArgumentsStartIndex + i), isolate);
8300ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  }
8301ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
8302394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (!bound_function->IsJSFunction()) {
83032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
83042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, bound_function,
83052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Execution::TryGetConstructorDelegate(isolate, bound_function));
8306394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8307394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(bound_function->IsJSFunction());
8308394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
83092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
83102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
83112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
8312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Execution::New(Handle<JSFunction>::cast(bound_function),
83132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                     total_argc, param_data.get()));
8314ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org  return *result;
8315ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org}
8316ba5a61b76d901fc18b36ae7bd97eaf938269c96ewhesse@chromium.org
831743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8318a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic Object* Runtime_NewObjectHelper(Isolate* isolate,
831969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org                                            Handle<Object> constructor,
832069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org                                            Handle<AllocationSite> site) {
83215aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // If the constructor isn't a proper function we throw a type error.
83225aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (!constructor->IsJSFunction()) {
83235aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
83245aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org    Handle<Object> type_error =
8325ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("not_constructor", arguments);
8326ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*type_error);
83275aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
832843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83295aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
83304111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
83314111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // If function should not have prototype, construction is not allowed. In this
83324111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // case generated code bailouts here, since function has no initial_map.
83337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (!function->should_have_prototype() && !function->shared()->bound()) {
83344111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
83354111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Handle<Object> type_error =
8336ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewTypeError("not_constructor", arguments);
8337ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*type_error);
83384111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
83394111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
8340ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Debug* debug = isolate->debug();
83415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Handle stepping into constructors if step into is active.
8342ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (debug->StepInActive()) {
8343ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
83445aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  }
834543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83465aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  if (function->has_initial_map()) {
83475aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org    if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
834843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // The 'Function' function ignores the receiver object when
834943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // called using 'new' and creates a new JSFunction object that
835043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // is returned.  The receiver object is only used for error
835143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // reporting if an error occurs when constructing the new
8352d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      // JSFunction. Factory::NewJSObject() should not be used to
83535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // allocate JSFunctions since it does not properly initialize
83545aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // the shared part of the function. Since the receiver is
83555aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // ignored anyway, we use the global object as the receiver
83565aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // instead of a new JSFunction object. This way, errors are
83575aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // reported the same way whether or not 'Function' is called
83585aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org      // using 'new'.
835946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      return isolate->context()->global_object();
836043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
836143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
836243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The function should be compiled for the optimization hints to be
83645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // available.
83654954674151afa960af66efb4831df06bde727333yangguo@chromium.org  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
836618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
836769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Handle<JSObject> result;
836869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (site.is_null()) {
836969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    result = isolate->factory()->NewJSObject(function);
837069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  } else {
837169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    result = isolate->factory()->NewJSObjectWithMemento(function, site);
837269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
837318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
8374ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->constructed_objects()->Increment();
8375ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->counters()->constructed_objects_runtime()->Increment();
837618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
83775aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  return *result;
837843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
837943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
838043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8381a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewObject) {
838269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  HandleScope scope(isolate);
838369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  ASSERT(args.length() == 1);
83848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
838569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return Runtime_NewObjectHelper(isolate,
838669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org                                 constructor,
838769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org                                 Handle<AllocationSite>::null());
838869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org}
838969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
839069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
8391a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewObjectWithAllocationSite) {
839269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  HandleScope scope(isolate);
839369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  ASSERT(args.length() == 2);
83948496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
83958496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
839669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Handle<AllocationSite> site;
839769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (feedback->IsAllocationSite()) {
839869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    // The feedback can be an AllocationSite or undefined.
839969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    site = Handle<AllocationSite>::cast(feedback);
840069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
84018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return Runtime_NewObjectHelper(isolate, constructor, site);
840269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org}
840369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
840469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
8405a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_FinalizeInstanceSize) {
8406ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
84074a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  ASSERT(args.length() == 1);
84084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8409f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8410011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  function->CompleteInobjectSlackTracking();
84114a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8412ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
84134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
84144a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
84154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
8416a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_CompileUnoptimized) {
8417ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
841843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
84198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
842043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
842126c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
84224954674151afa960af66efb4831df06bde727333yangguo@chromium.org    PrintF("[unoptimized: ");
8423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    function->PrintName();
842443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("]\n");
842543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
842643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
842743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
842834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // Compile the target function.
84294954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(function->shared()->allows_lazy_compilation());
84304954674151afa960af66efb4831df06bde727333yangguo@chromium.org
8431a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Handle<Code> code;
8432a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
8433a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                                     Compiler::GetUnoptimizedCode(function));
84344954674151afa960af66efb4831df06bde727333yangguo@chromium.org  function->ReplaceCode(*code);
843543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // All done. Return the compiled code.
8437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(function->is_compiled());
84384954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(function->code()->kind() == Code::FUNCTION ||
84394954674151afa960af66efb4831df06bde727333yangguo@chromium.org         (FLAG_always_opt &&
84404954674151afa960af66efb4831df06bde727333yangguo@chromium.org          function->code()->kind() == Code::OPTIMIZED_FUNCTION));
84414954674151afa960af66efb4831df06bde727333yangguo@chromium.org  return *code;
844243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
844343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
844443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8445a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_CompileOptimized) {
84464954674151afa960af66efb4831df06bde727333yangguo@chromium.org  HandleScope scope(isolate);
84474954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(args.length() == 2);
84488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
84494954674151afa960af66efb4831df06bde727333yangguo@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
84504954674151afa960af66efb4831df06bde727333yangguo@chromium.org
84514954674151afa960af66efb4831df06bde727333yangguo@chromium.org  Handle<Code> unoptimized(function->shared()->code());
84524954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!function->shared()->is_compiled()) {
84534954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // If the function is not compiled, do not optimize.
84544954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // This can happen if the debugger is activated and
84554954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // the function is returned to the not compiled state.
84564954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // TODO(yangguo): reconsider this.
84574954674151afa960af66efb4831df06bde727333yangguo@chromium.org    function->ReplaceCode(function->shared()->code());
84584954674151afa960af66efb4831df06bde727333yangguo@chromium.org  } else if (!isolate->use_crankshaft() ||
84594954674151afa960af66efb4831df06bde727333yangguo@chromium.org             function->shared()->optimization_disabled() ||
84604954674151afa960af66efb4831df06bde727333yangguo@chromium.org             isolate->DebuggerHasBreakPoints()) {
84614954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // If the function is not optimizable or debugger is active continue
84624954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // using the code from the full compiler.
8463c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    if (FLAG_trace_opt) {
8464c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      PrintF("[failed to optimize ");
8465c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      function->PrintName();
8466c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
8467750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org          function->shared()->optimization_disabled() ? "F" : "T",
84683847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          isolate->DebuggerHasBreakPoints() ? "T" : "F");
8469c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    }
84704954674151afa960af66efb4831df06bde727333yangguo@chromium.org    function->ReplaceCode(*unoptimized);
84714954674151afa960af66efb4831df06bde727333yangguo@chromium.org  } else {
84724954674151afa960af66efb4831df06bde727333yangguo@chromium.org    Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
84734954674151afa960af66efb4831df06bde727333yangguo@chromium.org                                                : Compiler::NOT_CONCURRENT;
8474a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    Handle<Code> code;
8475a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    if (Compiler::GetOptimizedCode(
8476a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org            function, unoptimized, mode).ToHandle(&code)) {
8477a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      function->ReplaceCode(*code);
8478a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    } else {
8479a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      function->ReplaceCode(*unoptimized);
8480a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    }
8481750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
8482750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
84834954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(function->code()->kind() == Code::FUNCTION ||
84844954674151afa960af66efb4831df06bde727333yangguo@chromium.org         function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
84854954674151afa960af66efb4831df06bde727333yangguo@chromium.org         function->IsInOptimizationQueue());
84865d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return function->code();
8487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8490b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgclass ActivationsFinder : public ThreadVisitor {
8491b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org public:
84923f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  Code* code_;
84933f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  bool has_code_activations_;
84943f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org
84953f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  explicit ActivationsFinder(Code* code)
84963f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    : code_(code),
84973f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org      has_code_activations_(false) { }
8498b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
8499b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
85003f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    JavaScriptFrameIterator it(isolate, top);
85013f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    VisitFrames(&it);
85023f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  }
8503b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
85043f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  void VisitFrames(JavaScriptFrameIterator* it) {
85053f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    for (; !it->done(); it->Advance()) {
85063f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org      JavaScriptFrame* frame = it->frame();
85073f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org      if (code_->contains(frame->pc())) has_code_activations_ = true;
8508b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
8509b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
8510b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org};
8511b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
8512b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
8513a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NotifyStubFailure) {
8514a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HandleScope scope(isolate);
8515a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(args.length() == 0);
8516a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
851779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(AllowHeapAllocation::IsAllowed());
8518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  delete deoptimizer;
8519a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return isolate->heap()->undefined_value();
8520a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
8521a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
8522a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
8523a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NotifyDeoptimized) {
8524ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
85268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(type_arg, 0);
8527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Deoptimizer::BailoutType type =
85288496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      static_cast<Deoptimizer::BailoutType>(type_arg);
8529ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
853079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  ASSERT(AllowHeapAllocation::IsAllowed());
8531a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
85323f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  Handle<JSFunction> function = deoptimizer->function();
85333f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  Handle<Code> optimized_code = deoptimizer->compiled_code();
85343f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org
85353f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
85363f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  ASSERT(type == deoptimizer->bailout_type());
8537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
853856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  // Make sure to materialize objects before causing any allocation.
8539a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  JavaScriptFrameIterator it(isolate);
854056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  deoptimizer->MaterializeHeapObjects(&it);
854144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  delete deoptimizer;
854244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
8543154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  JavaScriptFrame* frame = it.frame();
8544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RUNTIME_ASSERT(frame->function()->IsJSFunction());
8545c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  ASSERT(frame->function() == *function);
8546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Avoid doing too much work when running with --always-opt and keep
8548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // the optimized code around.
8549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8550ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
8551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
85533f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  // Search for other activations of the same function and code.
85543f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  ActivationsFinder activations_finder(*optimized_code);
85553f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  activations_finder.VisitFrames(&it);
85563f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
8557b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
85583f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org  if (!activations_finder.has_code_activations_) {
85593f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    if (function->code() == *optimized_code) {
85603f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org      if (FLAG_trace_deopt) {
85613f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org        PrintF("[removing optimized code for: ");
85623f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org        function->PrintName();
85633f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org        PrintF("]\n");
85643f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org      }
85653f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org      function->ReplaceCode(function->shared()->code());
8566f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      // Evict optimized code for this function from the cache so that it
8567f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      // doesn't get used for new closures.
8568f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
8569f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                                    "notify deoptimized");
8570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
857134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  } else {
85723f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
85733f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    // unconditionally if the code is not already marked for deoptimization.
85743f7dfd6b89fc3921382fbdc1212fabab54a19757titzer@chromium.org    // If there is an index by shared function info, all the better.
857534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    Deoptimizer::DeoptimizeFunction(*function);
8576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
85775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
8578ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
8579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8580a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8582a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
8583ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
8585f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8586ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
8587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Deoptimizer::DeoptimizeFunction(*function);
8589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
8591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8594a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
8595212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  HandleScope scope(isolate);
8596212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  ASSERT(args.length() == 1);
8597212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8598a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  function->shared()->ClearTypeFeedbackInfo();
8599212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  Code* unoptimized = function->shared()->code();
8600212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  if (unoptimized->kind() == Code::FUNCTION) {
8601212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    unoptimized->ClearInlineCaches();
8602212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  }
8603212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  return isolate->heap()->undefined_value();
8604212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org}
8605212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
8606212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
8607a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RunningInSimulator) {
860879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
86098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
86106d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#if defined(USE_SIMULATOR)
86116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return isolate->heap()->true_value();
86126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#else
86136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return isolate->heap()->false_value();
86146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#endif
86156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
86166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
86176d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
8618a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
86198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  SealHandleScope shs(isolate);
86203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  ASSERT(args.length() == 0);
86218496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return isolate->heap()->ToBoolean(
86228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate->concurrent_recompilation_enabled());
8623b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
8624b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
8625b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
8626a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
8627a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  HandleScope scope(isolate);
8628be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8629f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8630be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
86318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (!function->IsOptimizable() &&
86328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      !function->IsMarkedForConcurrentOptimization() &&
86338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      !function->IsInOptimizationQueue()) {
86348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return isolate->heap()->undefined_value();
86358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  }
86368297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
86374954674151afa960af66efb4831df06bde727333yangguo@chromium.org  function->MarkForOptimization();
8638be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
8639be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Code* unoptimized = function->shared()->code();
8640be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  if (args.length() == 2 &&
8641be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      unoptimized->kind() == Code::FUNCTION) {
8642be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8643750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
86443d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      // Start patching from the currently patched loop nesting level.
86453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      int current_level = unoptimized->allow_osr_at_loop_nesting_level();
8646528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
8647196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (FLAG_use_osr) {
8648196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
8649196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          unoptimized->set_allow_osr_at_loop_nesting_level(i);
8650196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
8651196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        }
8652e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      }
86534954674151afa960af66efb4831df06bde727333yangguo@chromium.org    } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent")) &&
86544954674151afa960af66efb4831df06bde727333yangguo@chromium.org               isolate->concurrent_recompilation_enabled()) {
86554954674151afa960af66efb4831df06bde727333yangguo@chromium.org      function->MarkForConcurrentOptimization();
8656750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
8657be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
8658be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
8659a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org  return isolate->heap()->undefined_value();
8660a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org}
8661a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org
8662a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org
8663a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
86646e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
86656e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
8666ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, function, 0);
8667ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  function->shared()->set_optimization_disabled(true);
86686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  return isolate->heap()->undefined_value();
86696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
86706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
86716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
8672a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
86731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  HandleScope scope(isolate);
8674ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8675e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  if (!isolate->use_crankshaft()) {
86761c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    return Smi::FromInt(4);  // 4 == "never".
86771c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
8678ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  bool sync_with_compiler_thread = true;
8679ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (args.length() == 2) {
8680ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
8681ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
8682ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      sync_with_compiler_thread = false;
8683ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    }
8684ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
86851044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
86869af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (isolate->concurrent_recompilation_enabled() &&
86879af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      sync_with_compiler_thread) {
86884954674151afa960af66efb4831df06bde727333yangguo@chromium.org    while (function->IsInOptimizationQueue()) {
8689ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8690ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      OS::Sleep(50);
8691304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
8692304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
86931c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  if (FLAG_always_opt) {
86941044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    // We may have always opt, but that is more best-effort than a real
86951044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    // promise, so we still say "no" if it is not optimized.
86961044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
86971044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org                                   : Smi::FromInt(2);  // 2 == "no".
86981c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
869910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  if (FLAG_deopt_every_n_times) {
870010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    return Smi::FromInt(6);  // 6 == "maybe deopted".
870110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  }
87021c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
87031c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                 : Smi::FromInt(2);  // 2 == "no".
87041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
87051c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
87061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
8707a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
87088496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
8709a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
8710b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
8711a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  isolate->optimizing_compiler_thread()->Unblock();
8712a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  return isolate->heap()->undefined_value();
8713a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org}
8714a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
8715a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
8716a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
87171c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  HandleScope scope(isolate);
87181c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  ASSERT(args.length() == 1);
8719f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
87201c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  return Smi::FromInt(function->shared()->opt_count());
87211c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
87221c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
87231c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
8724e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.orgstatic bool IsSuitableForOnStackReplacement(Isolate* isolate,
8725e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org                                            Handle<JSFunction> function,
87264954674151afa960af66efb4831df06bde727333yangguo@chromium.org                                            Handle<Code> current_code) {
8727e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // Keep track of whether we've succeeded in optimizing.
87284954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
8729e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // If we are trying to do OSR when there are already optimized
8730e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // activations of the function, it means (a) the function is directly or
8731e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // indirectly recursive and (b) an optimized invocation has been
8732e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // deoptimized so that we are currently in an unoptimized activation.
8733e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // Check for optimized activations of this function.
8734e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
8735e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    JavaScriptFrame* frame = it.frame();
8736e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    if (frame->is_optimized() && frame->function() == *function) return false;
8737e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  }
8738e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8739e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  return true;
8740e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org}
8741e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8742e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8743a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
8744ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
8745afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  ASSERT(args.length() == 1);
8746f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
87474954674151afa960af66efb4831df06bde727333yangguo@chromium.org  Handle<Code> caller_code(function->shared()->code());
87484954674151afa960af66efb4831df06bde727333yangguo@chromium.org
87494954674151afa960af66efb4831df06bde727333yangguo@chromium.org  // We're not prepared to handle a function with arguments object.
87504954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(!function->shared()->uses_arguments());
8751e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8752196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  RUNTIME_ASSERT(FLAG_use_osr);
8753196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8754afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  // Passing the PC in the javascript frame from the caller directly is
8755afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  // not GC safe, so we walk the stack to get it.
8756e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  JavaScriptFrameIterator it(isolate);
8757e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  JavaScriptFrame* frame = it.frame();
87584954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!caller_code->contains(frame->pc())) {
8759afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Code on the stack may not be the code object referenced by the shared
8760afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // function info.  It may have been replaced to include deoptimization data.
87614954674151afa960af66efb4831df06bde727333yangguo@chromium.org    caller_code = Handle<Code>(frame->LookupCode());
8762afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  }
8763afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
87644954674151afa960af66efb4831df06bde727333yangguo@chromium.org  uint32_t pc_offset = static_cast<uint32_t>(
87654954674151afa960af66efb4831df06bde727333yangguo@chromium.org      frame->pc() - caller_code->instruction_start());
8766afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
8767afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#ifdef DEBUG
8768e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  ASSERT_EQ(frame->function(), *function);
87694954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT_EQ(frame->LookupCode(), *caller_code);
87704954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(caller_code->contains(frame->pc()));
8771e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org#endif  // DEBUG
8772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
87744954674151afa960af66efb4831df06bde727333yangguo@chromium.org  BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
87754954674151afa960af66efb4831df06bde727333yangguo@chromium.org  ASSERT(!ast_id.IsNone());
87764954674151afa960af66efb4831df06bde727333yangguo@chromium.org
8777874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  Compiler::ConcurrencyMode mode =
8778874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org      isolate->concurrent_osr_enabled() &&
8779196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT
8780196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                   : Compiler::NOT_CONCURRENT;
8781e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  Handle<Code> result = Handle<Code>::null();
8782e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
87834954674151afa960af66efb4831df06bde727333yangguo@chromium.org  OptimizedCompileJob* job = NULL;
87844954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (mode == Compiler::CONCURRENT) {
87854954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // Gate the OSR entry with a stack check.
87864954674151afa960af66efb4831df06bde727333yangguo@chromium.org    BackEdgeTable::AddStackCheck(caller_code, pc_offset);
87874954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // Poll already queued compilation jobs.
87884954674151afa960af66efb4831df06bde727333yangguo@chromium.org    OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
87894954674151afa960af66efb4831df06bde727333yangguo@chromium.org    if (thread->IsQueuedForOSR(function, ast_id)) {
8790e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      if (FLAG_trace_osr) {
87914954674151afa960af66efb4831df06bde727333yangguo@chromium.org        PrintF("[OSR - Still waiting for queued: ");
8792e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org        function->PrintName();
87934954674151afa960af66efb4831df06bde727333yangguo@chromium.org        PrintF(" at AST id %d]\n", ast_id.ToInt());
8794e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      }
8795e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      return NULL;
8796e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    }
8797e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
87984954674151afa960af66efb4831df06bde727333yangguo@chromium.org    job = thread->FindReadyOSRCandidate(function, ast_id);
87994954674151afa960af66efb4831df06bde727333yangguo@chromium.org  }
8800e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
88014954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (job != NULL) {
88024954674151afa960af66efb4831df06bde727333yangguo@chromium.org    if (FLAG_trace_osr) {
88034954674151afa960af66efb4831df06bde727333yangguo@chromium.org      PrintF("[OSR - Found ready: ");
88044954674151afa960af66efb4831df06bde727333yangguo@chromium.org      function->PrintName();
88054954674151afa960af66efb4831df06bde727333yangguo@chromium.org      PrintF(" at AST id %d]\n", ast_id.ToInt());
8806e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    }
88074954674151afa960af66efb4831df06bde727333yangguo@chromium.org    result = Compiler::GetConcurrentlyOptimizedCode(job);
8808a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
8809e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    if (FLAG_trace_osr) {
88104954674151afa960af66efb4831df06bde727333yangguo@chromium.org      PrintF("[OSR - Compiling: ");
8811e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      function->PrintName();
88124954674151afa960af66efb4831df06bde727333yangguo@chromium.org      PrintF(" at AST id %d]\n", ast_id.ToInt());
88134954674151afa960af66efb4831df06bde727333yangguo@chromium.org    }
8814a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
8815a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        function, caller_code, mode, ast_id);
8816a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    if (maybe_result.ToHandle(&result) &&
8817a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
88184954674151afa960af66efb4831df06bde727333yangguo@chromium.org      // Optimization is queued.  Return to check later.
88194954674151afa960af66efb4831df06bde727333yangguo@chromium.org      return NULL;
8820e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    }
8821e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  }
8822e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8823528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Revert the patched back edge table, regardless of whether OSR succeeds.
88244954674151afa960af66efb4831df06bde727333yangguo@chromium.org  BackEdgeTable::Revert(isolate, *caller_code);
8825e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8826e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // Check whether we ended up with usable optimized code.
8827e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
8828c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    DeoptimizationInputData* data =
8829e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org        DeoptimizationInputData::cast(result->deoptimization_data());
8830e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8831e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    if (data->OsrPcOffset()->value() >= 0) {
8832e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8833e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      if (FLAG_trace_osr) {
88344954674151afa960af66efb4831df06bde727333yangguo@chromium.org        PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
8835e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org               ast_id.ToInt(), data->OsrPcOffset()->value());
8836e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      }
8837e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      // TODO(titzer): this is a massive hack to make the deopt counts
8838e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      // match. Fix heuristics for reenabling optimizations!
8839e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      function->shared()->increment_deopt_count();
88404954674151afa960af66efb4831df06bde727333yangguo@chromium.org
88414954674151afa960af66efb4831df06bde727333yangguo@chromium.org      // TODO(titzer): Do not install code into the function.
88424954674151afa960af66efb4831df06bde727333yangguo@chromium.org      function->ReplaceCode(*result);
8843e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      return *result;
88445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
8845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8846e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
88474954674151afa960af66efb4831df06bde727333yangguo@chromium.org  // Failed.
8848e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  if (FLAG_trace_osr) {
88494954674151afa960af66efb4831df06bde727333yangguo@chromium.org    PrintF("[OSR - Failed: ");
8850e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    function->PrintName();
88514954674151afa960af66efb4831df06bde727333yangguo@chromium.org    PrintF(" at AST id %d]\n", ast_id.ToInt());
8852e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  }
8853e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
8854486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (!function->IsOptimized()) {
8855486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    function->ReplaceCode(function->shared()->code());
8856486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
8857e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  return NULL;
8858a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8859a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8860a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8861a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
8862ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  SealHandleScope shs(isolate);
8863ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  ASSERT(args.length() == 2 || args.length() == 3);
8864ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org#ifdef DEBUG
8865ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  CONVERT_SMI_ARG_CHECKED(interval, 0);
8866ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  CONVERT_SMI_ARG_CHECKED(timeout, 1);
8867ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  isolate->heap()->set_allocation_timeout(timeout);
8868ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  FLAG_gc_interval = interval;
8869ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  if (args.length() == 3) {
8870ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org    // Enable/disable inline allocation if requested.
8871ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org    CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
8872ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org    if (inline_allocation) {
8873ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org      isolate->heap()->EnableInlineAllocation();
8874ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org    } else {
8875ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org      isolate->heap()->DisableInlineAllocation();
8876ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org    }
8877ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org  }
8878ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org#endif
8879ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org  return isolate->heap()->undefined_value();
8880ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org}
8881ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org
8882ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org
8883a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
888479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
88858496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
88861805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
88871805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  return isolate->heap()->undefined_value();
88881805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
88891805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
88901805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
8891a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetRootNaN) {
889279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
88938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
889488d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
889588d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  return isolate->heap()->nan_value();
889688d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org}
889788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
889888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
8899a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Call) {
8900c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  HandleScope scope(isolate);
8901c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  ASSERT(args.length() >= 2);
8902c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int argc = args.length() - 2;
8903f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
8904f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Object* receiver = args[0];
8905c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8906c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  // If there are too many arguments, allocate argv via malloc.
8907c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  const int argv_small_size = 10;
8908c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<Object> argv_small_buffer[argv_small_size];
8909c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  SmartArrayPointer<Handle<Object> > argv_large_buffer;
8910c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<Object>* argv = argv_small_buffer;
8911c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  if (argc > argv_small_size) {
8912c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    argv = new Handle<Object>[argc];
8913c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    if (argv == NULL) return isolate->StackOverflow();
8914c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8915c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
8916c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8917c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  for (int i = 0; i < argc; ++i) {
89188496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org     argv[i] = Handle<Object>(args[1 + i], isolate);
8919c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
8920c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8921c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Handle<JSReceiver> hfun(fun);
892209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> hreceiver(receiver, isolate);
89232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
89242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
89252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
89262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
8927c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  return *result;
8928c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
8929c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8930c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
8931a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Apply) {
893234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  HandleScope scope(isolate);
893334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ASSERT(args.length() == 5);
8934f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
89358496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
8936f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
8937fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  CONVERT_SMI_ARG_CHECKED(offset, 3);
8938fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  CONVERT_SMI_ARG_CHECKED(argc, 4);
8939594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  RUNTIME_ASSERT(offset >= 0);
8940a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // Loose upper bound to allow fuzzing. We'll most likely run out of
8941a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // stack space before hitting this limit.
8942a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  static int kMaxArgc = 1000000;
8943a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
894434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
894534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If there are too many arguments, allocate argv via malloc.
894634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  const int argv_small_size = 10;
894734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Handle<Object> argv_small_buffer[argv_small_size];
894834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  SmartArrayPointer<Handle<Object> > argv_large_buffer;
894934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Handle<Object>* argv = argv_small_buffer;
895034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (argc > argv_small_size) {
895134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    argv = new Handle<Object>[argc];
895234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (argv == NULL) return isolate->StackOverflow();
895334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
895434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
895534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
895634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  for (int i = 0; i < argc; ++i) {
8957202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8958202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        isolate, argv[i],
8959202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Object::GetElement(isolate, arguments, offset + i));
896034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
896134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
89622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
89632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
89642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
89652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::Call(isolate, fun, receiver, argc, argv, true));
896634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  return *result;
896734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org}
896834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
896934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
8970a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
8971ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
897243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
89738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
89748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(!object->IsJSFunction());
89758496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *Execution::GetFunctionDelegate(isolate, object);
897643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
897743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
897843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8979a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
8980ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
898105521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  ASSERT(args.length() == 1);
89828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
89838496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(!object->IsJSFunction());
89848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *Execution::GetConstructorDelegate(isolate, object);
898505521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org}
898605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
898705521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
8988a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewGlobalContext) {
89895b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  HandleScope scope(isolate);
899046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(args.length() == 2);
899146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
89925b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
89935b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
89945b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> result =
89955b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      isolate->factory()->NewGlobalContext(function, scope_info);
899646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
8997355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT(function->context() == isolate->context());
8998355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ASSERT(function->context()->global_object() == result->global_object());
89995b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  result->global_object()->set_global_context(*result);
90005b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  return *result;
900146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
900246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
900346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
9004a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_NewFunctionContext) {
90055b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  HandleScope scope(isolate);
90067276f14ca716596e0a0d17539516370c1f453847kasper.lund  ASSERT(args.length() == 1);
900743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90085b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9009c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int length = function->shared()->scope_info()->ContextLength();
90108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *isolate->factory()->NewFunctionContext(length, function);
901143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
901243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9013303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
9014a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_PushWithContext) {
90155b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  HandleScope scope(isolate);
90163cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  ASSERT(args.length() == 2);
90175b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<JSReceiver> extension_object;
9018ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (args[0]->IsJSReceiver()) {
90195b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    extension_object = args.at<JSReceiver>(0);
90206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  } else {
902174dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    // Try to convert the object to a proper JavaScript object.
902274dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    MaybeHandle<JSReceiver> maybe_object =
902374dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org        Object::ToObject(isolate, args.at<Object>(0));
902474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    if (!maybe_object.ToHandle(&extension_object)) {
90255b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      Handle<Object> handle = args.at<Object>(0);
90265b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      Handle<Object> result =
90275b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org          isolate->factory()->NewTypeError("with_expression",
90285b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                           HandleVector(&handle, 1));
90295b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      return isolate->Throw(*result);
903043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
903143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
903243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
90335b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<JSFunction> function;
90343cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (args[1]->IsSmi()) {
90353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // A smi sentinel indicates a context nested inside global code rather
90363cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // than some function.  There is a canonical empty function that can be
903746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // gotten from the native context.
90385b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    function = handle(isolate->context()->native_context()->closure());
90393cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  } else {
90405b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    function = args.at<JSFunction>(1);
90413cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  }
90423cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
90435b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> current(isolate->context());
90445b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> context = isolate->factory()->NewWithContext(
90455b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      function, current, extension_object);
90465b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  isolate->set_context(*context);
90475b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  return *context;
904837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
904937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
905037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
9051a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_PushCatchContext) {
90525b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  HandleScope scope(isolate);
90533cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  ASSERT(args.length() == 3);
90545b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
90555b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
90565b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<JSFunction> function;
90573cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  if (args[2]->IsSmi()) {
90583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // A smi sentinel indicates a context nested inside global code rather
90593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // than some function.  There is a canonical empty function that can be
906046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // gotten from the native context.
90615b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    function = handle(isolate->context()->native_context()->closure());
90623cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  } else {
90635b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    function = args.at<JSFunction>(2);
90643cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  }
90655b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> current(isolate->context());
90665b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> context = isolate->factory()->NewCatchContext(
90675b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      function, current, name, thrown_object);
90685b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  isolate->set_context(*context);
90695b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  return *context;
907037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
907137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
907237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
9073a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_PushBlockContext) {
90745b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  HandleScope scope(isolate);
90754acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  ASSERT(args.length() == 2);
90765b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
90775b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<JSFunction> function;
90784acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (args[1]->IsSmi()) {
90794acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // A smi sentinel indicates a context nested inside global code rather
90804acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    // than some function.  There is a canonical empty function that can be
908146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // gotten from the native context.
90825b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    function = handle(isolate->context()->native_context()->closure());
90834acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  } else {
90845b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    function = args.at<JSFunction>(1);
90854acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
90865b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> current(isolate->context());
90875b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Context> context = isolate->factory()->NewBlockContext(
90885b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      function, current, scope_info);
90895b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  isolate->set_context(*context);
90905b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  return *context;
90914acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
90924acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
90934acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
9094a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsJSModule) {
909579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
909681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  ASSERT(args.length() == 1);
90978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
909881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSModule());
909981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org}
910081cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
910181cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
9102a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_PushModuleContext) {
910379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
91048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ASSERT(args.length() == 2);
91058e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  CONVERT_SMI_ARG_CHECKED(index, 0);
91068e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91078e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  if (!args[1]->IsScopeInfo()) {
91088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    // Module already initialized. Find hosting context and retrieve context.
91098e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Context* host = Context::cast(isolate->context())->global_context();
91108e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Context* context = Context::cast(host->get(index));
91118e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    ASSERT(context->previous() == isolate->context());
91128e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    isolate->set_context(context);
91138e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    return context;
91148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
91158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91168e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
911781cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
91188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Allocate module context.
91198e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  HandleScope scope(isolate);
91208e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Factory* factory = isolate->factory();
91218e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<Context> context = factory->NewModuleContext(scope_info);
91228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Handle<JSModule> module = factory->NewJSModule(context, scope_info);
91238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  context->set_module(*module);
912481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  Context* previous = isolate->context();
912581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  context->set_previous(previous);
912681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  context->set_closure(previous->closure());
912746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  context->set_global_object(previous->global_object());
91288e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  isolate->set_context(*context);
9129ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
91308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Find hosting scope and initialize internal variable holding module there.
91318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  previous->global_context()->set(index, *context);
91328e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91338e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return *context;
91348e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
91358e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
9137a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_DeclareModules) {
91388e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  HandleScope scope(isolate);
91398e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ASSERT(args.length() == 1);
91408e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
91418e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  Context* host_context = isolate->context();
91428e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91438e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  for (int i = 0; i < descriptions->length(); ++i) {
91448e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
91458e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    int host_index = description->host_index();
91468e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Handle<Context> context(Context::cast(host_context->get(host_index)));
91478e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    Handle<JSModule> module(context->module());
91488e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91498e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    for (int j = 0; j < description->length(); ++j) {
91508e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      Handle<String> name(description->name(j));
91518e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      VariableMode mode = description->mode(j);
91528e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      int index = description->index(j);
91538e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      switch (mode) {
91548e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case VAR:
91558e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case LET:
91568e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case CONST:
9157486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        case CONST_LEGACY: {
91588e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          PropertyAttributes attr =
91598e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org              IsImmutableVariableMode(mode) ? FROZEN : SEALED;
91608e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Handle<AccessorInfo> info =
91618e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org              Accessors::MakeModuleExport(name, index, attr);
91628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          Handle<Object> result =
91638496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              JSObject::SetAccessor(module, info).ToHandleChecked();
91648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          ASSERT(!result->IsUndefined());
91658e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          USE(result);
91668e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          break;
91678e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        }
91688e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case MODULE: {
91698e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Object* referenced_context = Context::cast(host_context)->get(index);
91708e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          Handle<JSModule> value(Context::cast(referenced_context)->module());
91718f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          JSReceiver::SetProperty(module, name, value, FROZEN, STRICT).Assert();
91728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          break;
91738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        }
91748e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case INTERNAL:
91758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case TEMPORARY:
91768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case DYNAMIC:
91778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case DYNAMIC_GLOBAL:
91788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        case DYNAMIC_LOCAL:
91798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org          UNREACHABLE();
91808e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      }
91818e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
91828e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91838496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    JSObject::PreventExtensions(module).Assert();
91848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
91858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
91868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ASSERT(!isolate->has_pending_exception());
91878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  return isolate->heap()->undefined_value();
9188ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com}
9189ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
9190ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
9191a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_DeleteContextSlot) {
9192ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
919343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
919443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9195f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
9196f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
919743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
919843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
919943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
920043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = FOLLOW_CHAINS;
920180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
920280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Handle<Object> holder = context->Lookup(name,
920380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          flags,
920480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &index,
920580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &attributes,
920680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &binding_flags);
920743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // If the slot was not found the result is true.
92090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (holder.is_null()) {
9210ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->true_value();
921143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
921243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92130ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // If the slot was found in a context, it should be DONT_DELETE.
92140ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  if (holder->IsContext()) {
9215ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->false_value();
92160ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  }
92170ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
92180ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // The slot was found in a JSObject, either a context extension object,
9219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the global object, or the subject of a with.  Try to delete it
9220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // (respecting DONT_DELETE).
92210ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  Handle<JSObject> object = Handle<JSObject>::cast(holder);
92229e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
92239e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
92249e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result,
92259e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      JSReceiver::DeleteProperty(object, name));
9226ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
922743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
922843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
922943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9230a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// A mechanism to return a pair of Object pointers in registers (if possible).
9231a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// How this is achieved is calling convention-dependent.
9232a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// All currently supported x86 compiles uses calling conventions that are cdecl
9233a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// variants where a 64-bit value is returned in two 32-bit registers
9234a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// (edx:eax on ia32, r1:r0 on ARM).
9235a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
9236a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// In Win64 calling convention, a struct of two pointers is returned in memory,
9237a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// allocated by the caller, and passed as a pointer in a hidden first parameter.
92382abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org#ifdef V8_HOST_ARCH_64_BIT
92392abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgstruct ObjectPair {
9240a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Object* x;
9241a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Object* y;
92422abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org};
9243a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
9244e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
9245a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic inline ObjectPair MakePair(Object* x, Object* y) {
92462abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  ObjectPair result = {x, y};
9247a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
9248a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // In Win64 they are assigned to a hidden first argument.
9249a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  return result;
92502abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
9251b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org#else
92522abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgtypedef uint64_t ObjectPair;
9253a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic inline ObjectPair MakePair(Object* x, Object* y) {
9254731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org#if defined(V8_TARGET_LITTLE_ENDIAN)
925543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return reinterpret_cast<uint32_t>(x) |
92569fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org      (reinterpret_cast<ObjectPair>(y) << 32);
9257731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org#elif defined(V8_TARGET_BIG_ENDIAN)
9258731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    return reinterpret_cast<uint32_t>(y) |
9259731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        (reinterpret_cast<ObjectPair>(x) << 32);
9260731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org#else
9261731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org#error Unknown endianness
92622abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org#endif
926343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
9264731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org#endif
926543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
926643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
926740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgstatic Object* ComputeReceiverForNonGlobal(Isolate* isolate,
926840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                           JSObject* holder) {
92699fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  ASSERT(!holder->IsGlobalObject());
9270ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Context* top = isolate->context();
92719fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // Get the context extension function.
92725a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  JSFunction* context_extension_function =
927346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      top->native_context()->context_extension_function();
92749fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // If the holder isn't a context extension object, we just return it
92759fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // as the receiver. This allows arguments objects to be used as
92769fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // receivers, but only if they are put in the context scope chain
92779fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  // explicitly via a with-statement.
92789fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  Object* constructor = holder->map()->constructor();
92799fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (constructor != context_extension_function) return holder;
928040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Fall back to using the global object as the implicit receiver if
928140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // the property turns out to be a local variable allocated in a
9282e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  // context extension object - introduced via eval.
9283e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return isolate->heap()->undefined_value();
92845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
92855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
92865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
9287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic ObjectPair LoadContextSlotHelper(Arguments args,
9288ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        Isolate* isolate,
9289ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                        bool throw_error) {
9290ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
9291a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  ASSERT_EQ(2, args.length());
929243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92939fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (!args[0]->IsContext() || !args[1]->IsString()) {
9294ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakePair(isolate->ThrowIllegalOperation(), NULL);
92959fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
929643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Context> context = args.at<Context>(0);
92979fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  Handle<String> name = args.at<String>(1);
929843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
929943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
930043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
930143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = FOLLOW_CHAINS;
930280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
930380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Handle<Object> holder = context->Lookup(name,
930480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          flags,
930580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &index,
930680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &attributes,
930780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &binding_flags);
9308ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (isolate->has_pending_exception()) {
9309a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    return MakePair(isolate->heap()->exception(), NULL);
9310ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
931143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If the index is non-negative, the slot has been found in a context.
931343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= 0) {
9314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(holder->IsContext());
9315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the "property" we were looking for is a local variable, the
9316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
9317e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    Handle<Object> receiver = isolate->factory()->undefined_value();
9318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* value = Context::cast(*holder)->get(index);
931980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    // Check for uninitialized bindings.
9320394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    switch (binding_flags) {
9321394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case MUTABLE_CHECK_INITIALIZED:
9322394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
9323394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (value->IsTheHole()) {
9324394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          Handle<Object> reference_error =
9325394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              isolate->factory()->NewReferenceError("not_defined",
9326394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                                    HandleVector(&name, 1));
9327394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          return MakePair(isolate->Throw(*reference_error), NULL);
9328394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        }
9329394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        // FALLTHROUGH
9330394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case MUTABLE_IS_INITIALIZED:
9331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_IS_INITIALIZED:
9332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_IS_INITIALIZED_HARMONY:
9333394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ASSERT(!value->IsTheHole());
9334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return MakePair(value, *receiver);
9335394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case IMMUTABLE_CHECK_INITIALIZED:
9336731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        if (value->IsTheHole()) {
9337731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org          ASSERT((attributes & READ_ONLY) != 0);
9338731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org          value = isolate->heap()->undefined_value();
9339731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        }
9340731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        return MakePair(value, *receiver);
9341394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      case MISSING_BINDING:
9342394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        UNREACHABLE();
9343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return MakePair(NULL, NULL);
934480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    }
93459fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
93469fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
9347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Otherwise, if the slot was found the holder is a context extension
9348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object, subject of a with, or a global object.  We read the named
9349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // property from it.
9350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!holder.is_null()) {
9351ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9352528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
93537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // GetProperty below can cause GC.
935409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> receiver_handle(
935509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        object->IsGlobalObject()
9356e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org            ? Object::cast(isolate->heap()->undefined_value())
9357ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            : object->IsJSProxy() ? static_cast<Object*>(*object)
9358ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
935909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        isolate);
93607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
9361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // No need to unhole the value here.  This is taken care of by the
93629fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    // GetProperty function.
93632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> value;
93642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
93652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, value,
93662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Object::GetProperty(object, name),
9367a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        MakePair(isolate->heap()->exception(), NULL));
93685b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    return MakePair(*value, *receiver_handle);
936943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
937043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
937143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (throw_error) {
937243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // The property doesn't exist - throw exception.
937343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> reference_error =
9374ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewReferenceError("not_defined",
9375ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                              HandleVector(&name, 1));
9376ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakePair(isolate->Throw(*reference_error), NULL);
937743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
937840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // The property doesn't exist - return undefined.
9379ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return MakePair(isolate->heap()->undefined_value(),
9380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                    isolate->heap()->undefined_value());
938143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
938243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
938343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
938443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9385a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlot) {
9386ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return LoadContextSlotHelper(args, isolate, true);
938743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
938843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
938943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9390a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlotNoReferenceError) {
9391ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return LoadContextSlotHelper(args, isolate, false);
939243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
939343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
939443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9395a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_StoreContextSlot) {
9396ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
93979ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  ASSERT(args.length() == 4);
939843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93998496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
9400f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
9401f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
9402486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
940343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
940443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index;
940543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attributes;
940643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ContextLookupFlags flags = FOLLOW_CHAINS;
940780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  BindingFlags binding_flags;
940880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  Handle<Object> holder = context->Lookup(name,
940980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          flags,
941080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &index,
941180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &attributes,
941280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                          &binding_flags);
9413a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (isolate->has_pending_exception()) return isolate->heap()->exception();
941443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
941543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= 0) {
9416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The property was found in a context slot.
9417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Handle<Context> context = Handle<Context>::cast(holder);
9418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
9419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        context->get(index)->IsTheHole()) {
9420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Object> error =
9421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate->factory()->NewReferenceError("not_defined",
9422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                HandleVector(&name, 1));
9423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return isolate->Throw(*error);
9424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
9425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Ignore if read_only variable.
9426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((attributes & READ_ONLY) == 0) {
9427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Context is a fixed array and set cannot fail.
9428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      context->set(index, *value);
9429486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    } else if (strict_mode == STRICT) {
9430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Setting read only property in strict mode.
9431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Object> error =
9432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate->factory()->NewTypeError("strict_cannot_assign",
9433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                           HandleVector(&name, 1));
9434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return isolate->Throw(*error);
943543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
943643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return *value;
943743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
943843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Slow case: The property is not in a context slot.  It is either in a
9440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // context extension object, a property of the subject of a with, or a
9441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // property of the global object.
9442ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSReceiver> object;
944343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94449fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  if (!holder.is_null()) {
9445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // The property exists on the holder.
9446ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    object = Handle<JSReceiver>::cast(holder);
944743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
944844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    // The property was not found.
944943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    ASSERT(attributes == ABSENT);
945044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
9451486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (strict_mode == STRICT) {
945244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      // Throw in strict mode (assignment to undefined variable).
945344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      Handle<Object> error =
9454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate->factory()->NewReferenceError(
9455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com              "not_defined", HandleVector(&name, 1));
945644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      return isolate->Throw(*error);
945744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
9458486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    // In sloppy mode, the property is added to the global object.
945943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    attributes = NONE;
9460ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    object = Handle<JSReceiver>(isolate->context()->global_object());
946143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
946243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Set the property if it's not read only or doesn't yet exist.
9464bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if ((attributes & READ_ONLY) == 0 ||
94651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      (JSReceiver::GetOwnPropertyAttributes(object, name) == ABSENT)) {
94668f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(
9467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
9468f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
9469486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
94709ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Setting read only property in strict mode.
94719ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    Handle<Object> error =
9472ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewTypeError(
9473ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          "strict_cannot_assign", HandleVector(&name, 1));
9474ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->Throw(*error);
947543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
947643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
947743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
947843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
947943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9480a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_Throw) {
9481ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
948243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
948343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9484ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->Throw(args[0]);
948543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
948643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
948743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9488a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_ReThrow) {
9489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
949043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
949143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9492ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->ReThrow(args[0]);
949343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
949443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
949543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9496a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_PromoteScheduledException) {
949779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
94988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
9499ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->PromoteScheduledException();
9500c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
9501c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
9502c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
9503a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_ThrowReferenceError) {
9504ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
950543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
95068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
950743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> reference_error =
9508ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->factory()->NewReferenceError("not_defined",
9509ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          HandleVector(&name, 1));
9510ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->Throw(*reference_error);
951143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
951243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
951343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9514a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_ThrowNotDateError) {
9515de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  HandleScope scope(isolate);
9516de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  ASSERT(args.length() == 0);
9517de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  return isolate->Throw(*isolate->factory()->NewTypeError(
9518de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      "not_date_object", HandleVector<Object>(NULL, 0)));
9519de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org}
9520de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
9521de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
9522a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_StackGuard) {
952379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
95244a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  ASSERT(args.length() == 0);
952543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
952643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First check if this is a real stack overflow.
95273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  StackLimitCheck check(isolate);
95283ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (check.JsHasOverflowed()) {
9529ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->StackOverflow();
9530ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
953143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95323c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  return isolate->stack_guard()->HandleInterrupts();
953343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
953443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
953543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9536a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_TryInstallOptimizedCode) {
95374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  HandleScope scope(isolate);
95384a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  ASSERT(args.length() == 1);
95394a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
95404a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
95414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // First check if this is a real stack overflow.
95423ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  StackLimitCheck check(isolate);
95433ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (check.JsHasOverflowed()) {
95444a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    SealHandleScope shs(isolate);
95454a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    return isolate->StackOverflow();
95464a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
95474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
95484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
95494a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  return (function->IsOptimized()) ? function->code()
95504a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                                   : function->shared()->code();
95514a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org}
95524a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
95534a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
9554a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_Interrupt) {
955579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
955656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  ASSERT(args.length() == 0);
95573c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  return isolate->stack_guard()->HandleInterrupts();
955856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org}
955956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
956056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
9561c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgstatic int StackSize(Isolate* isolate) {
956243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n = 0;
9563c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
956443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return n;
956543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
956643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
956743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9568c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgstatic void PrintTransition(Isolate* isolate, Object* result) {
956943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // indentation
957043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  { const int nmax = 80;
9571c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    int n = StackSize(isolate);
957243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (n <= nmax)
957343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("%4d:%*s", n, n, "");
957443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    else
957543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("%4d:%*s", n, nmax, "...");
957643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
957743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
957843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (result == NULL) {
9579c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    JavaScriptFrame::PrintTop(isolate, stdout, true, false);
9580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    PrintF(" {\n");
958143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
958243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // function result
958343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("} -> ");
9584394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    result->ShortPrint();
958543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("\n");
958643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
958743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
958843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
958943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9590a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TraceEnter) {
959179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
95926e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 0);
9593c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  PrintTransition(isolate, NULL);
9594ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
959543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
959643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
959743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9598a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TraceExit) {
959979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
96008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
96018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
96028496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  PrintTransition(isolate, obj);
96038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return obj;  // return TOS
960443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
960543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
960643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9607a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPrint) {
960879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
960943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
961043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
961143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
961243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (args[0]->IsString()) {
961343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If we have a string, assume it's a code "marker"
961443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // and print some interesting cpu debugging info.
961574f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    JavaScriptFrameIterator it(isolate);
961643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    JavaScriptFrame* frame = it.frame();
9617eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    PrintF("fp = %p, sp = %p, caller_sp = %p: ",
9618eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org           frame->fp(), frame->sp(), frame->caller_sp());
961943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
962043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("DebugPrint: ");
962143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
962243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  args[0]->Print();
9623ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  if (args[0]->IsHeapObject()) {
9624ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    PrintF("\n");
9625ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    HeapObject::cast(args[0])->map()->Print();
9626ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  }
962743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else
96289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // ShortPrint is available in release mode. Print is not.
96299258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  args[0]->ShortPrint();
963043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
963143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PrintF("\n");
9632236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  Flush();
963343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
963443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return args[0];  // return TOS
963543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
963643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
963743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9638a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugTrace) {
963979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
96406e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 0);
9641bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  isolate->PrintStack(stdout);
9642ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
964343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
964443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
964543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9646a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateCurrentTime) {
9647e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
964831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
964970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
965043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
965143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // According to ECMA-262, section 15.9.1, page 117, the precision of
965243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the number in a Date object representing a particular instant in
965343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // time is milliseconds. Therefore, we floor the result of getting
965443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the OS time.
9655e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  double millis = std::floor(OS::TimeCurrentMillis());
9656e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(millis);
965743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
965843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
965943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9660a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateParseString) {
9661ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
9662bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(args.length() == 2);
9663f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
9664f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
9665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
96663484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  RUNTIME_ASSERT(output->HasFastElements());
9667c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  JSObject::EnsureCanContainHeapObjectElements(output);
9668830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(output->HasFastObjectElements());
9669f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
9670f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
967143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  str = String::Flatten(str);
967379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
967443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9675bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  bool result;
9676ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent str_content = str->GetFlatContent();
9677ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (str_content.IsAscii()) {
967859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    result = DateParser::Parse(str_content.ToOneByteVector(),
9679f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                               *output_array,
9680a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                               isolate->unicode_cache());
968143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
9682ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    ASSERT(str_content.IsTwoByte());
9683ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    result = DateParser::Parse(str_content.ToUC16Vector(),
9684f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                               *output_array,
9685a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                               isolate->unicode_cache());
9686bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
9687bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
9688bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (result) {
9689bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return *output;
9690bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else {
9691ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->null_value();
969243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
969343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
969443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
969543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9696a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
96979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HandleScope scope(isolate);
969843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
969943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9701a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
9702a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org                 x <= DateCache::kMaxTimeBeforeUTCInMs);
97036b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  const char* zone =
97046b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org      isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
97058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result = isolate->factory()->NewStringFromUtf8(
97068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      CStrVector(zone)).ToHandleChecked();
97078496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *result;
970843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
970943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
971043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9711a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateToUTC) {
9712e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope scope(isolate);
971343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
971443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9716a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
9717a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org                 x <= DateCache::kMaxTimeBeforeUTCInMs);
97184efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
97194efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
9720e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *isolate->factory()->NewNumber(static_cast<double>(time));
972143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
972243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
972343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9724a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DateCacheVersion) {
9725486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  HandleScope hs(isolate);
9726486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  ASSERT(args.length() == 0);
9727486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
9728486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    Handle<FixedArray> date_cache_version =
9729486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        isolate->factory()->NewFixedArray(1, TENURED);
9730486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    date_cache_version->set(0, Smi::FromInt(0));
9731486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    isolate->eternal_handles()->CreateSingleton(
9732486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
9733486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
9734486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  Handle<FixedArray> date_cache_version =
9735486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
9736486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          EternalHandles::DATE_CACHE_VERSION));
9737486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  // Return result as a JS array.
9738486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  Handle<JSObject> result =
9739486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      isolate->factory()->NewJSObject(isolate->array_function());
9740fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
9741486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  return *result;
9742486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org}
9743486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
9744486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
9745a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GlobalReceiver) {
974679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
97475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  ASSERT(args.length() == 1);
97488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, global, 0);
9749ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
97505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return JSGlobalObject::cast(global)->global_receiver();
97515a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
97525a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
97535a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
9754a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
9755113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  SealHandleScope shs(isolate);
9756113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  ASSERT(args.length() == 1);
97578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, global, 0);
9758113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
9759113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  return isolate->heap()->ToBoolean(
9760113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org      !JSGlobalObject::cast(global)->IsDetached());
9761113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org}
9762113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org
9763113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org
9764a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ParseJson) {
9765ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
97668496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
9767f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9768e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
97699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  source = String::Flatten(source);
97702efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Optimized fast case where we only have ASCII characters.
9771e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  Handle<Object> result;
9772255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9773255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      isolate, result,
9774255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
9775255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org                                   : JsonParser<false>::Parse(source));
9776e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  return *result;
9777e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org}
9778e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
9779e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
9780fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgbool CodeGenerationFromStringsAllowed(Isolate* isolate,
9781fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                                      Handle<Context> context) {
9782f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  ASSERT(context->allow_code_gen_from_strings()->IsFalse());
9783f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Check with callback if set.
9784f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  AllowCodeGenerationFromStringsCallback callback =
9785f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate->allow_code_gen_callback();
9786f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (callback == NULL) {
9787f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // No callback set and code generation disallowed.
9788f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return false;
9789f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  } else {
9790f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // Callback set. Let it decide if code generation is allowed.
9791ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    VMState<EXTERNAL> state(isolate);
9792f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return callback(v8::Utils::ToLocal(context));
9793fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
9794fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org}
9795fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
9796fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
97971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org// Walk up the stack expecting:
97981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org//  - Runtime_CompileString
97991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org//  - JSFunction callee (eval, Function constructor, etc)
98001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org//  - call() (maybe)
98011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org//  - apply() (maybe)
98021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org//  - bind() (maybe)
98031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org// - JSFunction caller (maybe)
98041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org//
98051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org// return true if the caller has the same security token as the callee
98061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org// or if an exit frame was hit, in which case allow it through, as it could
98071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org// have come through the api.
98081845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstatic bool TokensMatchForCompileString(Isolate* isolate) {
98091845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  MaybeHandle<JSFunction> callee;
98101845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  bool exit_handled = true;
98111845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  bool tokens_match = true;
98121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  bool done = false;
98131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
98141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    StackFrame* raw_frame = it.frame();
98151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    if (!raw_frame->is_java_script()) {
98161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      if (raw_frame->is_exit()) exit_handled = false;
98171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      continue;
98181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
98191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
98201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
98211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    outer_frame->Summarize(&frames);
98221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    for (int i = frames.length() - 1; i >= 0 && !done; --i) {
98231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      FrameSummary& frame = frames[i];
98241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Handle<JSFunction> fun = frame.function();
98251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // Capture the callee function.
98261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      if (callee.is_null()) {
98271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        callee = fun;
98281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        exit_handled = true;
98291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        continue;
98301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
98311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // Exit condition.
98321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Handle<Context> context(callee.ToHandleChecked()->context());
98331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      if (!fun->context()->HasSameSecurityTokenAs(*context)) {
98341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        tokens_match = false;
98351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        done = true;
98361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        continue;
98371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
98381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // Skip bound functions in correct origin.
98391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      if (fun->shared()->bound()) {
98401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        exit_handled = true;
98411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        continue;
98421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
98431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      done = true;
98441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
98451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
98461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return !exit_handled || tokens_match;
98471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
98481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
98491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
9850a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CompileString) {
9851ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
98528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 2);
9853f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
98549faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
98559258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
985646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Extract native context.
985746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> context(isolate->context()->native_context());
9858fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
98591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Filter cross security context calls.
98601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if (!TokensMatchForCompileString(isolate)) {
98611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    return isolate->heap()->undefined_value();
98621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
98631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
986446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check if native context allows code generation from
9865fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // strings. Throw an exception if it doesn't.
9866f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (context->allow_code_gen_from_strings()->IsFalse() &&
9867f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      !CodeGenerationFromStringsAllowed(isolate, context)) {
986856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Handle<Object> error_message =
986956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        context->ErrorMessageForCodeGenerationFromStrings();
987056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    return isolate->Throw(*isolate->factory()->NewEvalError(
987156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9872fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
9873fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
987446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Compile source string in the native context.
98759faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  ParseRestriction restriction = function_literal_only
98769faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
98778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<JSFunction> fun;
98788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
98798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, fun,
98808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Compiler::GetFunctionFromEval(
98818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
988243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *fun;
988343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
988443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
988543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9886ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic ObjectPair CompileGlobalEval(Isolate* isolate,
9887ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                    Handle<String> source,
988883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                                    Handle<Object> receiver,
9889486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                    StrictMode strict_mode,
989004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                                    int scope_position) {
9891fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  Handle<Context> context = Handle<Context>(isolate->context());
989246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> native_context = Handle<Context>(context->native_context());
9893fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
989446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Check if native context allows code generation from
9895fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  // strings. Throw an exception if it doesn't.
989646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (native_context->allow_code_gen_from_strings()->IsFalse() &&
989746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      !CodeGenerationFromStringsAllowed(isolate, native_context)) {
989856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    Handle<Object> error_message =
9899c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org        native_context->ErrorMessageForCodeGenerationFromStrings();
990056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    isolate->Throw(*isolate->factory()->NewEvalError(
990156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org        "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9902a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    return MakePair(isolate->heap()->exception(), NULL);
9903fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org  }
9904fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
99051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Deal with a normal eval call with a string argument. Compile it
99061af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // and return the compiled function bound in the local context.
99074954674151afa960af66efb4831df06bde727333yangguo@chromium.org  static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
99088496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<JSFunction> compiled;
99098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
99108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, compiled,
99118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Compiler::GetFunctionFromEval(
99128496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          source, context, strict_mode, restriction, scope_position),
9913a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      MakePair(isolate->heap()->exception(), NULL));
99141af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  return MakePair(*compiled, *receiver);
99151af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org}
99161af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
99171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
9918a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_ResolvePossiblyDirectEval) {
99196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
992004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ASSERT(args.length() == 5);
9921a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
99229ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  Handle<Object> callee = args.at<Object>(0);
99231af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
9924c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // If "eval" didn't refer to the original GlobalEval, it's not a
9925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // direct call to eval.
9926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // (And even if it is, but the first argument isn't a string, just let
9927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // execution default to an indirect call to eval, which will also return
9928c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the first argument without doing anything).
992946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (*callee != isolate->native_context()->global_eval_fun() ||
99301af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org      !args[1]->IsString()) {
9931e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    return MakePair(*callee, isolate->heap()->undefined_value());
99321af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
99331af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
9934486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  ASSERT(args[3]->IsSmi());
9935486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  ASSERT(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
9936486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
993704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  ASSERT(args[4]->IsSmi());
9938ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return CompileGlobalEval(isolate,
9939ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           args.at<String>(1),
994083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                           args.at<Object>(2),
9941486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                           strict_mode,
994204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                           args.smi_at(4));
9943a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
9944a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
9945a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
9946a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_AllocateInNewSpace) {
99478496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  HandleScope scope(isolate);
9948c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  ASSERT(args.length() == 1);
9949ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(size, 0);
99508496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
99518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(size > 0);
99528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
99538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
9954c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
9955c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
9956c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
9957a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_AllocateInTargetSpace) {
99588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  HandleScope scope(isolate);
9959ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(args.length() == 2);
9960ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(size, 0);
9961ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(flags, 1);
99628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
99638496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(size > 0);
99648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9965ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  bool double_align = AllocateDoubleAlignFlag::decode(flags);
9966ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  AllocationSpace space = AllocateTargetSpace::decode(flags);
99678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *isolate->factory()->NewFillerObject(size, double_align, space);
99682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
99692bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
99702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
99715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Push an object unto an array of objects if it is not already in the
99729258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// array.  Returns true if the element was pushed on the stack and
99739258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// false otherwise.
9974a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_PushIfAbsent) {
9975b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HandleScope scope(isolate);
99769258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  ASSERT(args.length() == 2);
9977b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
9978b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
9979830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
99809258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  int length = Smi::cast(array->length())->value();
99819258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  FixedArray* elements = FixedArray::cast(array->elements());
99829258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  for (int i = 0; i < length; i++) {
9983b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (elements->get(i) == *element) return isolate->heap()->false_value();
99849258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
9985b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
99868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Strict not needed. Used for cycle detection in Array join implementation.
99879e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(
99889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate,
99899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      JSObject::SetFastElement(array, length, element, SLOPPY, true));
9990ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->true_value();
99919258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
99929258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
99939258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
99949bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org/**
99959bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * A simple visitor visits every element of Array's.
99969bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * The backend storage can be a fixed array for fast elements case,
99979bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * or a dictionary for sparse array. Since Dictionary is a subtype
99989bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * of FixedArray, the class can be used by both fast and slow cases.
99999bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * The second parameter of the constructor, fast_elements, specifies
100009bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * whether the storage is a FixedArray or Dictionary.
100019bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org *
100029bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * An index limit is used to deal with the situation that a result array
100039bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * length overflows 32-bit non-negative integer.
100049bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org */
100059bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.orgclass ArrayConcatVisitor {
100069bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org public:
10007ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ArrayConcatVisitor(Isolate* isolate,
10008ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                     Handle<FixedArray> storage,
100099bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org                     bool fast_elements) :
10010ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_(isolate),
10011ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      storage_(Handle<FixedArray>::cast(
10012ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->global_handles()->Create(*storage))),
100135d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      index_offset_(0u),
10014e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      fast_elements_(fast_elements),
10015e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      exceeds_array_limit_(false) { }
100169bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
100179ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  ~ArrayConcatVisitor() {
100189ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    clear_storage();
100199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
100209ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
100219bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  void visit(uint32_t i, Handle<Object> elm) {
10022e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (i > JSObject::kMaxElementCount - index_offset_) {
10023e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      exceeds_array_limit_ = true;
10024e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      return;
10025e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
100260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    uint32_t index = index_offset_ + i;
100279bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
100289bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    if (fast_elements_) {
100295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (index < static_cast<uint32_t>(storage_->length())) {
100305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        storage_->set(index, *elm);
100315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        return;
100325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
100335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Our initial estimate of length was foiled, possibly by
100345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // getters on the arrays increasing the length of later arrays
100355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // during iteration.
100365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // This shouldn't happen in anything but pathological cases.
1003784b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org      SetDictionaryMode();
100385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Fall-through to dictionary mode.
100399bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
100405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    ASSERT(!fast_elements_);
10041f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> dict(
10042f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        SeededNumberDictionary::cast(*storage_));
10043f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> result =
10044f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        SeededNumberDictionary::AtNumberPut(dict, index, elm);
100455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (!result.is_identical_to(dict)) {
100469ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      // Dictionary needed to grow.
100479ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      clear_storage();
100489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      set_storage(*result);
100495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
10050fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
100519bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
100529bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  void increase_index_offset(uint32_t delta) {
100535d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (JSObject::kMaxElementCount - index_offset_ < delta) {
100545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      index_offset_ = JSObject::kMaxElementCount;
100550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    } else {
100560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      index_offset_ += delta;
100570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
1005884b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org    // If the initial length estimate was off (see special case in visit()),
1005984b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org    // but the array blowing the limit didn't contain elements beyond the
1006084b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org    // provided-for index range, go to dictionary mode now.
1006184b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org    if (fast_elements_ &&
10062c62ef8e847c395f9d153819774af3b01119c671eishell@chromium.org        index_offset_ >
10063c62ef8e847c395f9d153819774af3b01119c671eishell@chromium.org            static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
1006484b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org      SetDictionaryMode();
1006584b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org    }
100669bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
100679bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10068e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool exceeds_array_limit() {
10069e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return exceeds_array_limit_;
10070e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
10071e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
100725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  Handle<JSArray> ToArray() {
10073ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
100745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    Handle<Object> length =
10075ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
10076af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    Handle<Map> map = JSObject::GetElementsTransitionMap(
10077af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org        array,
10078af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org        fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
100795d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    array->set_map(*map);
100805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    array->set_length(*length);
100815d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    array->set_elements(*storage_);
100825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    return array;
100835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
10084edf0cd1f0a597ded80ff7c8ab0e5ffdbcb7a5391kasperl@chromium.org
100859bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org private:
100865d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // Convert storage to dictionary mode.
1008784b86472bb519c85690c1cc7996b02ab618c0d16jkummerow@chromium.org  void SetDictionaryMode() {
100885d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    ASSERT(fast_elements_);
100899ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    Handle<FixedArray> current_storage(*storage_);
10090f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> slow_storage(
10091865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        SeededNumberDictionary::New(isolate_, current_storage->length()));
100925d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    uint32_t current_length = static_cast<uint32_t>(current_storage->length());
100935d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    for (uint32_t i = 0; i < current_length; i++) {
10094c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      HandleScope loop_scope(isolate_);
1009509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      Handle<Object> element(current_storage->get(i), isolate_);
100965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (!element->IsTheHole()) {
10097f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        Handle<SeededNumberDictionary> new_storage =
10098f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org            SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
100999ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        if (!new_storage.is_identical_to(slow_storage)) {
101009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org          slow_storage = loop_scope.CloseAndEscape(new_storage);
101019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org        }
101025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
101035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
101049ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    clear_storage();
101059ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    set_storage(*slow_storage);
101065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    fast_elements_ = false;
101075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
101085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
101099ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  inline void clear_storage() {
101104f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
101119ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
101129ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
101139ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  inline void set_storage(FixedArray* storage) {
10114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    storage_ = Handle<FixedArray>::cast(
10115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate_->global_handles()->Create(storage));
101169ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
101179ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
10118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
101199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  Handle<FixedArray> storage_;  // Always a global handle.
101205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // Index after last seen index. Always less than or equal to
101215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // JSObject::kMaxElementCount.
101229bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  uint32_t index_offset_;
10123e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool fast_elements_ : 1;
10124e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool exceeds_array_limit_ : 1;
101259bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org};
101269bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
101279bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
101285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgstatic uint32_t EstimateElementCount(Handle<JSArray> array) {
101295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t length = static_cast<uint32_t>(array->length()->Number());
101305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  int element_count = 0;
101315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  switch (array->GetElementsKind()) {
10132830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
10133830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
10134830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
10135830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
101365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Fast elements can't have lengths that are not representable by
101375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // a 32-bit signed integer.
101385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
101395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int fast_length = static_cast<int>(length);
101405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      Handle<FixedArray> elements(FixedArray::cast(array->elements()));
101415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (int i = 0; i < fast_length; i++) {
101425d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (!elements->get(i)->IsTheHole()) element_count++;
101435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
101445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
101455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
10146c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case FAST_DOUBLE_ELEMENTS:
10147fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS: {
10148fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // Fast elements can't have lengths that are not representable by
10149fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // a 32-bit signed integer.
10150fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
10151fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int fast_length = static_cast<int>(length);
10152fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (array->elements()->IsFixedArray()) {
10153fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ASSERT(FixedArray::cast(array->elements())->length() == 0);
10154fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        break;
10155fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
10156fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<FixedDoubleArray> elements(
10157fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          FixedDoubleArray::cast(array->elements()));
10158fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      for (int i = 0; i < fast_length; i++) {
10159fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (!elements->is_the_hole(i)) element_count++;
10160fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
10161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
10162fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
1016383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case DICTIONARY_ELEMENTS: {
10164f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Handle<SeededNumberDictionary> dictionary(
10165f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          SeededNumberDictionary::cast(array->elements()));
101665d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int capacity = dictionary->Capacity();
101675d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (int i = 0; i < capacity; i++) {
1016809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
101695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (dictionary->IsKey(*key)) {
101705d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          element_count++;
101715d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
101725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
101735d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
101745d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
10175486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    case SLOPPY_ARGUMENTS_ELEMENTS:
10176af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
10177af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ELEMENTS:                                         \
10178af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case TYPE##_ELEMENTS:                                                    \
10179af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
10180af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
10181af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
101825d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // External arrays are always dense.
101835d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      return length;
101845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
101855d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // As an estimate, we assume that the prototype doesn't contain any
101865d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // inherited elements.
101875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return element_count;
101885d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
101895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
101905d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
101915d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
101923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgtemplate<class ExternalArrayClass, class ElementType>
10193ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic void IterateExternalArrayElements(Isolate* isolate,
10194ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                         Handle<JSObject> receiver,
101955d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                         bool elements_are_ints,
101965d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                         bool elements_are_guaranteed_smis,
101975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                         ArrayConcatVisitor* visitor) {
101983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  Handle<ExternalArrayClass> array(
101993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      ExternalArrayClass::cast(receiver->elements()));
102005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t len = static_cast<uint32_t>(array->length());
102013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
102025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  ASSERT(visitor != NULL);
102035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  if (elements_are_ints) {
102045d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (elements_are_guaranteed_smis) {
102055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < len; j++) {
10206c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        HandleScope loop_scope(isolate);
1020709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
1020809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                      isolate);
102095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        visitor->visit(j, e);
102105d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
102115d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    } else {
102125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < len; j++) {
10213c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        HandleScope loop_scope(isolate);
102147c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        int64_t val = static_cast<int64_t>(array->get_scalar(j));
102155d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (Smi::IsValid(static_cast<intptr_t>(val))) {
1021609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org          Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
102175d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          visitor->visit(j, e);
102185d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        } else {
102195d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          Handle<Object> e =
10220ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org              isolate->factory()->NewNumber(static_cast<ElementType>(val));
102213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org          visitor->visit(j, e);
102223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        }
102235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
102245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
102255d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  } else {
102265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    for (uint32_t j = 0; j < len; j++) {
10227ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      HandleScope loop_scope(isolate);
102287c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
102295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      visitor->visit(j, e);
102305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
102315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
102325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
102335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
102345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
102355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org// Used for sorting indices in a List<uint32_t>.
102365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgstatic int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
102375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t a = *ap;
102385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t b = *bp;
102395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return (a == b) ? 0 : (a < b) ? -1 : 1;
102405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org}
102415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
102425d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
102435d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgstatic void CollectElementIndices(Handle<JSObject> object,
102445d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                  uint32_t range,
102455d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                                  List<uint32_t>* indices) {
1024609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Isolate* isolate = object->GetIsolate();
1024783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ElementsKind kind = object->GetElementsKind();
102485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  switch (kind) {
10249830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
10250830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
10251830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
10252830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
102535d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      Handle<FixedArray> elements(FixedArray::cast(object->elements()));
102545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      uint32_t length = static_cast<uint32_t>(elements->length());
102555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (range < length) length = range;
102565d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t i = 0; i < length; i++) {
102575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (!elements->get(i)->IsTheHole()) {
102585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          indices->Add(i);
102595d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
102605d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
102615d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
102625d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
10263830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
10264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case FAST_DOUBLE_ELEMENTS: {
10265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      // TODO(1810): Decide if it's worthwhile to implement this.
10266c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      UNREACHABLE();
10267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
10268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1026983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case DICTIONARY_ELEMENTS: {
10270f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Handle<SeededNumberDictionary> dict(
10271f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          SeededNumberDictionary::cast(object->elements()));
102725d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      uint32_t capacity = dict->Capacity();
102735d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < capacity; j++) {
1027409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        HandleScope loop_scope(isolate);
1027509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> k(dict->KeyAt(j), isolate);
102765d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (dict->IsKey(*k)) {
102775d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          ASSERT(k->IsNumber());
102785d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          uint32_t index = static_cast<uint32_t>(k->Number());
102795d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          if (index < range) {
102805d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org            indices->Add(index);
102813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org          }
102823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        }
102833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      }
102845d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
102855d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
102865d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    default: {
102875d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int dense_elements_length;
102885d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      switch (kind) {
10289af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
10290af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        case EXTERNAL_##TYPE##_ELEMENTS: {                                     \
10291af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org          dense_elements_length =                                              \
10292af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org              External##Type##Array::cast(object->elements())->length();       \
10293af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org          break;                                                               \
102945d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        }
10295af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
10296af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        TYPED_ARRAYS(TYPED_ARRAY_CASE)
10297af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
10298af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
102995d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        default:
103005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          UNREACHABLE();
103015d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          dense_elements_length = 0;
103025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          break;
103035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
103045d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      uint32_t length = static_cast<uint32_t>(dense_elements_length);
103055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (range <= length) {
103065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        length = range;
103075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        // We will add all indices, so we might as well clear it first
103085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        // and avoid duplicates.
103095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        indices->Clear();
103105d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
103115d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t i = 0; i < length; i++) {
103125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        indices->Add(i);
103133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      }
103145d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      if (length == range) return;  // All indices accounted for already.
103155d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
103163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
103173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
103183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
1031909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> prototype(object->GetPrototype(), isolate);
103205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  if (prototype->IsJSObject()) {
103215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // The prototype will usually have no inherited element indices,
103225d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    // but we have to check.
103235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
103245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
103253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
103263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
103275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
103289bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org/**
103295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * A helper function that visits elements of a JSArray in numerical
103305d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * order.
103319bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org *
103325d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * The visitor argument called for each existing element in the array
103335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * with the element index and the element's value.
103345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * Afterwards it increments the base-index of the visitor by the array
103355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * length.
103368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org * Returns false if any access threw an exception, otherwise true.
103379bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org */
10338ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic bool IterateElements(Isolate* isolate,
10339ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            Handle<JSArray> receiver,
103405d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                            ArrayConcatVisitor* visitor) {
103415d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
103420b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  switch (receiver->GetElementsKind()) {
10343830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
10344830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
10345830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
10346830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
103475d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Run through the elements FixedArray and use HasElement and GetElement
103485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // to check the prototype for missing elements.
103490b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
103505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int fast_length = static_cast<int>(length);
103515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      ASSERT(fast_length <= elements->length());
103525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (int j = 0; j < fast_length; j++) {
10353ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        HandleScope loop_scope(isolate);
10354ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        Handle<Object> element_value(elements->get(j), isolate);
103555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        if (!element_value->IsTheHole()) {
103565d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          visitor->visit(j, element_value);
10357528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        } else if (JSReceiver::HasElement(receiver, j)) {
103585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          // Call GetElement on receiver, not its prototype, or getters won't
103595d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          // have the correct receiver.
10360202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10361202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              isolate, element_value,
10362202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              Object::GetElement(isolate, receiver, j),
10363202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              false);
103645d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          visitor->visit(j, element_value);
103650b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        }
103660b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
103670b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
103680b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
10369830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
10370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    case FAST_DOUBLE_ELEMENTS: {
10371c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      // Empty array is FixedArray but not FixedDoubleArray.
10372c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      if (length == 0) break;
10373fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // Run through the elements FixedArray and use HasElement and GetElement
10374fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // to check the prototype for missing elements.
10375a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      if (receiver->elements()->IsFixedArray()) {
10376a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org        ASSERT(receiver->elements()->length() == 0);
10377a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org        break;
10378a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      }
10379fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<FixedDoubleArray> elements(
10380fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          FixedDoubleArray::cast(receiver->elements()));
10381fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int fast_length = static_cast<int>(length);
10382fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ASSERT(fast_length <= elements->length());
10383fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      for (int j = 0; j < fast_length; j++) {
10384fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        HandleScope loop_scope(isolate);
10385fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (!elements->is_the_hole(j)) {
10386fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          double double_value = elements->get_scalar(j);
10387fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          Handle<Object> element_value =
10388fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              isolate->factory()->NewNumber(double_value);
10389fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          visitor->visit(j, element_value);
10390528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        } else if (JSReceiver::HasElement(receiver, j)) {
10391fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          // Call GetElement on receiver, not its prototype, or getters won't
10392fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          // have the correct receiver.
10393202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          Handle<Object> element_value;
10394202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10395202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              isolate, element_value,
10396202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              Object::GetElement(isolate, receiver, j),
10397202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              false);
10398fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          visitor->visit(j, element_value);
10399fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
10400fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
10401c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      break;
10402c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
1040383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    case DICTIONARY_ELEMENTS: {
10404f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
104055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      List<uint32_t> indices(dict->Capacity() / 2);
104065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // Collect all indices in the object and the prototypes less
104075d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      // than length. This might introduce duplicates in the indices list.
104085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      CollectElementIndices(receiver, length, &indices);
104095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      indices.Sort(&compareUInt32);
104105d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int j = 0;
104115d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      int n = indices.length();
104125d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      while (j < n) {
10413c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org        HandleScope loop_scope(isolate);
104145d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        uint32_t index = indices[j];
10415202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Handle<Object> element;
10416202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10417202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org            isolate, element,
10418202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org            Object::GetElement(isolate, receiver, index),
10419202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org            false);
104205d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        visitor->visit(index, element);
104215d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        // Skip to next different index (i.e., omit duplicates).
104225d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        do {
104235d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org          j++;
104245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        } while (j < n && indices[j] == index);
104255d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
104265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      break;
104275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
10428af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
10429af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
104304d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org          receiver->elements()));
104315d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      for (uint32_t j = 0; j < length; j++) {
1043209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
104335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org        visitor->visit(j, e);
104349bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org      }
104350b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
104369bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
10437af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_INT8_ELEMENTS: {
10438af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalInt8Array, int8_t>(
10439ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
104403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
104413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
10442af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_UINT8_ELEMENTS: {
10443af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
10444ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
104453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
104463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
10447af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_INT16_ELEMENTS: {
10448af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalInt16Array, int16_t>(
10449ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
104503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
104513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
10452af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_UINT16_ELEMENTS: {
10453af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
10454ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, true, visitor);
104553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
104563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
10457af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_INT32_ELEMENTS: {
10458af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalInt32Array, int32_t>(
10459ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, false, visitor);
104603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
104613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
10462af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_UINT32_ELEMENTS: {
10463af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
10464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, true, false, visitor);
104653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
104663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
10467af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_FLOAT32_ELEMENTS: {
10468af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalFloat32Array, float>(
10469ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate, receiver, false, false, visitor);
104700b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
104719bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
10472af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_FLOAT64_ELEMENTS: {
10473af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      IterateExternalArrayElements<ExternalFloat64Array, double>(
104743847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com          isolate, receiver, false, false, visitor);
104753847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      break;
104763847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
104770b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    default:
104780b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      UNREACHABLE();
104790b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
104809bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
104815d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  visitor->increase_index_offset(length);
104828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  return true;
104839bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org}
104849bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
104859bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
104869bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org/**
104879bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * Array::concat implementation.
104889bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org * See ECMAScript 262, 15.4.4.4.
104895d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org * TODO(581): Fix non-compliance for very large concatenations and update to
104900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * following the ECMAScript 5 specification.
104919bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org */
10492a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ArrayConcat) {
10493ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handle_scope(isolate);
104946e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 1);
104959bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10496f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
104975d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  int argument_count = static_cast<int>(arguments->length()->Number());
10498830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  RUNTIME_ASSERT(arguments->HasFastObjectElements());
104995d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
105005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
105015d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // Pass 1: estimate the length and number of elements of the result.
105025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // The actual length can be larger if any of the arguments have getters
105035d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // that mutate other arguments (but will otherwise be precise).
105045d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  // The number of elements is precise if there are no inherited elements.
105055d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
10506fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsKind kind = FAST_SMI_ELEMENTS;
10507fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
105085d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t estimate_result_length = 0;
105095d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  uint32_t estimate_nof_elements = 0;
10510fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  for (int i = 0; i < argument_count; i++) {
10511c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    HandleScope loop_scope(isolate);
1051209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> obj(elements->get(i), isolate);
10513fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    uint32_t length_estimate;
10514fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    uint32_t element_estimate;
10515fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (obj->IsJSArray()) {
10516fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<JSArray> array(Handle<JSArray>::cast(obj));
10517fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      length_estimate = static_cast<uint32_t>(array->length()->Number());
10518fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (length_estimate != 0) {
10519fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        ElementsKind array_kind =
10520fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            GetPackedElementsKind(array->map()->elements_kind());
10521fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
10522fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          kind = array_kind;
10523c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
105245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      }
10525fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      element_estimate = EstimateElementCount(array);
10526fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
10527fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (obj->IsHeapObject()) {
10528fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (obj->IsNumber()) {
10529fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
10530fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            kind = FAST_DOUBLE_ELEMENTS;
10531fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          }
10532fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
10533fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          kind = FAST_ELEMENTS;
10534fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
105359bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org      }
10536fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      length_estimate = 1;
10537fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      element_estimate = 1;
10538fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
10539fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Avoid overflows by capping at kMaxElementCount.
10540fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (JSObject::kMaxElementCount - estimate_result_length <
10541fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        length_estimate) {
10542fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_result_length = JSObject::kMaxElementCount;
10543fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
10544fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_result_length += length_estimate;
10545fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
10546fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (JSObject::kMaxElementCount - estimate_nof_elements <
10547fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        element_estimate) {
10548fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_nof_elements = JSObject::kMaxElementCount;
10549fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
10550fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      estimate_nof_elements += element_estimate;
105519bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    }
105529bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
105539bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
105549bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // If estimated number of elements is more than half of length, a
105559bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // fixed array (fast case) is more time and space-efficient than a
105569bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // dictionary.
105575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
105589bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10559f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
10560f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<FixedArrayBase> storage =
10561f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        isolate->factory()->NewFixedDoubleArray(estimate_result_length);
10562f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    int j = 0;
10563f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    if (estimate_result_length > 0) {
10564fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Handle<FixedDoubleArray> double_storage =
10565f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org          Handle<FixedDoubleArray>::cast(storage);
10566fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      bool failure = false;
10567fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      for (int i = 0; i < argument_count; i++) {
1056809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> obj(elements->get(i), isolate);
10569fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (obj->IsSmi()) {
10570fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          double_storage->set(j, Smi::cast(*obj)->value());
10571fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          j++;
10572fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else if (obj->IsNumber()) {
10573fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          double_storage->set(j, obj->Number());
10574fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          j++;
10575fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        } else {
10576fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          JSArray* array = JSArray::cast(*obj);
10577fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          uint32_t length = static_cast<uint32_t>(array->length()->Number());
10578fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          switch (array->map()->elements_kind()) {
10579fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_HOLEY_DOUBLE_ELEMENTS:
10580fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_DOUBLE_ELEMENTS: {
10581c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org              // Empty array is FixedArray but not FixedDoubleArray.
10582c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org              if (length == 0) break;
10583fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              FixedDoubleArray* elements =
10584fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  FixedDoubleArray::cast(array->elements());
10585fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              for (uint32_t i = 0; i < length; i++) {
10586fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                if (elements->is_the_hole(i)) {
10587fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  failure = true;
10588fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  break;
10589fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                }
10590fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                double double_value = elements->get_scalar(i);
10591fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                double_storage->set(j, double_value);
10592fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                j++;
10593fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              }
10594fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              break;
10595fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            }
10596fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_HOLEY_SMI_ELEMENTS:
10597fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_SMI_ELEMENTS: {
10598fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              FixedArray* elements(
10599fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  FixedArray::cast(array->elements()));
10600fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              for (uint32_t i = 0; i < length; i++) {
10601fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                Object* element = elements->get(i);
10602fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                if (element->IsTheHole()) {
10603fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  failure = true;
10604fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  break;
10605fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                }
10606fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                int32_t int_value = Smi::cast(element)->value();
10607fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                double_storage->set(j, int_value);
10608fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                j++;
10609fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              }
10610fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              break;
10611fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            }
10612fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            case FAST_HOLEY_ELEMENTS:
10613fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              ASSERT_EQ(0, length);
10614fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              break;
10615fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            default:
10616fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org              UNREACHABLE();
10617fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          }
10618fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
10619fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (failure) break;
10620fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
10621fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
10622f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<JSArray> array = isolate->factory()->NewJSArray(0);
10623f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Smi* length = Smi::FromInt(j);
10624f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Map> map;
10625f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    map = JSObject::GetElementsTransitionMap(array, kind);
10626f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    array->set_map(*map);
10627f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    array->set_length(length);
10628f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    array->set_elements(*storage);
10629f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    return *array;
10630f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  }
10631f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
10632f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<FixedArray> storage;
10633f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (fast_case) {
10634fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // The backing storage array must have non-existing elements to preserve
10635fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // holes across concat operations.
10636ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    storage = isolate->factory()->NewFixedArrayWithHoles(
10637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        estimate_result_length);
106389bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  } else {
106399bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
106409bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    uint32_t at_least_space_for = estimate_nof_elements +
106419bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org                                  (estimate_nof_elements >> 2);
106429bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org    storage = Handle<FixedArray>::cast(
10643865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        SeededNumberDictionary::New(isolate, at_least_space_for));
106449bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
106459bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10646ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ArrayConcatVisitor visitor(isolate, storage, fast_case);
106479bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
106485d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  for (int i = 0; i < argument_count; i++) {
1064909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> obj(elements->get(i), isolate);
106505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    if (obj->IsJSArray()) {
106515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      Handle<JSArray> array = Handle<JSArray>::cast(obj);
10652ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      if (!IterateElements(isolate, array, &visitor)) {
10653a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        return isolate->heap()->exception();
106548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      }
106555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    } else {
106565d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      visitor.visit(0, obj);
106575d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org      visitor.increase_index_offset(1);
106585d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    }
106595d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  }
106609bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
10661e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (visitor.exceeds_array_limit()) {
10662e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return isolate->Throw(
10663e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        *isolate->factory()->NewRangeError("invalid_array_length",
10664e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                                           HandleVector<Object>(NULL, 0)));
10665e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
106665d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  return *visitor.ToArray();
106679bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org}
106689bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
106699bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
1067043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This will not allocate (flatten the string), but it may run
1067143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// very slowly for very deeply nested ConsStrings.  For debugging use only.
10672a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GlobalPrint) {
1067379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1067443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1067543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10676f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, string, 0);
106774cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ConsStringIteratorOp op;
106784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(string, &op);
106794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  while (stream.HasMore()) {
106804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t character = stream.GetNext();
1068143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    PrintF("%c", character);
1068243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1068343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return string;
1068443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1068543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10686e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
106875ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Moves all own elements of an object, that are below a limit, to positions
106885ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// starting at zero. All undefined values are placed after non-undefined values,
106895ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// and are followed by non-existing element. Does not change the length
106905ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// property.
106915ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Returns the number of non-undefined elements collected.
1069297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org// Returns -1 if hole removal is not supported by this method.
10693a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
10694ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  HandleScope scope(isolate);
106955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  ASSERT(args.length() == 2);
10696ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
106975ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
10698ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  return *JSObject::PrepareElementsForSort(object, limit);
1069943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1070043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1070143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1070243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Move contents of argument 0 (an array) to argument 1 (an array)
10703a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MoveArrayContents) {
1070463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  HandleScope scope(isolate);
1070543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1070663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
1070763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
1070849ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  JSObject::ValidateElements(from);
1070949ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  JSObject::ValidateElements(to);
1071063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
1071163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  Handle<FixedArrayBase> new_elements(from->elements());
10712830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ElementsKind from_kind = from->GetElementsKind();
1071363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
1071463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  JSObject::SetMapAndElements(to, new_map, new_elements);
1071543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  to->set_length(from->length());
1071663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
1071763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  JSObject::ResetElements(from);
10718b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  from->set_length(Smi::FromInt(0));
1071963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
1072049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  JSObject::ValidateElements(to);
1072163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  return *to;
1072243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1072343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1072443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107252ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org// How many elements does this object/array have?
10726a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
1072779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1072843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
10729a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  CONVERT_ARG_CHECKED(JSArray, object, 0);
107302ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org  HeapObject* elements = object->elements();
1073143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (elements->IsDictionary()) {
10732f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
10733f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return Smi::FromInt(result);
1073443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
10735a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    return object->length();
1073643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1073743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1073843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1073943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1074043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns an array that tells you where in the [0, length) interval an array
10741f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// might have elements.  Can either return an array of keys (positive integers
10742f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// or undefined) or a number representing the positive length of an interval
10743f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org// starting at index 0.
107442ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org// Intervals can span over some keys that are not in the object.
10745a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetArrayKeys) {
10746ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
107476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 2);
10748f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
1074943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
107509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (array->elements()->IsDictionary()) {
10751f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10752f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    for (Handle<Object> p = array;
10753f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org         !p->IsNull();
10754f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org         p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
10755f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
10756f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        // Bail out if we find a proxy or interceptor, likely not worth
10757f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        // collecting keys in that case.
10758f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        return *isolate->factory()->NewNumberFromUint(length);
1075943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
10760f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      Handle<JSObject> current = Handle<JSObject>::cast(p);
10761f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      Handle<FixedArray> current_keys =
10762fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org          isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
10763fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      current->GetOwnElementKeys(*current_keys, NONE);
10764202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10765202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
10766f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
10767f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Erase any keys >= length.
10768f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10769f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // is changed to let this happen on the JS side.
10770f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    for (int i = 0; i < keys->length(); i++) {
10771f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
1077243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
10773ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return *isolate->factory()->NewJSArrayWithElements(keys);
1077443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
10775a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
10776a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org                   array->HasFastDoubleElements());
10777f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10778f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
1077943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1078043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1078143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1078243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10783a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LookupAccessor) {
10784fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  HandleScope scope(isolate);
1078543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
10786fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
10787fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10788f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(flag, 2);
107899a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10790657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
107918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Object> result;
107928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
107938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result,
107948496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
10795fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return *result;
1079643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1079743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1079843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10799a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugBreak) {
1080079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1080165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  ASSERT(args.length() == 0);
108028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  isolate->debug()->HandleDebugBreak();
108033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  return isolate->heap()->undefined_value();
1080465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
1080565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
1080665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
1080743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper functions for wrapping and unwrapping stack frame ids.
1080843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic Smi* WrapFrameId(StackFrame::Id id) {
1080971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
1081043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(id >> 2);
1081143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1081243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1081343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10814f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic StackFrame::Id UnwrapFrameId(int wrapped) {
10815f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return static_cast<StackFrame::Id>(wrapped << 2);
1081643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1081743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1081843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1081943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Adds a JavaScript function as a debug event listener.
10820245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// args[0]: debug event listener function to set or null or undefined for
10821245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org//          clearing the event listener function
1082243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: object supplied during callback
10823a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
1082479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1082543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
10826245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  RUNTIME_ASSERT(args[0]->IsJSFunction() ||
10827245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                 args[0]->IsUndefined() ||
10828245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                 args[0]->IsNull());
108298496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
108308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
10831d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  isolate->debug()->SetEventListener(callback, data);
1083243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10833ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1083443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1083543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1083643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10837a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Break) {
1083879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1083931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
108403c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  isolate->stack_guard()->RequestDebugBreak();
10841ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1084243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1084343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1084443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10845c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgstatic Handle<Object> DebugLookupResultValue(Isolate* isolate,
10846c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                             Handle<Object> receiver,
10847c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                             Handle<Name> name,
10848c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                             LookupResult* result,
10849c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                             bool* has_caught = NULL) {
10850c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Object> value = isolate->factory()->undefined_value();
10851c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if  (!result->IsFound()) return value;
1085243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (result->type()) {
108532abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    case NORMAL:
10854c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      value = JSObject::GetNormalizedProperty(
10855c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          handle(result->holder(), isolate), result);
10856c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      break;
10857c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    case FIELD:
10858c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
10859c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                       result->representation(),
10860e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                       result->GetFieldIndex());
10861c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      break;
10862fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    case CONSTANT:
10863c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      return handle(result->GetConstant(), isolate);
108643291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    case CALLBACKS: {
10865c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      Handle<Object> structure(result->GetCallbackObject(), isolate);
108663484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      ASSERT(!structure->IsForeign());
108673484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      if (structure->IsAccessorInfo()) {
108688ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor(
10869e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org            receiver, name, handle(result->holder(), isolate), structure);
10870c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        if (!obj.ToHandle(&value)) {
10871c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          value = handle(isolate->pending_exception(), isolate);
10872c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          isolate->clear_pending_exception();
10873c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          if (has_caught != NULL) *has_caught = true;
10874c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          return value;
10875c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        }
1087643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
10877c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      break;
108783291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    }
1087943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case INTERCEPTOR:
10880c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    case HANDLER:
10881a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      break;
108827a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org    case NONEXISTENT:
1088343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
10884c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      break;
1088543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
10886c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  ASSERT(!value->IsTheHole() || result->IsReadOnly());
10887c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return value->IsTheHole()
10888c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value;
1088943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1089043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1089143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108923291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// Get debugger related details for an object property.
108933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// args[0]: object holding property
108943291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// args[1]: name of the property
108953291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org//
108963291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// The array returned contains the following information:
108973291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 0: Property value
108983291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 1: Property details
108993291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 2: Property value is exception
109003291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 3: Getter function if defined
109013291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// 4: Setter function if defined
109023291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// Items 2-4 are only filled if the property has either a getter or a setter
109033291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// defined through __defineGetter__ and/or __defineSetter__.
10904a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
10905ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1090643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1090743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1090843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10909f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10910750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1091143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10912755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Make sure to set the current context to the context before the debugger was
10913755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // entered (if the debugger is entered). The reason for switching context here
10914755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // is that for some property lookups (accessors and interceptors) callbacks
10915755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // into the embedding application can occour, and the embedding application
1091646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // could have the assumption that its own native context is the current
10917755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // context and not some internal debugger context.
10918ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SaveContext save(isolate);
10919196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (isolate->debug()->in_debug_scope()) {
10920ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
10921755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  }
10922755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
10923ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Skip the global proxy as it has no properties and always delegates to the
10924ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // real global object.
10925ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  if (obj->IsJSGlobalProxy()) {
10926ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
10927ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
10928ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10929ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1093043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the name is trivially convertible to an index and get the element
1093143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // if so.
1093243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t index;
1093343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
10934ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
10935202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> element_or_char;
10936202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10937202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        isolate, element_or_char,
10938202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Runtime::GetElementOrCharAt(isolate, obj, index));
109399b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    details->set(0, *element_or_char);
10940f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    details->set(
10941f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
10942ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return *isolate->factory()->NewJSArrayWithElements(details);
1094343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1094443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10945ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Find the number of objects making up this.
10946fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  int length = OwnPrototypeChainLength(*obj);
10947ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10948fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // Try own lookup on each of the objects.
10949ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  Handle<JSObject> jsproto = obj;
10950ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  for (int i = 0; i < length; i++) {
10951394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    LookupResult result(isolate);
10952fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    jsproto->LookupOwn(name, &result);
10953753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    if (result.IsFound()) {
109542bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // LookupResult is not GC safe as it holds raw object pointers.
109552bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // GC can happen later in this code so put the required fields into
109562bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // local variables using handles when required for later use.
109572bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      Handle<Object> result_callback_obj;
1095899aa490225c81012235659d9a183226b286178c8yangguo@chromium.org      if (result.IsPropertyCallbacks()) {
10959ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        result_callback_obj = Handle<Object>(result.GetCallbackObject(),
10960ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                             isolate);
109612bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      }
10962c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
10963c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
10964c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      bool has_caught = false;
10965c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      Handle<Object> value = DebugLookupResultValue(
10966c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          isolate, obj, name, &result, &has_caught);
109672bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
109682bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // If the callback object is a fixed array then it contains JavaScript
109692bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      // getter and/or setter.
10970c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      bool has_js_accessors = result.IsPropertyCallbacks() &&
10971c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                              result_callback_obj->IsAccessorPair();
109722bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      Handle<FixedArray> details =
10973c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
109742bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      details->set(0, *value);
10975c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      details->set(1, result.GetPropertyDetails().AsSmi());
10976c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      if (has_js_accessors) {
10977bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com        AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
10978c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        details->set(2, isolate->heap()->ToBoolean(has_caught));
1097988aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org        details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
1098088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org        details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
109812bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      }
109822bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
10983ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return *isolate->factory()->NewJSArrayWithElements(details);
10984ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
10985ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    if (i < length - 1) {
10986ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
10987ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
10988ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
10989ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10990ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1099143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1099243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1099343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10994a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugGetProperty) {
10995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1099643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1099743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1099843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10999f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11000750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11002394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult result(isolate);
110033484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  obj->Lookup(name, &result);
11004c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return *DebugLookupResultValue(isolate, obj, name, &result);
1100543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1100843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the property type calculated from the property details.
1100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: smi with property details.
11010a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
1101179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
11013f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11014f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return Smi::FromInt(static_cast<int>(details.type()));
1101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1101643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1101743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1101843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the property attribute calculated from the property details.
1101943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: smi with property details.
11020a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
1102179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1102243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
11023f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11024f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return Smi::FromInt(static_cast<int>(details.attributes()));
1102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1102743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1102843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the property insertion index calculated from the property details.
1102943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: smi with property details.
11030a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
1103179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
11033f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
1103446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // TODO(verwaest): Depends on the type of details.
1103546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return Smi::FromInt(details.dictionary_index());
1103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return property value from named interceptor.
1104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: object
1104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: property name
11042a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
11043ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1104443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
11045f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(obj->HasNamedInterceptor());
11047750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110498f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Object> result;
110508ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  LookupIterator it(obj, name, obj);
110518f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
110528ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      isolate, result, JSObject::GetProperty(&it));
11053dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  return *result;
1105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return element value from indexed interceptor.
1105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: object
1105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: index
11060a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
11061ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
11063f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(obj->HasIndexedInterceptor());
1106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
11066202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> result;
11067202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11068202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
11069b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  return *result;
1107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
110738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgstatic bool CheckExecutionState(Isolate* isolate, int break_id) {
110746a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  return !isolate->debug()->debug_context().is_null() &&
110756a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org         isolate->debug()->break_id() != 0 &&
110766a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org         isolate->debug()->break_id() == break_id;
110778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org}
110788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
110798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
11080a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CheckExecutionState) {
1108179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
110828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
1108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
110848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11085ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->true_value();
1108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11089a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetFrameCount) {
11090ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
110928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
110938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
1109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Count all frames which are relevant to debugging stack trace.
1109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int n = 0;
11097ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  StackFrame::Id id = isolate->debug()->break_frame_id();
110988bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  if (id == StackFrame::NO_ID) {
110998bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    // If there is no JavaScript stack frame count is 0.
111008bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    return Smi::FromInt(0);
111018bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
111024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
111034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
111044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    n += it.frame()->GetInlineCount();
111054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
1110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Smi::FromInt(n);
1110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1111084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.orgclass FrameInspector {
1111184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org public:
1111284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  FrameInspector(JavaScriptFrame* frame,
11113659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                 int inlined_jsframe_index,
1111484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                 Isolate* isolate)
1111584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
1111684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    // Calculate the deoptimized frame.
1111784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (frame->is_optimized()) {
1111884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
11119659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          frame, inlined_jsframe_index, isolate);
1112084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    }
1112184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    has_adapted_arguments_ = frame_->has_adapted_arguments();
11122967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    is_bottommost_ = inlined_jsframe_index == 0;
1112384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    is_optimized_ = frame_->is_optimized();
1112484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1112584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1112684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ~FrameInspector() {
1112784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    // Get rid of the calculated deoptimized frame if any.
1112884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    if (deoptimized_frame_ != NULL) {
1112984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
1113084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                                                  isolate_);
1113184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    }
1113284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1113384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1113484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  int GetParametersCount() {
1113584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1113684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->parameters_count()
1113784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->ComputeParametersCount();
1113884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1113984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  int expression_count() { return deoptimized_frame_->expression_count(); }
1114084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Object* GetFunction() {
1114184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1114284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->GetFunction()
1114384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->function();
1114484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1114584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Object* GetParameter(int index) {
1114684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1114784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->GetParameter(index)
1114884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->GetParameter(index);
1114984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1115084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Object* GetExpression(int index) {
1115184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return is_optimized_
1115284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        ? deoptimized_frame_->GetExpression(index)
1115384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org        : frame_->GetExpression(index);
1115484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
11155fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  int GetSourcePosition() {
11156fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    return is_optimized_
11157fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org        ? deoptimized_frame_->GetSourcePosition()
11158fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org        : frame_->LookupCode()->SourcePosition(frame_->pc());
11159fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
11160967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool IsConstructor() {
11161967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    return is_optimized_ && !is_bottommost_
11162967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        ? deoptimized_frame_->HasConstructStub()
11163967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        : frame_->IsConstructor();
11164967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  }
1116584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1116684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  // To inspect all the provided arguments the frame might need to be
1116784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  // replaced with the arguments frame.
1116884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  void SetArgumentsFrame(JavaScriptFrame* frame) {
1116984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    ASSERT(has_adapted_arguments_);
1117084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    frame_ = frame;
1117184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    is_optimized_ = frame_->is_optimized();
1117284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    ASSERT(!is_optimized_);
1117384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1117484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1117584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org private:
1117684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  JavaScriptFrame* frame_;
1117784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  DeoptimizedFrameInfo* deoptimized_frame_;
1117884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  Isolate* isolate_;
1117984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  bool is_optimized_;
11180967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool is_bottommost_;
1118184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  bool has_adapted_arguments_;
1118284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1118384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  DISALLOW_COPY_AND_ASSIGN(FrameInspector);
1118484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org};
1118584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1118684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
1118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsFrameIdIndex = 0;
1118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsReceiverIndex = 1;
1118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsFunctionIndex = 2;
1119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsArgumentCountIndex = 3;
1119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsLocalCountIndex = 4;
1119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsSourcePositionIndex = 5;
1119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kFrameDetailsConstructCallIndex = 6;
111942cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgstatic const int kFrameDetailsAtReturnIndex = 7;
111954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic const int kFrameDetailsFlagsIndex = 8;
111962cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.orgstatic const int kFrameDetailsFirstDynamicIndex = 9;
1119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11198c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
11199c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic SaveContext* FindSavedContextForFrame(Isolate* isolate,
11200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                             JavaScriptFrame* frame) {
11201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SaveContext* save = isolate->save_context();
11202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  while (save != NULL && !save->IsBelowFrame(frame)) {
11203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    save = save->prev();
11204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
11205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(save != NULL);
11206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return save;
11207c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
11208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
11209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return an array with frame details
1121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: number: break id
1121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: number: frame index
1121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The array returned contains the following information:
1121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 0: Frame id
1121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1: Receiver
1121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2: Function
1121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3: Argument count
1121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 4: Local count
1122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 5: Source position
1122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 6: Constructor call
112222cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org// 7: Is at return
112234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org// 8: Flags
1122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Arguments name, value
1122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Locals name, value
112262cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org// Return value if any
11227a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetFrameDetails) {
11228ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
112308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
112318496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
1123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
11234ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
1123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the relevant frame with the requested index.
11237ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  StackFrame::Id id = isolate->debug()->break_frame_id();
112388bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  if (id == StackFrame::NO_ID) {
112398bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    // If there are no JavaScript stack frames return undefined.
11240ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return heap->undefined_value();
112418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
112424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
1124474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate, id);
1124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (; !it.done(); it.Advance()) {
112464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (index < count + it.frame()->GetInlineCount()) break;
112474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    count += it.frame()->GetInlineCount();
1124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
11249ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (it.done()) return heap->undefined_value();
1125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11251659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  bool is_optimized = it.frame()->is_optimized();
11252659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11253659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
11254659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (is_optimized) {
11255659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    inlined_jsframe_index =
112564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        it.frame()->GetInlineCount() - (index - count) - 1;
112574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
11258659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
11259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the saved contexts chain to find the active context for the
1126143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // selected frame.
11262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
1126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the frame id.
11265ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
1126643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11267fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Find source position in unoptimized code.
11268fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  int position = frame_inspector.GetSourcePosition();
1126943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11270967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  // Check for constructor frame.
11271967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  bool constructor = frame_inspector.IsConstructor();
1127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112736a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Get scope info and read from it for local variable information.
11274659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11275717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11276c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
112778432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  ASSERT(*scope_info != ScopeInfo::Empty(isolate));
1127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the locals names and values into a temporary array.
112805aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int local_count = scope_info->LocalCount();
112815aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
112825aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    // Hide compiler-introduced temporary variables, whether on the stack or on
112835aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    // the context.
112845aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    if (scope_info->LocalIsSynthetic(slot))
112855aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      local_count--;
112865aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  }
112875aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
11288ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> locals =
112895aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      isolate->factory()->NewFixedArray(local_count * 2);
11290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Fill in the values of the locals.
112925aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int local = 0;
112934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int i = 0;
11294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (; i < scope_info->StackLocalCount(); ++i) {
112954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // Use the value from the stack.
112965aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    if (scope_info->LocalIsSynthetic(i))
112975aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      continue;
112985aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    locals->set(local * 2, scope_info->LocalName(i));
112995aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
113005aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    local++;
113014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
113025aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  if (local < local_count) {
113033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    // Get the context containing declarations.
113043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    Handle<Context> context(
113053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org        Context::cast(it.frame()->context())->declaration_context());
11306c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    for (; i < scope_info->LocalCount(); ++i) {
113075aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      if (scope_info->LocalIsSynthetic(i))
113085aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org        continue;
11309c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<String> name(scope_info->LocalName(i));
11310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      VariableMode mode;
11311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      InitializationFlag init_flag;
113125aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      locals->set(local * 2, *name);
11313b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      int context_slot_index =
11314a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org          ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
11315b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      Object* value = context->get(context_slot_index);
113165aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      locals->set(local * 2 + 1, value);
113175aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      local++;
1131843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1131943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1132043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check whether this frame is positioned at return. If not top
11322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // frame or if the frame is optimized it cannot be at a return.
11323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool at_return = false;
11324659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (!is_optimized && index == 0) {
11325ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    at_return = isolate->debug()->IsBreakAtReturn(it.frame());
11326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
113272cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
113282cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // If positioned just before return find the value to be returned and add it
113292cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // to the frame information.
11330ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> return_value = isolate->factory()->undefined_value();
113312cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  if (at_return) {
1133274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    StackFrameIterator it2(isolate);
113332cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    Address internal_frame_sp = NULL;
113342cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    while (!it2.done()) {
113352cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      if (it2.frame()->is_internal()) {
113362cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        internal_frame_sp = it2.frame()->sp();
113372cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      } else {
113382cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        if (it2.frame()->is_java_script()) {
113392cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org          if (it2.frame()->id() == it.frame()->id()) {
113402cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // The internal frame just before the JavaScript frame contains the
113412cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // value to return on top. A debug break at return will create an
113422cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // internal frame to store the return value (eax/rax/r0) before
113432cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            // entering the debug break exit frame.
113442cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            if (internal_frame_sp != NULL) {
113452cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org              return_value =
11346ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                  Handle<Object>(Memory::Object_at(internal_frame_sp),
11347ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 isolate);
113482cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org              break;
113492cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org            }
113502cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org          }
113512cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        }
113522cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
113532cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        // Indicate that the previous frame was not an internal frame.
113542cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org        internal_frame_sp = NULL;
113552cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      }
113562cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org      it2.Advance();
113572cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    }
113582cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  }
1135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Now advance to the arguments adapter frame (if any). It contains all
1136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the provided parameters whereas the function frame always have the number
1136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // of arguments matching the functions parameters. The rest of the
1136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // information (except for what is collected above) is the same.
11364659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
1136584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    it.AdvanceToArgumentsFrame();
1136684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    frame_inspector.SetArgumentsFrame(it.frame());
1136784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the number of arguments to fill. At least fill the number of
1137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // parameters for the function and fill more if more parameters are provided.
11371c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int argument_count = scope_info->ParameterCount();
1137284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  if (argument_count < frame_inspector.GetParametersCount()) {
1137384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    argument_count = frame_inspector.GetParametersCount();
1137484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
1137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Calculate the size of the result.
1137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int details_size = kFrameDetailsFirstDynamicIndex +
113785aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org                     2 * (argument_count + local_count) +
113792cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org                     (at_return ? 1 : 0);
11380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
1138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the frame id.
1138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsFrameIdIndex, *frame_id);
1138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1138543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the function (same as in function frame).
1138684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
1138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the arguments count.
1138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
1139043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1139143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the locals count
1139243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsLocalCountIndex,
113935aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org               Smi::FromInt(local_count));
1139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1139543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the source position.
11396236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  if (position != RelocInfo::kNoPosition) {
1139743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
1139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
11399ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
1140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the constructor information.
11403ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
1140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114052cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Add the at return information.
11406ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
114072cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
114084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Add flags to indicate information on whether this frame is
114094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //   bit 0: invoked in the debugger context.
114104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //   bit 1: optimized frame.
114114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  //   bit 2: inlined in optimized frame
114124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  int flags = 0;
114134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (*save->context() == *isolate->debug()->debug_context()) {
114144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    flags |= 1 << 0;
114154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
11416659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (is_optimized) {
114174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    flags |= 1 << 1;
11418659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    flags |= inlined_jsframe_index << 2;
114194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
114204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
1142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the dynamic part.
1142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int details_index = kFrameDetailsFirstDynamicIndex;
1142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1142543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add arguments name and value.
1142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < argument_count; i++) {
1142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Name of the argument.
11428c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (i < scope_info->ParameterCount()) {
11429c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      details->set(details_index++, scope_info->ParameterName(i));
1143043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
11431ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      details->set(details_index++, heap->undefined_value());
1143243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1143343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    // Parameter value.
11435659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (i < frame_inspector.GetParametersCount()) {
1143684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      // Get the value from the stack.
1143784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      details->set(details_index++, frame_inspector.GetParameter(i));
1143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
1143984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      details->set(details_index++, heap->undefined_value());
1144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1144143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add locals name and value from the temporary copy from the function frame.
114445aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  for (int i = 0; i < local_count * 2; i++) {
1144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    details->set(details_index++, locals->get(i));
1144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
114482cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  // Add the value being returned.
114492cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  if (at_return) {
114502cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org    details->set(details_index++, *return_value);
114512cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  }
114522cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
1145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the receiver (same as in function frame).
1145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
1145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // THE FRAME ITERATOR TO WRAP THE RECEIVER.
11456ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> receiver(it.frame()->receiver(), isolate);
114571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (!receiver->IsJSObject() &&
11458486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      shared->strict_mode() == SLOPPY &&
11459bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      !function->IsBuiltin()) {
11460717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // If the receiver is not a JSObject and the function is not a
11461717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // builtin or strict-mode we have hit an optimization where a
11462717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // value object is not converted into a wrapped JS objects. To
11463717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    // hide this optimization from the debugger, we wrap the receiver
1146443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // by creating correct wrapper object based on the calling frame's
1146546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // native context.
1146643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.Advance();
11467e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    if (receiver->IsUndefined()) {
11468e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      Context* context = function->context();
11469e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      receiver = handle(context->global_object()->global_receiver());
11470e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    } else {
11471e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      ASSERT(!receiver->IsNull());
11472e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      Context* context = Context::cast(it.frame()->context());
11473e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      Handle<Context> native_context(Context::cast(context->native_context()));
1147474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org      receiver = Object::ToObject(
1147574dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org          isolate, receiver, native_context).ToHandleChecked();
11476e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    }
1147743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1147843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details->set(kFrameDetailsReceiverIndex, *receiver);
1147943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1148043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT_EQ(details_size, details_index);
11481ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(details);
1148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1148343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1148443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11485a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgstatic bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
11486a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                              Handle<String> parameter_name) {
11487a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  VariableMode mode;
11488a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  InitializationFlag flag;
11489a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &flag) != -1;
11490a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org}
11491a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
11492a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
11493eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// Create a plain JSObject which materializes the local scope for the specified
11494eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// frame.
114958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT
114968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgstatic MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
1149784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    Isolate* isolate,
11498ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSObject> target,
11499ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSFunction> function,
11500659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    FrameInspector* frame_inspector) {
115016a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11502c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11503eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11504eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // First fill all parameters.
11505c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
115064954674151afa960af66efb4831df06bde727333yangguo@chromium.org    // Do not materialize the parameter if it is shadowed by a context local.
11507a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<String> name(scope_info->ParameterName(i));
11508a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
115094954674151afa960af66efb4831df06bde727333yangguo@chromium.org
11510a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    HandleScope scope(isolate);
1151109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> value(i < frame_inspector->GetParametersCount()
1151209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             ? frame_inspector->GetParameter(i)
1151309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                             : isolate->heap()->undefined_value(),
1151409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                         isolate);
11515594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(!value->IsTheHole());
11516659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
115178f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_ON_EXCEPTION(
11518ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
11519486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
115208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        JSObject);
11521eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11522eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11523eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Second fill all stack locals.
11524c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
115255aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    if (scope_info->LocalIsSynthetic(i)) continue;
115264954674151afa960af66efb4831df06bde727333yangguo@chromium.org    Handle<String> name(scope_info->StackLocalName(i));
11527594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11528594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (value->IsTheHole()) continue;
11529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
115308f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_ON_EXCEPTION(
11531ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate,
11532486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
115338f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        JSObject);
11534eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11535eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11536ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return target;
11537ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
115384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
11539ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11540ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11541ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    Handle<JSObject> target,
11542ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    Handle<JSFunction> function,
11543ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    JavaScriptFrame* frame,
11544ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                    int inlined_jsframe_index) {
11545ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11546ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Optimized frames are not supported.
11547ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // TODO(yangguo): make sure all code deoptimized when debugger is active
11548ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    //                and assert that this cannot happen.
11549ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return;
11550ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11551ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11552ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11553ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11554ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11555ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Parameters.
11556ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11557a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    // Shadowed parameters were not materialized.
11558a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<String> name(scope_info->ParameterName(i));
11559a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11560a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
11561594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    ASSERT(!frame->GetParameter(i)->IsTheHole());
11562ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HandleScope scope(isolate);
11563202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> value =
11564202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Object::GetPropertyOrElement(target, name).ToHandleChecked();
11565ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    frame->SetParameterValue(i, *value);
11566ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11567ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11568ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Stack locals.
11569ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
115705aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    if (scope_info->LocalIsSynthetic(i)) continue;
11571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (frame->GetExpression(i)->IsTheHole()) continue;
11572ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HandleScope scope(isolate);
115732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    Handle<Object> value = Object::GetPropertyOrElement(
11574202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        target,
11575202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
11576ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    frame->SetExpression(i, *value);
11577ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11578ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
11579ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11580ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
115818f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
115828f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Isolate* isolate,
115838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<JSObject> target,
115848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<JSFunction> function,
115858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    JavaScriptFrame* frame) {
11586ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  HandleScope scope(isolate);
11587ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11588ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11589ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11590ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!scope_info->HasContext()) return target;
11591ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11592ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Third fill all context locals.
11593ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Context> frame_context(Context::cast(frame->context()));
11594ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Context> function_context(frame_context->declaration_context());
11595d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (!ScopeInfo::CopyContextLocalsToScopeObject(
11596d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org          scope_info, function_context, target)) {
115978f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return MaybeHandle<JSObject>();
11598ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
11599ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11600ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Finally copy any properties from the function context extension.
11601ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // These will be variables introduced by eval.
11602ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (function_context->closure() == *function) {
11603ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (function_context->has_extension() &&
11604ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        !function_context->IsNativeContext()) {
11605ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11606202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Handle<FixedArray> keys;
11607202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
116089fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          isolate, keys,
116099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
116109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          JSObject);
11611ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11612ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      for (int i = 0; i < keys->length(); i++) {
11613ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        // Names of variables introduced by eval are strings.
11614ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        ASSERT(keys->get(i)->IsString());
11615ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        Handle<String> key(String::cast(keys->get(i)));
11616202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Handle<Object> value;
11617202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        ASSIGN_RETURN_ON_EXCEPTION(
11618202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org            isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
116198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        RETURN_ON_EXCEPTION(
11620ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            isolate,
11621202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org            Runtime::SetObjectProperty(
11622202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                isolate, target, key, value, NONE, SLOPPY),
116238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            JSObject);
11624eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      }
11625eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11626eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
116274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
11628ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return target;
11629eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
11630eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11631eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
116328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
11633659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Isolate* isolate,
11634659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    JavaScriptFrame* frame,
11635659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int inlined_jsframe_index) {
11636659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
11637ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11638ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11639ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSObject> local_scope =
11640ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
116418f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
116428f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, local_scope,
116438f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      MaterializeStackLocalsWithFrameInspector(
116448f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          isolate, local_scope, function, &frame_inspector),
116458f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      JSObject);
11646ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
11647ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return MaterializeLocalContext(isolate, local_scope, function, frame);
11648659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
11649659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11650659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11651a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Set the context local variable value.
11652a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic bool SetContextLocalValue(Isolate* isolate,
11653a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<ScopeInfo> scope_info,
11654a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<Context> context,
11655a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<String> variable_name,
11656a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                 Handle<Object> new_value) {
11657a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
11658a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<String> next_name(scope_info->ContextLocalName(i));
116592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (String::Equals(variable_name, next_name)) {
11660a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      VariableMode mode;
11661a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      InitializationFlag init_flag;
11662a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      int context_index =
11663a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org          ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &init_flag);
11664a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      context->set(context_index, *new_value);
11665a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return true;
11666a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11667a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11668a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11669a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return false;
11670a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11671a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11672a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11673a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic bool SetLocalVariableValue(Isolate* isolate,
11674a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  JavaScriptFrame* frame,
11675a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  int inlined_jsframe_index,
11676a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<String> variable_name,
11677a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<Object> new_value) {
11678a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11679a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Optimized frames are not supported.
11680a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
11681a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11683169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Handle<JSFunction> function(frame->function());
11684a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
11685a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11686a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11687a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool default_result = false;
11688a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11689a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Parameters.
11690a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
116912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    HandleScope scope(isolate);
116922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
11693a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      frame->SetParameterValue(i, *new_value);
11694a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Argument might be shadowed in heap context, don't stop here.
11695a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      default_result = true;
11696a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11697a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11698a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11699a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Stack locals.
11700a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
117012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    HandleScope scope(isolate);
117022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
11703a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      frame->SetExpression(i, *new_value);
11704a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return true;
11705a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11706a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11707a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11708a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (scope_info->HasContext()) {
11709a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Context locals.
11710a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<Context> frame_context(Context::cast(frame->context()));
11711a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<Context> function_context(frame_context->declaration_context());
11712a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (SetContextLocalValue(
11713a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        isolate, scope_info, function_context, variable_name, new_value)) {
11714a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return true;
11715a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11716a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11717a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // Function context extension. These are variables introduced by eval.
11718a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (function_context->closure() == *function) {
11719a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (function_context->has_extension() &&
11720a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          !function_context->IsNativeContext()) {
11721a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11722a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11723528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        if (JSReceiver::HasProperty(ext, variable_name)) {
11724a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          // We don't expect this to do anything except replacing
11725a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          // property value.
11726e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org          Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
117278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                     NONE, SLOPPY).Assert();
11728a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          return true;
11729a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        }
11730a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
11731a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
11732a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11733a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11734a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return default_result;
11735a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11736a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11737a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11738eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// Create a plain JSObject which materializes the closure content for the
11739eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// context.
117408f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
117418f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Isolate* isolate,
117428f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Context> context) {
117436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  ASSERT(context->IsFunctionContext());
11744eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
117456a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  Handle<SharedFunctionInfo> shared(context->closure()->shared());
11746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
11747eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
117482efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Allocate and initialize a JSObject with all the content of this function
11749eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // closure.
11750ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSObject> closure_scope =
11751ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
11752eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11753eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Fill all context locals to the context extension.
11754d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (!ScopeInfo::CopyContextLocalsToScopeObject(
11755d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org          scope_info, context, closure_scope)) {
117568f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return MaybeHandle<JSObject>();
11757496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  }
11758eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11759eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Finally copy any properties from the function context extension. This will
11760eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // be variables introduced by eval.
11761eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (context->has_extension()) {
11762eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    Handle<JSObject> ext(JSObject::cast(context->extension()));
11763202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<FixedArray> keys;
11764202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
117659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate, keys,
117669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
11767394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
11768eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    for (int i = 0; i < keys->length(); i++) {
11769202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      HandleScope scope(isolate);
11770eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      // Names of variables introduced by eval are strings.
11771eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      ASSERT(keys->get(i)->IsString());
11772eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      Handle<String> key(String::cast(keys->get(i)));
11773202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Handle<Object> value;
11774202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
11775202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11776202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      RETURN_ON_EXCEPTION(
11777ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate,
11778202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          Runtime::SetObjectProperty(
11779202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org              isolate, closure_scope, key, value, NONE, SLOPPY),
117808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          JSObject);
11781eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
11782eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
11783eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11784eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  return closure_scope;
11785eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
11786eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
11787eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1178849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// This method copies structure of MaterializeClosure method above.
1178949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgstatic bool SetClosureVariableValue(Isolate* isolate,
1179049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                    Handle<Context> context,
1179149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                    Handle<String> variable_name,
1179249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                    Handle<Object> new_value) {
1179349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  ASSERT(context->IsFunctionContext());
1179449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1179549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  Handle<SharedFunctionInfo> shared(context->closure()->shared());
1179649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  Handle<ScopeInfo> scope_info(shared->scope_info());
1179749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1179849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Context locals to the context extension.
11799a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (SetContextLocalValue(
11800a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          isolate, scope_info, context, variable_name, new_value)) {
11801a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return true;
1180249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1180349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1180449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Properties from the function context extension. This will
1180549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // be variables introduced by eval.
1180649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  if (context->has_extension()) {
1180749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    Handle<JSObject> ext(JSObject::cast(context->extension()));
11808528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (JSReceiver::HasProperty(ext, variable_name)) {
1180949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      // We don't expect this to do anything except replacing property value.
11810e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
118118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                 NONE, SLOPPY).Assert();
1181249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      return true;
1181349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
1181449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1181549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1181649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return false;
1181749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
1181849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1181949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
118206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// Create a plain JSObject which materializes the scope for the specified
118216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org// catch context.
118228f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
118238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Isolate* isolate,
118248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Context> context) {
118256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  ASSERT(context->IsCatchContext());
118266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Handle<String> name(String::cast(context->extension()));
1182709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
1182809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                               isolate);
118296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Handle<JSObject> catch_scope =
118306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
118318f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  RETURN_ON_EXCEPTION(
118326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      isolate,
11833e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
11834486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                 NONE, SLOPPY),
118358f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      JSObject);
118366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  return catch_scope;
118376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
118386d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
118396d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
11840a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgstatic bool SetCatchVariableValue(Isolate* isolate,
11841a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<Context> context,
11842a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<String> variable_name,
11843a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                  Handle<Object> new_value) {
11844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(context->IsCatchContext());
11845a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<String> name(String::cast(context->extension()));
118462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (!String::Equals(name, variable_name)) {
11847a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
11848a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
11849a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  context->set(Context::THROWN_OBJECT_INDEX, *new_value);
11850a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return true;
11851a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11852a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11853a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
118544acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org// Create a plain JSObject which materializes the block scope for the specified
118554acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org// block context.
118568f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
118574acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Isolate* isolate,
118584acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    Handle<Context> context) {
118594acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  ASSERT(context->IsBlockContext());
11860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
118614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
118624acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Allocate and initialize a JSObject with all the arguments, stack locals
118634acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // heap locals and extension properties of the debugged function.
118644acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Handle<JSObject> block_scope =
118654acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
118664acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
118674acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  // Fill all context locals.
11868d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (!ScopeInfo::CopyContextLocalsToScopeObject(
11869d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org          scope_info, context, block_scope)) {
118708f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return MaybeHandle<JSObject>();
118714acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
118724acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
118734acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return block_scope;
118744acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org}
118754acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
118764acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
11877f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// Create a plain JSObject which materializes the module scope for the specified
11878f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// module context.
118798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
11880f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Isolate* isolate,
11881f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    Handle<Context> context) {
11882f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  ASSERT(context->IsModuleContext());
11883f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11884f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11885f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Allocate and initialize a JSObject with all the members of the debugged
11886f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // module.
11887f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<JSObject> module_scope =
11888f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
11889f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11890f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Fill all context locals.
11891d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (!ScopeInfo::CopyContextLocalsToScopeObject(
11892d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org          scope_info, context, module_scope)) {
118938f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return MaybeHandle<JSObject>();
11894f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
11895f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11896f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  return module_scope;
11897f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org}
11898f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
11899f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
119001044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// Iterate over the actual scopes visible from a stack frame or from a closure.
119011044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// The iteration proceeds from the innermost visible nested scope outwards.
119021044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// All scopes are backed by an actual context except the local scope,
119031044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org// which is inserted "artificially" in the context chain.
11904eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgclass ScopeIterator {
11905eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org public:
11906eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  enum ScopeType {
11907eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ScopeTypeGlobal = 0,
11908eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ScopeTypeLocal,
11909eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    ScopeTypeWith,
11910a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    ScopeTypeClosure,
119114acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    ScopeTypeCatch,
11912f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    ScopeTypeBlock,
11913f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    ScopeTypeModule
11914eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  };
11915eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1191684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ScopeIterator(Isolate* isolate,
1191784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org                JavaScriptFrame* frame,
11918fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                int inlined_jsframe_index,
11919fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                bool ignore_nested_scopes = false)
11920ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(isolate),
11921ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      frame_(frame),
11922659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      inlined_jsframe_index_(inlined_jsframe_index),
11923169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      function_(frame->function()),
11924eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      context_(Context::cast(frame->context())),
1192556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      nested_scope_chain_(4),
1192656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      failed_(false) {
119271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
119281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Catch the case when the debugger stops in an internal function.
119291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Handle<SharedFunctionInfo> shared_info(function_->shared());
119301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Handle<ScopeInfo> scope_info(shared_info->scope_info());
119311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (shared_info->script() == isolate->heap()->undefined_value()) {
119321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      while (context_->closure() == *function_) {
119331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        context_ = Handle<Context>(context_->previous(), isolate_);
119341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
119351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return;
119361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
119371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
119381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Get the debug info (create it if it does not exist).
119395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
119401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Return if ensuring debug info failed.
119411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return;
119421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
119431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
11944fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // Currently it takes too much time to find nested scopes due to script
11945fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // parsing. Sometimes we want to run the ScopeIterator as fast as possible
11946fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // (for example, while collecting async call stacks on every
11947fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // addEventListener call), even if we drop some nested scopes.
11948fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // Later we may optimize getting the nested scopes (cache the result?)
11949fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    // and include nested scopes into the "fast" iteration case as well.
11950fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    if (!ignore_nested_scopes) {
11951fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
11952fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
11953fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // Find the break point where execution has stopped.
11954fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      BreakLocationIterator break_location_iterator(debug_info,
11955fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                                    ALL_BREAK_LOCATIONS);
11956fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // pc points to the instruction after the current one, possibly a break
11957fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // location as well. So the "- 1" to exclude it from the search.
11958fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
11959fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
11960fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // Within the return sequence at the moment it is not possible to
119611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // get a source position which is consistent with the current scope chain.
119621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Thus all nested with, catch and block contexts are skipped and we only
119631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // provide the function scope.
11964fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      ignore_nested_scopes = break_location_iterator.IsExit();
11965fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    }
11966fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
11967fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    if (ignore_nested_scopes) {
119681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (scope_info->HasContext()) {
119691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        context_ = Handle<Context>(context_->declaration_context(), isolate_);
119701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      } else {
119711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        while (context_->closure() == *function_) {
119721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          context_ = Handle<Context>(context_->previous(), isolate_);
119731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
119741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
11975fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      if (scope_info->scope_type() == FUNCTION_SCOPE) {
11976dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        nested_scope_chain_.Add(scope_info);
11977dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      }
119781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else {
119791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Reparse the code and analyze the scopes.
119801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Handle<Script> script(Script::cast(shared_info->script()));
119811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Scope* scope = NULL;
119821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
119831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // Check whether we are in global, eval or function code.
119841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Handle<ScopeInfo> scope_info(shared_info->scope_info());
11985dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (scope_info->scope_type() != FUNCTION_SCOPE) {
119861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // Global or eval code.
119875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        CompilationInfoWithZone info(script);
11988dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        if (scope_info->scope_type() == GLOBAL_SCOPE) {
119891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          info.MarkAsGlobal();
119901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        } else {
11991dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org          ASSERT(scope_info->scope_type() == EVAL_SCOPE);
119921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          info.MarkAsEval();
11993355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org          info.SetContext(Handle<Context>(function_->context()));
119941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
11995e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
119961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          scope = info.function()->scope();
119971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
119985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        RetrieveScopeChain(scope, shared_info);
119991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      } else {
120001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // Function code
120015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        CompilationInfoWithZone info(shared_info);
12002e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
120031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          scope = info.function()->scope();
120041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
120055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        RetrieveScopeChain(scope, shared_info);
120061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
12007eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
12008eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12009eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
120101044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ScopeIterator(Isolate* isolate,
120111044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org                Handle<JSFunction> function)
120121044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    : isolate_(isolate),
120131044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      frame_(NULL),
120141044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      inlined_jsframe_index_(0),
120151044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      function_(function),
1201656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      context_(function->context()),
1201756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      failed_(false) {
120181044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    if (function->IsBuiltin()) {
120191044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org      context_ = Handle<Context>();
120201044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    }
120211044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
120221044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
12023eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // More scopes?
1202456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool Done() {
1202556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
1202656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    return context_.is_null();
1202756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
1202856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
1202956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool Failed() { return failed_; }
12030eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12031eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Move to the next scope.
12032eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void Next() {
1203356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
120341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    ScopeType scope_type = Type();
120351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (scope_type == ScopeTypeGlobal) {
120361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // The global scope is always the last in the chain.
1203746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(context_->IsNativeContext());
12038eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      context_ = Handle<Context>();
12039eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return;
12040eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
120411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (nested_scope_chain_.is_empty()) {
120421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      context_ = Handle<Context>(context_->previous(), isolate_);
120431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else {
120441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (nested_scope_chain_.last()->HasContext()) {
120451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        ASSERT(context_->previous() != NULL);
120461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        context_ = Handle<Context>(context_->previous(), isolate_);
120471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
120481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      nested_scope_chain_.RemoveLast();
12049eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
12050eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12051eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12052eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Return the type of the current scope.
1205334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  ScopeType Type() {
1205456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
120551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!nested_scope_chain_.is_empty()) {
120561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
12057dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      switch (scope_info->scope_type()) {
120581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case FUNCTION_SCOPE:
120591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(context_->IsFunctionContext() ||
120601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                 !scope_info->HasContext());
120611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeLocal;
12062f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        case MODULE_SCOPE:
12063f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org          ASSERT(context_->IsModuleContext());
12064f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org          return ScopeTypeModule;
120651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case GLOBAL_SCOPE:
1206646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          ASSERT(context_->IsNativeContext());
120671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeGlobal;
120681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case WITH_SCOPE:
120691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(context_->IsWithContext());
120701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeWith;
120711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case CATCH_SCOPE:
120721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(context_->IsCatchContext());
120731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeCatch;
120741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case BLOCK_SCOPE:
120751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          ASSERT(!scope_info->HasContext() ||
120761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                 context_->IsBlockContext());
120771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return ScopeTypeBlock;
120781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        case EVAL_SCOPE:
120791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          UNREACHABLE();
120801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
12081eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
1208246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (context_->IsNativeContext()) {
1208346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ASSERT(context_->global_object()->IsGlobalObject());
12084eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return ScopeTypeGlobal;
12085eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
120866d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (context_->IsFunctionContext()) {
12087eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return ScopeTypeClosure;
12088eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
120896d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (context_->IsCatchContext()) {
12090a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org      return ScopeTypeCatch;
12091a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    }
120924acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (context_->IsBlockContext()) {
120934acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      return ScopeTypeBlock;
120944acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
12095f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    if (context_->IsModuleContext()) {
12096f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      return ScopeTypeModule;
12097f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    }
120986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    ASSERT(context_->IsWithContext());
12099eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    return ScopeTypeWith;
12100eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12101eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12102eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Return the JavaScript object with the content of the current scope.
121038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  MaybeHandle<JSObject> ScopeObject() {
1210456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
12105eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    switch (Type()) {
12106eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeGlobal:
1210746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        return Handle<JSObject>(CurrentContext()->global_object());
12108eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeLocal:
12109eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        // Materialize the content of the local scope into a JSObject.
121101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        ASSERT(nested_scope_chain_.length() == 1);
12111659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
12112eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeWith:
12113eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        // Return the with object.
121146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
121156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeCatch:
121166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        return MaterializeCatchScope(isolate_, CurrentContext());
12117eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeClosure:
12118eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        // Materialize the content of the closure scope into a JSObject.
12119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return MaterializeClosure(isolate_, CurrentContext());
121204acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      case ScopeIterator::ScopeTypeBlock:
121214acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org        return MaterializeBlockScope(isolate_, CurrentContext());
12122f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      case ScopeIterator::ScopeTypeModule:
12123f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        return MaterializeModuleScope(isolate_, CurrentContext());
12124eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
12125eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    UNREACHABLE();
12126eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    return Handle<JSObject>();
12127eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12128eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1212949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  bool SetVariableValue(Handle<String> variable_name,
1213049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                        Handle<Object> new_value) {
1213149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    ASSERT(!failed_);
1213249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    switch (Type()) {
1213349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeGlobal:
1213449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1213549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeLocal:
12136a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
12137a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org            variable_name, new_value);
1213849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeWith:
1213949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1214049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeCatch:
12141a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        return SetCatchVariableValue(isolate_, CurrentContext(),
12142a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org            variable_name, new_value);
1214349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeClosure:
1214449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        return SetClosureVariableValue(isolate_, CurrentContext(),
1214549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org            variable_name, new_value);
1214649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeBlock:
1214749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        // TODO(2399): should we implement it?
1214849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1214949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org      case ScopeIterator::ScopeTypeModule:
1215049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        // TODO(2399): should we implement it?
1215149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        break;
1215249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    }
1215349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    return false;
1215449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1215549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
121561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<ScopeInfo> CurrentScopeInfo() {
1215756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
121581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (!nested_scope_chain_.is_empty()) {
121591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return nested_scope_chain_.last();
121601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else if (context_->IsBlockContext()) {
121611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
121621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else if (context_->IsFunctionContext()) {
121631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
121641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
121651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return Handle<ScopeInfo>::null();
121661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
121671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
12168eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Return the context for this scope. For the local context there might not
12169eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // be an actual context.
12170eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<Context> CurrentContext() {
1217156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
121721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (Type() == ScopeTypeGlobal ||
121731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        nested_scope_chain_.is_empty()) {
121741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return context_;
121751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else if (nested_scope_chain_.last()->HasContext()) {
121761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return context_;
121771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    } else {
12178eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      return Handle<Context>();
12179eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
12180eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12181eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12182eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG
12183eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Debug print of the content of the current scope.
12184eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void DebugPrint() {
1218556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    ASSERT(!failed_);
12186eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    switch (Type()) {
12187eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeGlobal:
12188eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("Global:\n");
12189eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        CurrentContext()->Print();
12190eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
12191eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12192eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      case ScopeIterator::ScopeTypeLocal: {
12193eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("Local:\n");
12194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        function_->shared()->scope_info()->Print();
12195eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        if (!CurrentContext().is_null()) {
12196eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          CurrentContext()->Print();
12197eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          if (CurrentContext()->has_extension()) {
1219809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org            Handle<Object> extension(CurrentContext()->extension(), isolate_);
12199eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org            if (extension->IsJSContextExtensionObject()) {
12200eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org              extension->Print();
12201eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org            }
12202eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          }
12203eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        }
12204eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
12205eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      }
12206eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
122076d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeWith:
12208eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("With:\n");
122096d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        CurrentContext()->extension()->Print();
12210eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
12211eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
122126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeCatch:
12213a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        PrintF("Catch:\n");
122146d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        CurrentContext()->extension()->Print();
122156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
12216a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org        break;
12217a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
122186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      case ScopeIterator::ScopeTypeClosure:
12219eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        PrintF("Closure:\n");
12220eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        CurrentContext()->Print();
12221eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        if (CurrentContext()->has_extension()) {
1222209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org          Handle<Object> extension(CurrentContext()->extension(), isolate_);
12223eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          if (extension->IsJSContextExtensionObject()) {
12224eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org            extension->Print();
12225eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org          }
12226eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        }
12227eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        break;
12228eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12229eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org      default:
12230eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org        UNREACHABLE();
12231eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    }
12232eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    PrintF("\n");
12233eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12234eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
12235eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12236eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org private:
12237ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
12238eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame_;
12239659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int inlined_jsframe_index_;
12240eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<JSFunction> function_;
12241eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  Handle<Context> context_;
122421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  List<Handle<ScopeInfo> > nested_scope_chain_;
1224356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool failed_;
12244eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
122455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void RetrieveScopeChain(Scope* scope,
122465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                          Handle<SharedFunctionInfo> shared_info) {
122475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (scope != NULL) {
122485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      int source_position = shared_info->code()->SourcePosition(frame_->pc());
122495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
122505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    } else {
122515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // A failed reparse indicates that the preparser has diverged from the
122525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // parser or that the preparse data given to the initial parse has been
122535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // faulty. We fail in debug mode but in release mode we only provide the
122545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // information we get from the context chain but nothing about
122555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      // completely stack allocated scopes or stack allocated locals.
1225656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      // Or it could be due to stack overflow.
1225756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      ASSERT(isolate_->has_pending_exception());
1225856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      failed_ = true;
122595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
122605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
122615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
12262eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
12263eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org};
12264eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12265eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12266a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetScopeCount) {
12267ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12268eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(args.length() == 2);
122698496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
122708496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12271eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12272f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12273eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12274eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Get the frame where the debugging is performed.
12275eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
1227674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate, id);
12277eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame = it.frame();
12278eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12279eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Count the visible scopes.
12280eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  int n = 0;
1228184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  for (ScopeIterator it(isolate, frame, 0);
1228284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       !it.Done();
1228384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       it.Next()) {
12284eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    n++;
12285eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12286eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12287eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  return Smi::FromInt(n);
12288eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12289eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12290eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
122911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Returns the list of step-in positions (text offset) in a function of the
122921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// stack frame in a range from the current debug break position to the end
122931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// of the corresponding statement.
12294a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetStepInPositions) {
122951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HandleScope scope(isolate);
122961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(args.length() == 2);
122978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
122988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
122991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
123001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
123011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
123021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Get the frame where the debugging is performed.
123031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
123041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  JavaScriptFrameIterator frame_it(isolate, id);
12305e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  RUNTIME_ASSERT(!frame_it.done());
12306e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org
123071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  JavaScriptFrame* frame = frame_it.frame();
123081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12309594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSFunction> fun =
12310594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Handle<JSFunction>(frame->function());
123111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<SharedFunctionInfo> shared =
12312594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Handle<SharedFunctionInfo>(fun->shared());
12313594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
12314594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
12315594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->undefined_value();
12316594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
12317594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
123181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
123191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
123201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int len = 0;
123211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<JSArray> array(isolate->factory()->NewJSArray(10));
123221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Find the break point where execution has stopped.
123231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  BreakLocationIterator break_location_iterator(debug_info,
123241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                ALL_BREAK_LOCATIONS);
123251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12326e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
123271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int current_statement_pos = break_location_iterator.statement_position();
123281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
123291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  while (!break_location_iterator.Done()) {
12330e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    bool accept;
12331594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (break_location_iterator.pc() > frame->pc()) {
12332e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      accept = true;
12333e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    } else {
12334e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
12335e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      // The break point is near our pc. Could be a step-in possibility,
12336e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      // that is currently taken by active debugger call.
12337e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      if (break_frame_id == StackFrame::NO_ID) {
12338e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        // We are not stepping.
12339e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        accept = false;
12340e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      } else {
12341e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
12342e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        // If our frame is a top frame and we are stepping, we can do step-in
12343e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        // at this place.
12344e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        accept = additional_frame_it.frame()->id() == id;
12345e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      }
12346e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    }
12347e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    if (accept) {
12348594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (break_location_iterator.IsStepInLocation(isolate)) {
12349594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        Smi* position_value = Smi::FromInt(break_location_iterator.position());
123509e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        RETURN_FAILURE_ON_EXCEPTION(
123519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org            isolate,
123529e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org            JSObject::SetElement(array, len,
123539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                 Handle<Object>(position_value, isolate),
123549e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                 NONE, SLOPPY));
12355594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        len++;
12356594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
123571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
123581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // Advance iterator.
123591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    break_location_iterator.Next();
123601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (current_statement_pos !=
123611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        break_location_iterator.statement_position()) {
123621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      break;
123631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
123641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
123651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return *array;
123661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
123671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
123681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12369eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgstatic const int kScopeDetailsTypeIndex = 0;
12370eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgstatic const int kScopeDetailsObjectIndex = 1;
12371eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgstatic const int kScopeDetailsSize = 2;
12372eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
123731044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
123748f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
123758f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Isolate* isolate,
123761044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    ScopeIterator* it) {
123771044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Calculate the size of the result.
123781044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  int details_size = kScopeDetailsSize;
123791044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
123801044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
123811044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Fill in scope details.
123821044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
123838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<JSObject> scope_object;
123848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
123858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, scope_object, it->ScopeObject(), JSObject);
123861044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  details->set(kScopeDetailsObjectIndex, *scope_object);
123871044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
12388ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return isolate->factory()->NewJSArrayWithElements(details);
123891044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org}
123901044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
12391e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
12392eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// Return an array with scope details
12393eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// args[0]: number: break id
12394eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// args[1]: number: frame index
1239584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org// args[2]: number: inlined frame index
1239684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org// args[3]: number: scope index
12397eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org//
12398eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// The array returned contains the following information:
12399eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// 0: Scope type
12400eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org// 1: Scope object
12401a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetScopeDetails) {
12402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1240384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ASSERT(args.length() == 4);
124048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
124058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12406eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12407f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12408659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1240984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12410eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12411eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Get the frame where the debugging is performed.
12412eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
1241374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator frame_it(isolate, id);
12414eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame = frame_it.frame();
12415eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12416eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Find the requested scope.
12417eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  int n = 0;
12418659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  ScopeIterator it(isolate, frame, inlined_jsframe_index);
12419eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  for (; !it.Done() && n < index; it.Next()) {
12420eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    n++;
12421eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12422eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  if (it.Done()) {
12423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
12424eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
124258f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<JSObject> details;
124268f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
124278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, details, MaterializeScopeDetails(isolate, &it));
12428ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return *details;
12429ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org}
12430ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
12431ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
12432ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// Return an array of scope details
12433ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// args[0]: number: break id
12434ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// args[1]: number: frame index
12435ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// args[2]: number: inlined frame index
12436fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// args[3]: boolean: ignore nested scopes
12437ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org//
12438ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// The array returned contains arrays with the following information:
12439ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// 0: Scope type
12440ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org// 1: Scope object
12441a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
12442ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HandleScope scope(isolate);
12443fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  ASSERT(args.length() == 3 || args.length() == 4);
124448496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
124458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12446ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
12447ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12448ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12449ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
12450fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  bool ignore_nested_scopes = false;
12451fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  if (args.length() == 4) {
12452fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
12453fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    ignore_nested_scopes = flag;
12454fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  }
12455fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
12456ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  // Get the frame where the debugging is performed.
12457ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  StackFrame::Id id = UnwrapFrameId(wrapped_id);
12458ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  JavaScriptFrameIterator frame_it(isolate, id);
12459ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  JavaScriptFrame* frame = frame_it.frame();
12460ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
12461ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  List<Handle<JSObject> > result(4);
12462fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
12463ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  for (; !it.Done(); it.Next()) {
124648f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<JSObject> details;
124658f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
124668f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        isolate, details, MaterializeScopeDetails(isolate, &it));
12467ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    result.Add(details);
12468ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
12469ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
12470ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
12471ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  for (int i = 0; i < result.length(); ++i) {
12472ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    array->set(i, *result[i]);
12473ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
12474ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return *isolate->factory()->NewJSArrayWithElements(array);
124751044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org}
12476eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12477eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12478a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
124791044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  HandleScope scope(isolate);
124801044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(args.length() == 1);
12481eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
124821044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Check arguments.
124831044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
124841044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
124851044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Count the visible scopes.
124861044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  int n = 0;
124871044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
124881044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    n++;
124891044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
124901044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
124911044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  return Smi::FromInt(n);
124921044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org}
124931044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
124941044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
12495a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
124961044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  HandleScope scope(isolate);
124971044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ASSERT(args.length() == 2);
124981044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
124991044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Check arguments.
125001044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
125011044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
125021044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
125031044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  // Find the requested scope.
125041044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  int n = 0;
125051044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  ScopeIterator it(isolate, fun);
125061044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  for (; !it.Done() && n < index; it.Next()) {
125071044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    n++;
125081044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
125091044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  if (it.Done()) {
125101044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    return isolate->heap()->undefined_value();
125111044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  }
125121044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org
125138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<JSObject> details;
125148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
125158f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, details, MaterializeScopeDetails(isolate, &it));
12516ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return *details;
12517eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12518eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12519eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
1252049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgstatic bool SetScopeVariableValue(ScopeIterator* it, int index,
1252149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                  Handle<String> variable_name,
1252249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                  Handle<Object> new_value) {
1252349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  for (int n = 0; !it->Done() && n < index; it->Next()) {
1252449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    n++;
1252549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1252649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  if (it->Done()) {
1252749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    return false;
1252849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1252949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return it->SetVariableValue(variable_name, new_value);
1253049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
1253149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1253249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1253349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// Change variable value in closure or local scope
1253449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[0]: number or JsFunction: break id or function
1253549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[1]: number: frame index (when arg[0] is break id)
1253649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[2]: number: inlined frame index (when arg[0] is break id)
1253749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[3]: number: scope index
1253849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[4]: string: variable name
1253949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// args[5]: object: new value
1254049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org//
1254149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// Return true if success and false otherwise
12542a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
1254349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  HandleScope scope(isolate);
1254449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  ASSERT(args.length() == 6);
1254549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1254649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  // Check arguments.
1254749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
1254849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
125498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
1255049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1255149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  bool res;
1255249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  if (args[0]->IsNumber()) {
125538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
125548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
125558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
1255649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1255749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1255849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1255949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    // Get the frame where the debugging is performed.
1256049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    StackFrame::Id id = UnwrapFrameId(wrapped_id);
1256149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    JavaScriptFrameIterator frame_it(isolate, id);
1256249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    JavaScriptFrame* frame = frame_it.frame();
1256349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1256449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    ScopeIterator it(isolate, frame, inlined_jsframe_index);
1256549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    res = SetScopeVariableValue(&it, index, variable_name, new_value);
1256649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  } else {
1256749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1256849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    ScopeIterator it(isolate, fun);
1256949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    res = SetScopeVariableValue(&it, index, variable_name, new_value);
1257049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
1257149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1257249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return isolate->heap()->ToBoolean(res);
1257349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
1257449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
1257549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
12576a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
12577ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12578eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  ASSERT(args.length() == 0);
12579eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12580eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG
12581eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Print the scopes for the top frame.
12582c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  StackFrameLocator locator(isolate);
12583eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
1258484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  for (ScopeIterator it(isolate, frame, 0);
1258584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       !it.Done();
1258684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org       it.Next()) {
12587eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org    it.DebugPrint();
12588eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  }
12589eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
12590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
12591eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12592eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12593eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12594a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetThreadCount) {
12595ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12596bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(args.length() == 1);
125978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
125988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12599bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12600bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Count all archived V8 threads.
12601bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int n = 0;
12602ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  for (ThreadState* thread =
12603ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->thread_manager()->FirstThreadStateInUse();
12604bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org       thread != NULL;
12605bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org       thread = thread->Next()) {
12606bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    n++;
12607bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
12608bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12609bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Total number of threads is current thread and archived threads.
12610bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  return Smi::FromInt(n + 1);
12611bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
12612bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12613bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12614bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kThreadDetailsCurrentThreadIndex = 0;
12615bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kThreadDetailsThreadIdIndex = 1;
12616bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kThreadDetailsSize = 2;
12617bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12618bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Return an array with thread details
12619bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// args[0]: number: break id
12620bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// args[1]: number: thread index
12621bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//
12622bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// The array returned contains the following information:
12623bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// 0: Is current thread?
12624bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// 1: Thread id
12625a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetThreadDetails) {
12626ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12627bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(args.length() == 2);
126288496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
126298496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12630bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12631bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12632bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12633bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Allocate array for result.
12634ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> details =
12635ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFixedArray(kThreadDetailsSize);
12636bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12637bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Thread index 0 is current thread.
12638bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (index == 0) {
12639bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Fill the details.
12640ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    details->set(kThreadDetailsCurrentThreadIndex,
12641ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                 isolate->heap()->true_value());
12642bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    details->set(kThreadDetailsThreadIdIndex,
12643a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                 Smi::FromInt(ThreadId::Current().ToInteger()));
12644bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else {
12645bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Find the thread with the requested index.
12646bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    int n = 1;
12647ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ThreadState* thread =
12648ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->thread_manager()->FirstThreadStateInUse();
12649bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    while (index != n && thread != NULL) {
12650bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      thread = thread->Next();
12651bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      n++;
12652bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
12653bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (thread == NULL) {
12654ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return isolate->heap()->undefined_value();
12655bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
12656bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12657bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    // Fill the details.
12658ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    details->set(kThreadDetailsCurrentThreadIndex,
12659ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                 isolate->heap()->false_value());
12660a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org    details->set(kThreadDetailsThreadIdIndex,
12661a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org                 Smi::FromInt(thread->id().ToInteger()));
12662bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
12663bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12664bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Convert to JS array and return.
12665ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(details);
12666bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
12667bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12668bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
12669e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org// Sets the disable break state
12670e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org// args[0]: disable break state
12671a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetDisableBreak) {
12672ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12673e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  ASSERT(args.length() == 1);
12674f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
12675ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->set_disable_break(disable_break);
12676ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return  isolate->heap()->undefined_value();
12677e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org}
12678e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
12679e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
1268093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgstatic bool IsPositionAlignmentCodeCorrect(int alignment) {
1268193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
1268293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org}
1268393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1268493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
12685a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetBreakLocations) {
12686ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1268793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  ASSERT(args.length() == 2);
1268843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12689f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1269093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
1269193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1269293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
1269393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    return isolate->ThrowIllegalOperation();
1269493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
1269593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  BreakPositionAlignment alignment =
1269693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      static_cast<BreakPositionAlignment>(statement_aligned_code);
1269793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
126985aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  Handle<SharedFunctionInfo> shared(fun->shared());
1269943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the number of break points
1270093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  Handle<Object> break_locations =
1270193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      Debug::GetSourceBreakLocations(shared, alignment);
12702ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
1270343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return array as JS array
12704ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *isolate->factory()->NewJSArrayWithElements(
1270543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<FixedArray>::cast(break_locations));
1270643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1270743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1270843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Set a break point in a function.
127105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// args[0]: function
127115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// args[1]: number: break source position (within the function source)
127125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// args[2]: number: break point object
12713a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
127145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HandleScope scope(isolate);
127155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  ASSERT(args.length() == 3);
127165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
127175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12718a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
12719a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org                 source_position <= function->shared()->end_position());
127208496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
127215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
127225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Set break point.
12723a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org  RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
12724a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org      function, break_point_object_arg, &source_position));
127255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
127265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return Smi::FromInt(source_position);
127275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
127285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
127295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
127305ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// Changes the state of a break point in a script and returns source position
127315ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// where break point was set. NOTE: Regarding performance see the NOTE for
127325ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org// GetScriptFromScriptData.
1273343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: script to set break point in
1273443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: number: break source position (within the script source)
1273593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org// args[2]: number, breakpoint position alignment
1273693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org// args[3]: number: break point object
12737a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
12738ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1273993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  ASSERT(args.length() == 4);
12740f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
1274143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
1274243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(source_position >= 0);
1274393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
127448496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
1274593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1274693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
1274793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    return isolate->ThrowIllegalOperation();
1274893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
1274993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  BreakPositionAlignment alignment =
1275093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      static_cast<BreakPositionAlignment>(statement_aligned_code);
1275143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1275243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the script from the script wrapper.
1275343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(wrapper->value()->IsScript());
1275443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Script> script(Script::cast(wrapper->value()));
1275543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Set break point.
127575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
1275893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org                                                &source_position,
1275993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org                                                alignment)) {
127604954674151afa960af66efb4831df06bde727333yangguo@chromium.org    return isolate->heap()->undefined_value();
1276143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
127625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
127635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return Smi::FromInt(source_position);
1276443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1276543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1276643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1276743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clear a break point
1276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: number: break point object
12769a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
12770ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1277143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
127728496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
1277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear break point.
12775ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ClearBreakPoint(break_point_object_arg);
1277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12777ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1277843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1277943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1278043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12781c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// Change the state of break on exceptions.
12782c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
12783c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// args[1]: Boolean indicating on/off.
12784a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
12785ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1278643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
127878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12788f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
1278943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12790c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // If the number doesn't match an enum value, the ChangeBreakOnException
12791c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // function will default to affecting caught exceptions.
127928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12793c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // Update break point state.
12794ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ChangeBreakOnException(type, enable);
12795ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1279643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1279743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1279843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12799c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// Returns the state of break on exceptions
12800c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org// args[0]: boolean indicating uncaught exceptions
12801a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsBreakOnException) {
12802ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12803c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  ASSERT(args.length() == 1);
128048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12805c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
128068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12807ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool result = isolate->debug()->IsBreakOnException(type);
12808c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  return Smi::FromInt(result);
12809c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org}
12810c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
12811c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
1281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Prepare for stepping
1281343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: break id for checking execution state
1281443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: step action from the enumeration StepAction
12815a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// args[2]: number of times to perform the step, for step out it is the number
12816a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org//          of frames to step down.
12817a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_PrepareStep) {
12818ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
12819639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  ASSERT(args.length() == 4);
128208496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
128218496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
128228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
1282343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
128244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
1282543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1282643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12827639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
12828639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
12829639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  StackFrame::Id frame_id;
12830639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (wrapped_frame_id == 0) {
12831639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    frame_id = StackFrame::NO_ID;
12832639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  } else {
12833639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    frame_id = UnwrapFrameId(wrapped_frame_id);
12834639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
12835639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
1283643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the step action and check validity.
1283743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
1283843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (step_action != StepIn &&
1283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepNext &&
1284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepOut &&
1284143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepInMin &&
1284243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      step_action != StepMin) {
128434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
1284443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1284543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1284663ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
1284763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org      step_action != StepMin && step_action != StepOut) {
12848639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    return isolate->ThrowIllegalOperation();
12849639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
12850639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
1285143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of steps.
1285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int step_count = NumberToInt32(args[2]);
1285343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (step_count < 1) {
128544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return isolate->Throw(isolate->heap()->illegal_argument_string());
1285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1285643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12857a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Clear all current stepping setup.
12858ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ClearStepping();
12859a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1286043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Prepare step.
12861ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
12862639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                step_count,
12863639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                frame_id);
12864ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1286543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1286643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1286743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1286843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clear all stepping set by PrepareStep.
12869a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ClearStepping) {
12870ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1287131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
12872ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->debug()->ClearStepping();
12873ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1287443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1287543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1287643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1287743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper function to find or create the arguments object for
1287843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Runtime_DebugEvaluate.
128798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
12880ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Isolate* isolate,
12881ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSObject> target,
12882ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<JSFunction> function) {
12883ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Do not materialize the arguments object for eval or top-level code.
12884ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Skip if "arguments" is already taken.
12885ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!function->shared()->is_function() ||
12886fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSReceiver::HasOwnProperty(
12887fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org          target, isolate->factory()->arguments_string())) {
12888ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return target;
1288943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1289043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12891ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // FunctionGetArguments can't throw an exception.
12892ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSObject> arguments = Handle<JSObject>::cast(
12893ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Accessors::FunctionGetArguments(function));
128948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<String> arguments_str = isolate->factory()->arguments_string();
128958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  RETURN_ON_EXCEPTION(
128968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate,
128978f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      Runtime::SetObjectProperty(
128988f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          isolate, target, arguments_str, arguments, ::NONE, SLOPPY),
128998f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      JSObject);
12900ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return target;
1290143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1290243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1290343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12904c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org// Compile and evaluate source for the given context.
129058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgstatic MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
129068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                         Handle<Context> context,
129078496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                         Handle<Object> context_extension,
129088496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                         Handle<Object> receiver,
129098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                         Handle<String> source) {
12910c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  if (context_extension->IsJSObject()) {
12911c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
12912c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    Handle<JSFunction> closure(context->closure(), isolate);
12913c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    context = isolate->factory()->NewWithContext(closure, context, extension);
12914c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  }
12915c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
129168496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<JSFunction> eval_fun;
129178496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
129188496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, eval_fun,
129194954674151afa960af66efb4831df06bde727333yangguo@chromium.org      Compiler::GetFunctionFromEval(source,
129204954674151afa960af66efb4831df06bde727333yangguo@chromium.org                                    context,
12921486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                    SLOPPY,
129224954674151afa960af66efb4831df06bde727333yangguo@chromium.org                                    NO_PARSE_RESTRICTION,
129238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                    RelocInfo::kNoPosition),
129248496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Object);
129254954674151afa960af66efb4831df06bde727333yangguo@chromium.org
129262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
129278496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
129282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
129298496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Execution::Call(isolate, eval_fun, receiver, 0, NULL),
129308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Object);
12931c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12932c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  // Skip the global proxy as it has no properties and always delegates to the
12933c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  // real global object.
12934c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  if (result->IsJSGlobalProxy()) {
12935c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
12936c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  }
12937c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
12938c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  // Clear the oneshot breakpoints so that the debugger does not step further.
12939c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  isolate->debug()->ClearStepping();
129408496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return result;
12941c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org}
12942ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
12943ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1294443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Evaluate a piece of JavaScript in the context of a stack frame for
12945ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// debugging.  Things that need special attention are:
12946ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// - Parameters and stack-allocated locals need to be materialized.  Altered
12947ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org//   values need to be written back to the stack afterwards.
12948ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// - The arguments object needs to materialized.
12949a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugEvaluate) {
12950ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1295143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1295243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the execution state and decode arguments frame and source to be
1295343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // evaluated.
1295484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  ASSERT(args.length() == 6);
129558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
129568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
129578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
12958f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12959659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12960f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
12961f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
129628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
12963bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
12964bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  // Handle the processing of break.
129658d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  DisableBreak disable_break_scope(isolate->debug(), disable_break);
1296643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1296743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the frame where the debugging is performed.
1296843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  StackFrame::Id id = UnwrapFrameId(wrapped_id);
1296974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  JavaScriptFrameIterator it(isolate, id);
1297043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JavaScriptFrame* frame = it.frame();
12971659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
12972659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
1297343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1297443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the saved contexts chain to find the active context for the
1297543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // selected frame.
12976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SaveContext* save = FindSavedContextForFrame(isolate, frame);
12977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
12978ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SaveContext savex(isolate);
12979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->set_context(*(save->context()));
1298043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12981ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Evaluate on the context of the frame.
12982ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Context> context(Context::cast(frame->context()));
12983ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(!context.is_null());
1298443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12985ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Materialize stack locals and the arguments object.
12986ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<JSObject> materialized =
12987ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate->factory()->NewJSObject(isolate->object_function());
1298843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129898f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
129908f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, materialized,
129918f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      MaterializeStackLocalsWithFrameInspector(
129928f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          isolate, materialized, function, &frame_inspector));
12993ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
129948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
129958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate, materialized,
129968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      MaterializeArgumentsObject(isolate, materialized, function));
12997ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
12998ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Add the materialized object in a with-scope to shadow the stack locals.
12999ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  context = isolate->factory()->NewWithContext(function, context, materialized);
1300043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13001ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> receiver(frame->receiver(), isolate);
130028496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Object> result;
130038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
130048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result,
130058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      DebugEvaluate(isolate, context, context_extension, receiver, source));
130061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13007ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Write back potential changes to materialized stack locals to the stack.
13008ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  UpdateStackLocalsFromMaterializedObject(
13009ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      isolate, materialized, function, frame, inlined_jsframe_index);
130101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
13011ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return *result;
1301243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1301343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1301443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13015a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
13016ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1301743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1301843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the execution state and decode arguments frame and source to be
1301943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // evaluated.
130205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(args.length() == 4);
130218496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
130228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
130238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
13024f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13025f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
130268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
13027bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund
13028bd3ec4e5037180e591d597bc7a8c92200798c3dbkasper.lund  // Handle the processing of break.
130298d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  DisableBreak disable_break_scope(isolate->debug(), disable_break);
1303043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1303143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Enter the top context from before the debugger was invoked.
13032ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SaveContext save(isolate);
1303343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  SaveContext* top = &save;
13034ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
1303543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    top = top->prev();
1303643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1303743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (top != NULL) {
13038ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->set_context(*top->context());
1303943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1304043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1304146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Get the native context now set to the top context from before the
1304243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // debugger was invoked.
1304346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Context> context = isolate->native_context();
1304446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<Object> receiver = isolate->global_object();
130458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Object> result;
130468496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
130478496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result,
130488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      DebugEvaluate(isolate, context, context_extension, receiver, source));
130498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *result;
1305043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1305143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1305243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13053a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
13054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1305531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
1305643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1305743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the script objects.
13058ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
1305943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1306043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert the script objects to proper JS objects.
1306171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  for (int i = 0; i < instances->length(); i++) {
130627c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
130637c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // Get the script wrapper in a local handle before calling GetScriptWrapper,
130647c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // because using
130657c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    //   instances->set(i, *GetScriptWrapper(script))
130667c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
130672efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // already have dereferenced the instances handle.
130689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<JSObject> wrapper = Script::GetWrapper(script);
130697c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    instances->set(i, *wrapper);
1307043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1307143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1307243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return result as a JS array.
13073ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSObject> result =
13074ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewJSObject(isolate->array_function());
13075fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
1307643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
1307743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1307843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1307943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1308043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper function used by Runtime_DebugReferencedBy below.
13081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int DebugReferencedBy(HeapIterator* iterator,
13082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             JSObject* target,
1308343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             Object* instance_filter, int max_references,
1308443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             FixedArray* instances, int instances_size,
1308543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             JSFunction* arguments_function) {
130868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Isolate* isolate = target->GetIsolate();
1308779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1308879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1308943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate the heap.
1309143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
1309243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSObject* last = NULL;
13093b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  HeapObject* heap_obj = NULL;
13094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (((heap_obj = iterator->next()) != NULL) &&
1309543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         (max_references == 0 || count < max_references)) {
1309643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Only look at all JSObjects.
1309743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (heap_obj->IsJSObject()) {
1309843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Skip context extension objects and argument arrays as these are
1309943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // checked in the context of functions using them.
1310043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      JSObject* obj = JSObject::cast(heap_obj);
13101245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      if (obj->IsJSContextExtensionObject() ||
1310243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          obj->map()->constructor() == arguments_function) {
1310343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        continue;
1310443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1310543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1310643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Check if the JS object has a reference to the object looked for.
1310743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (obj->ReferencesObject(target)) {
1310843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Check instance filter if supplied. This is normally used to avoid
1310943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // references from mirror objects (see Runtime_IsInPrototypeChain).
1311043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (!instance_filter->IsUndefined()) {
1311143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          Object* V = obj;
1311243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          while (true) {
131138432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            Object* prototype = V->GetPrototype(isolate);
1311443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (prototype->IsNull()) {
1311543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              break;
1311643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            }
1311743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (instance_filter == prototype) {
1311843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              obj = NULL;  // Don't add this object.
1311943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              break;
1312043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            }
1312143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            V = prototype;
1312243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
1312343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1312443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1312543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (obj != NULL) {
1312643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          // Valid reference found add to instance array if supplied an update
1312743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          // count.
1312843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          if (instances != NULL && count < instances_size) {
1312943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            instances->set(count, obj);
1313043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
1313143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          last = obj;
1313243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          count++;
1313343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1313443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1313543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1313643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1313743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1313843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check for circular reference only. This can happen when the object is only
1313943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // referenced from mirrors and has a circular reference in which case the
1314043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // object is not really alive and would have been garbage collected if not
1314143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // referenced from the mirror.
1314243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (count == 1 && last == target) {
1314343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    count = 0;
1314443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1314543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1314643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the number of referencing objects found.
1314743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return count;
1314843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1314943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1315043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1315143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Scan the heap for objects with direct references to an object
1315243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: the object to find references to
1315343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: constructor function for instances to exclude (Mirror)
1315443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[2]: the the maximum number of objects to return
13155a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
131567010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  HandleScope scope(isolate);
1315743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 3);
1315843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1315943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check parameters.
131607010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
131618496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
1316243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(instance_filter->IsUndefined() ||
1316343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                 instance_filter->IsJSObject());
1316443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
1316543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(max_references >= 0);
1316643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1316843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the constructor function for context extension and arguments array.
131697010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSObject> arguments_boilerplate(
131707010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      isolate->context()->native_context()->sloppy_arguments_boilerplate());
131717010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSFunction> arguments_function(
131727010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      JSFunction::cast(arguments_boilerplate->map()->constructor()));
1317343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1317443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of referencing objects.
1317543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count;
13176fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // First perform a full GC in order to avoid dead objects and to make the heap
13177fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // iterable.
13178fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  Heap* heap = isolate->heap();
13179fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13180fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  {
13181fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    HeapIterator heap_iterator(heap);
13182fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    count = DebugReferencedBy(&heap_iterator,
13183fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                              *target, *instance_filter, max_references,
13184fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                              NULL, 0, *arguments_function);
13185fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
1318643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1318743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate an array to hold the result.
131887010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
1318943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1319043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the referencing objects.
13191fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  {
13192fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    HeapIterator heap_iterator(heap);
13193fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    count = DebugReferencedBy(&heap_iterator,
13194fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                              *target, *instance_filter, max_references,
13195fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                              *instances, count, *arguments_function);
13196fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
1319743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1319843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return result as JS array.
131997010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSFunction> constructor(
1320046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      isolate->context()->native_context()->array_function());
132017010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org
132027010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
13203fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
132047010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  return *result;
1320543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1320643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1320743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1320843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Helper function used by Runtime_DebugConstructedBy below.
13209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int DebugConstructedBy(HeapIterator* iterator,
13210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              JSFunction* constructor,
13211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              int max_references,
13212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              FixedArray* instances,
13213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                              int instances_size) {
1321479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1321543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1321643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Iterate the heap.
1321743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
13218b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  HeapObject* heap_obj = NULL;
13219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (((heap_obj = iterator->next()) != NULL) &&
1322043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen         (max_references == 0 || count < max_references)) {
1322143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Only look at all JSObjects.
1322243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (heap_obj->IsJSObject()) {
1322343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      JSObject* obj = JSObject::cast(heap_obj);
1322443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (obj->map()->constructor() == constructor) {
1322543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // Valid reference found add to instance array if supplied an update
1322643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // count.
1322743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (instances != NULL && count < instances_size) {
1322843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          instances->set(count, obj);
1322943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1323043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        count++;
1323143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1323243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1323343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1323443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1323543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the number of referencing objects found.
1323643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return count;
1323743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1323843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1323943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1324043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Scan the heap for objects constructed by a specific function.
1324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: the constructor to find instances of
1324243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[1]: the the maximum number of objects to return
13243a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
132447010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  HandleScope scope(isolate);
1324543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 2);
1324643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1324743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1324843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check parameters.
132497010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
1325043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
1325143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_ASSERT(max_references >= 0);
1325243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1325343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the number of referencing objects.
1325443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count;
13255fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // First perform a full GC in order to avoid dead objects and to make the heap
13256fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  // iterable.
13257fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  Heap* heap = isolate->heap();
13258fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13259fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  {
13260fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    HeapIterator heap_iterator(heap);
13261fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    count = DebugConstructedBy(&heap_iterator,
13262fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               *constructor,
13263fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               max_references,
13264fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               NULL,
13265fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               0);
13266fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
1326743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1326843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate an array to hold the result.
132697010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
1327043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the referencing objects.
13272fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  {
13273fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    HeapIterator heap_iterator2(heap);
13274fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    count = DebugConstructedBy(&heap_iterator2,
13275fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               *constructor,
13276fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               max_references,
13277fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               *instances,
13278fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                               count);
13279fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
1328043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1328143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return result as JS array.
132827010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSFunction> array_function(
132837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      isolate->context()->native_context()->array_function());
132847010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
13285fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
132867010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  return *result;
1328743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1328843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1328943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13290ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Find the effective prototype object as returned by __proto__.
13291ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// args[0]: the object to find the prototype for.
13292a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
13293e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HandleScope shs(isolate);
1329443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
13295e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
13296e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
1329743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1329843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1329943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133002c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org// Patches script source (should be called upon BeforeCompile event).
13301a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
133022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  HandleScope scope(isolate);
133032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  ASSERT(args.length() == 2);
133042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
133052c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
1330646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
133072c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
133082c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  RUNTIME_ASSERT(script_wrapper->value()->IsScript());
133092c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  Handle<Script> script(Script::cast(script_wrapper->value()));
133102c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
13311d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  int compilation_state = script->compilation_state();
133122c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
133132c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  script->set_source(*source);
133142c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
133152c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  return isolate->heap()->undefined_value();
133162c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
133172c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
133182c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
13319a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SystemBreak) {
1332079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
1332131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  ASSERT(args.length() == 0);
133229259716434187c932704601f700375e53d865de8rossberg@chromium.org  OS::DebugBreak();
13323ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1332443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1332543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1332643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13327a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
13328ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
133296e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org#ifdef DEBUG
1333065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  ASSERT(args.length() == 1);
1333165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  // Get the function and make sure it is compiled.
13332f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
133334954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13334a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    return isolate->heap()->exception();
1333565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
1333665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  func->code()->PrintLn();
1333718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif  // DEBUG
13338ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1333918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}
1334018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
1334118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
13342a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
13343ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
133446e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org#ifdef DEBUG
1334518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  ASSERT(args.length() == 1);
1334618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Get the function and make sure it is compiled.
13347f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
133484954674151afa960af66efb4831df06bde727333yangguo@chromium.org  if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13349a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    return isolate->heap()->exception();
1335018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  }
13351400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  func->shared()->construct_stub()->PrintLn();
1335265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif  // DEBUG
13353ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
1335465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org}
133559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
133569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13357a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
1335879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
133599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  ASSERT(args.length() == 1);
133609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13361f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunction, f, 0);
133629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  return f->shared()->inferred_name();
133639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}
13364ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
13365ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int FindSharedFunctionInfosForScript(HeapIterator* iterator,
13367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                            Script* script,
13368ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                            FixedArray* buffer) {
1336979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
13370ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int counter = 0;
13371ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int buffer_size = buffer->length();
13372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* obj = iterator->next();
13373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       obj != NULL;
13374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       obj = iterator->next()) {
13375ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    ASSERT(obj != NULL);
13376ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (!obj->IsSharedFunctionInfo()) {
13377ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      continue;
13378ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
13379ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
13380ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (shared->script() != script) {
13381ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      continue;
13382ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
13383ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (counter < buffer_size) {
13384ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      buffer->set(counter, shared);
13385ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
13386ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    counter++;
13387ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
13388ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return counter;
13389ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13390ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13391e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13392ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For a script finds all SharedFunctionInfo's in the heap that points
13393ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// to this script. Returns JSArray of SharedFunctionInfo wrapped
13394ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// in OpaqueReferences.
13395a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
133966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13397d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13398ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 1);
13399f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSValue, script_value, 0);
13400ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13401de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  RUNTIME_ASSERT(script_value->value()->IsScript());
13402ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
13403ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13404ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  const int kBufferSize = 32;
13405ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13406ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<FixedArray> array;
13407ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  array = isolate->factory()->NewFixedArray(kBufferSize);
13408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int number;
134097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = isolate->heap();
13410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
134117c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    HeapIterator heap_iterator(heap);
13412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Script* scr = *script;
13413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FixedArray* arr = *array;
13414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
13416ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (number > kBufferSize) {
13417ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    array = isolate->factory()->NewFixedArray(number);
134187c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    HeapIterator heap_iterator(heap);
13419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Script* scr = *script;
13420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FixedArray* arr = *array;
13421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13422ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
13423ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13424ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
13425ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  result->set_length(Smi::FromInt(number));
13426ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13427ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  LiveEdit::WrapSharedFunctionInfos(result);
13428ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13429ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return *result;
13430ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13431ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13432e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13433ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For a script calculates compilation information about all its functions.
13434ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// The script source is explicitly specified by the second argument.
13435ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// The source of the actual script is not used, however it is important that
13436ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// all generated code keeps references to this particular instance of script.
13437ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Returns a JSArray of compilation infos. The array is ordered so that
13438ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// each function with all its descendant is always stored in a continues range
13439ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// with the function itself going first. The root function is a script function.
13440a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
134416e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13442d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13443ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13444f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSValue, script, 0);
13445f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13446de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
13447de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  RUNTIME_ASSERT(script->value()->IsScript());
13448ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
13449ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
134509e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<JSArray> result;
134519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
134529e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
134539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return *result;
13454ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13455ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13456e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
134574111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// Changes the source of the script to a new_source.
134584111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// If old_script_name is provided (i.e. is a String), also creates a copy of
134594111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// the script with its original source and sends notification to debugger.
13460a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
134616e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13462d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13463ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 3);
13464f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
13465f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
134668496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
13467ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13468f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  RUNTIME_ASSERT(original_script_value->value()->IsScript());
13469f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Handle<Script> original_script(Script::cast(original_script_value->value()));
13470ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
134719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> old_script = LiveEdit::ChangeScriptSource(
134729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      original_script,  new_source,  old_script_name);
13473ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
134744111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (old_script->IsScript()) {
134759e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Script> script_handle = Handle<Script>::cast(old_script);
134769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return *Script::GetWrapper(script_handle);
134774111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  } else {
13478ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->null_value();
134794111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
13480ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13481ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13483a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
134846e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13485d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(args.length() == 1);
13487f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
134889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
134899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org
134909e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  LiveEdit::FunctionSourceUpdated(shared_info);
134919e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return isolate->heap()->undefined_value();
13492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
13493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13495ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Replaces code of SharedFunctionInfo with a new one.
13496a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
134976e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13498d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13499ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13500f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
13501f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
135029e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13503ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
135049e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
135059e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return isolate->heap()->undefined_value();
13506ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13507ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13508e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13509ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Connects SharedFunctionInfo to another script.
13510a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
135116e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13512d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13513ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
135148496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
135158496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
135164111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
135174111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (function_object->IsJSValue()) {
135184111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
135194111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    if (script_object->IsJSValue()) {
13520f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
13521f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      Script* script = Script::cast(JSValue::cast(*script_object)->value());
13522ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      script_object = Handle<Object>(script, isolate);
135234111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    }
13524a7cc028b1ce5d5b762b630529fa1956d89f76541machenbach@chromium.org    RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
135254111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    LiveEdit::SetFunctionScript(function_wrapper, script_object);
135264111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  } else {
135274111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    // Just ignore this. We may not have a SharedFunctionInfo for some functions
135284111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    // and we check it in this function.
135294111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
135304111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
13531ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
135324111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
13533ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
135344111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
135354111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// In a code of a parent function replaces original function as embedded object
135364111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// with a substitution one.
13537a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
135386e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13539d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
135404111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  ASSERT(args.length() == 3);
135414111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
13542f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
13543f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
13544f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
13545f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
13546f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
13547f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
135484111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
135499e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  LiveEdit::ReplaceRefToNestedFunction(
135509e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      parent_wrapper, orig_wrapper, subst_wrapper);
13551ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
13552ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13553ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
135544111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
13555ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Updates positions of a shared function info (first parameter) according
13556ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// to script source change. Text change is described in second parameter as
13557ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// array of groups of 3 numbers:
13558ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// (change_begin, change_end, change_end_new_position).
13559ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Each group describes a change in text; groups are sorted by change_begin.
13560a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
135616e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13562d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13563ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ASSERT(args.length() == 2);
13564f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13565f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
135669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
13567ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
135689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
135699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return isolate->heap()->undefined_value();
13570ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13571ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13572ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13573ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// For array of SharedFunctionInfo's (each wrapped in JSValue)
13574ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// checks that none of them have activations on stacks (of any thread).
13575ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// Returns array of the same length with corresponding results of
13576ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// LiveEdit::FunctionPatchabilityStatus type.
13577a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
135786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13579d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13580357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  ASSERT(args.length() == 2);
13581f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13582f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
13583a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(shared_array->length()->IsSmi());
13584a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  int array_length = Smi::cast(shared_array->length())->value();
13585a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  for (int i = 0; i < array_length; i++) {
13586a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<Object> element =
13587a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        Object::GetElement(isolate, shared_array, i).ToHandleChecked();
13588a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    RUNTIME_ASSERT(
13589a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        element->IsJSValue() &&
13590a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org        Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
13591a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
13592ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
135931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
13594ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
13595ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13596e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13597c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// Compares 2 strings line-by-line, then token-wise and returns diff in form
13598c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
13599c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org// of diff chunks.
13600a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
136016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13602d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13603c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  ASSERT(args.length() == 2);
13604f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
13605f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
13606c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
13607c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  return *LiveEdit::CompareStrings(s1, s2);
13608c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
13609c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
13610c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
136115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Restarts a call frame and completely drops all frames above.
136125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Returns true if successful. Otherwise returns undefined or an error message.
13613a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
136145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HandleScope scope(isolate);
13615d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
136165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  ASSERT(args.length() == 2);
136178496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
136188496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
136195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
136205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
136215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Heap* heap = isolate->heap();
136225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
136235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Find the relevant frame with the requested index.
136245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  StackFrame::Id id = isolate->debug()->break_frame_id();
136255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (id == StackFrame::NO_ID) {
136265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // If there are no JavaScript stack frames return undefined.
136275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return heap->undefined_value();
136285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
136295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
136305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int count = 0;
136315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  JavaScriptFrameIterator it(isolate, id);
136325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  for (; !it.done(); it.Advance()) {
136335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (index < count + it.frame()->GetInlineCount()) break;
136345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    count += it.frame()->GetInlineCount();
136355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
136365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (it.done()) return heap->undefined_value();
136375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
136381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  const char* error_message = LiveEdit::RestartFrame(it.frame());
136395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (error_message) {
136404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return *(isolate->factory()->InternalizeUtf8String(error_message));
136415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
136425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return heap->true_value();
136435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
136445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
136455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
13646086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org// A testing entry. Returns statement position which is the closest to
13647086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org// source_position.
13648a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
136496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
13650d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  CHECK(isolate->debug()->live_edit_enabled());
13651086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  ASSERT(args.length() == 2);
13652f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13653086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
13654086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13655ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Code> code(function->code(), isolate);
13656086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (code->kind() != Code::FUNCTION &&
13658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      code->kind() != Code::OPTIMIZED_FUNCTION) {
13659ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return isolate->heap()->undefined_value();
13660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
13661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
13662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
13663086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int closest_pc = 0;
13664086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int distance = kMaxInt;
13665086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  while (!it.done()) {
13666086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    int statement_position = static_cast<int>(it.rinfo()->data());
13667086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    // Check if this break point is closer that what was previously found.
13668086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    if (source_position <= statement_position &&
13669086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org        statement_position - source_position < distance) {
13670b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org      closest_pc =
13671b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org          static_cast<int>(it.rinfo()->pc() - code->instruction_start());
13672086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      distance = statement_position - source_position;
13673086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      // Check whether we can't get any closer.
13674086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org      if (distance == 0) break;
13675086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    }
13676086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    it.next();
13677086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
13678086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13679086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  return Smi::FromInt(closest_pc);
13680086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
13681086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13682086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
13683357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// Calls specified function with or without entering the debugger.
13684357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// This is used in unit tests to run code as if debugger is entered or simply
13685357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// to have a stack with C++ frame in the middle.
13686a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
13687ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
136886e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 2);
13689f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13690f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
13691357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
136922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  MaybeHandle<Object> maybe_result;
136932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (without_debugger) {
136942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    maybe_result = Execution::Call(isolate,
136952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   function,
136962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   isolate->global_object(),
136972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   0,
136982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   NULL);
13699357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  } else {
13700196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    DebugScope debug_scope(isolate->debug());
137012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    maybe_result = Execution::Call(isolate,
137022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   function,
137032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   isolate->global_object(),
137042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   0,
137052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   NULL);
13706357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  }
137072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
137082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
137092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return *result;
13710357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
13711357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
13712357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
13713d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Sets a v8 flag.
13714a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetFlags) {
1371579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
137168496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
13717f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, arg, 0);
1371883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  SmartArrayPointer<char> flags =
13719d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
13720afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
13721ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
13722d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
13723d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13724d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13725d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Performs a GC.
13726d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Presently, it only does a full GC.
13727a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CollectGarbage) {
1372879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
137298496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
13730bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
13731ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
13732d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
13733d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13734d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
13735d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Gets the current heap usage.
13736a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetHeapUsage) {
1373779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
137388496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
13739ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
13740d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  if (!Smi::IsValid(usage)) {
13741ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return *isolate->factory()->NewNumberFromInt(usage);
13742d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  }
13743d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org  return Smi::FromInt(usage);
13744d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org}
137459ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
13746ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
13747594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#ifdef V8_I18N_SUPPORT
13748a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
13749594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
137509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Factory* factory = isolate->factory();
13751594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13752594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
13753594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
13754594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13755594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
13756594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13757594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Return value which denotes invalid language tag.
13758594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const char* const kInvalidTag = "invalid-tag";
13759594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13760594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode error = U_ZERO_ERROR;
13761594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char icu_result[ULOC_FULLNAME_CAPACITY];
13762594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int icu_length = 0;
13763594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13764594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
13765594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                      &icu_length, &error);
13766594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(error) || icu_length == 0) {
137678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *factory->NewStringFromAsciiChecked(kInvalidTag);
13768594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13769594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13770594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char result[ULOC_FULLNAME_CAPACITY];
13771594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Force strict BCP47 rules.
13773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
13774594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13775594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(error)) {
137768496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *factory->NewStringFromAsciiChecked(kInvalidTag);
13777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13778594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
137798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *factory->NewStringFromAsciiChecked(result);
13780594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13781594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13782594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13783a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
13784594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
137858496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Factory* factory = isolate->factory();
13786594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13787594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
13788594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
13789594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13790594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const icu::Locale* available_locales = NULL;
13791594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int32_t count = 0;
13792594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13793594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (service->IsUtf8EqualTo(CStrVector("collator"))) {
13794594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::Collator::getAvailableLocales(count);
13795594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
13796594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::NumberFormat::getAvailableLocales(count);
13797594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
13798594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::DateFormat::getAvailableLocales(count);
13799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
13800594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    available_locales = icu::BreakIterator::getAvailableLocales(count);
13801594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13802594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13803594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode error = U_ZERO_ERROR;
13804594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char result[ULOC_FULLNAME_CAPACITY];
13805594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> locales =
138068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      factory->NewJSObject(isolate->object_function());
13807594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13808594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (int32_t i = 0; i < count; ++i) {
13809594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    const char* icu_name = available_locales[i].getName();
13810594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13811594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    error = U_ZERO_ERROR;
13812594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // No need to force strict BCP47 rules.
13813594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13814594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (U_FAILURE(error)) {
13815594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      // This shouldn't happen, but lets not break the user.
13816594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      continue;
13817594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13818594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
138198496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(isolate,
13820fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        JSObject::SetOwnPropertyIgnoreAttributes(
13821594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            locales,
138228496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org            factory->NewStringFromAsciiChecked(result),
138238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org            factory->NewNumber(i),
13824594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE));
13825594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13826594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13827594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *locales;
13828594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13829594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13830594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13831a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
138329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HandleScope scope(isolate);
138339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Factory* factory = isolate->factory();
13834594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13835594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 0);
13836594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13837594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Locale default_locale;
13838594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13839594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set the locale
13840594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  char result[ULOC_FULLNAME_CAPACITY];
13841594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
13842594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uloc_toLanguageTag(
13843594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
13844594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_SUCCESS(status)) {
138458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *factory->NewStringFromAsciiChecked(result);
13846594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13847594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
138488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *factory->NewStringFromStaticAscii("und");
13849594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13850594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13851594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13852a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
13853594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
138548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Factory* factory = isolate->factory();
13855594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13856594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
13857594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13858594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
13859594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13860594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  uint32_t length = static_cast<uint32_t>(input->length()->Number());
13861a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // Set some limit to prevent fuzz tests from going OOM.
13862a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // Can be bumped when callers' requirements change.
13863a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(length < 100);
138648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<FixedArray> output = factory->NewFixedArray(length);
138658496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
138668496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<Name> base = factory->NewStringFromStaticAscii("base");
13867594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (unsigned int i = 0; i < length; ++i) {
13868202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> locale_id;
13869202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13870202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        isolate, locale_id, Object::GetElement(isolate, input, i));
138714452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    if (!locale_id->IsString()) {
138728496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return isolate->Throw(*factory->illegal_argument_string());
13873594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13874594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13875594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    v8::String::Utf8Value utf8_locale_id(
138764452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org        v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
13877594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13878594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    UErrorCode error = U_ZERO_ERROR;
13879594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13880594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Convert from BCP47 to ICU format.
13881594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de-DE-u-co-phonebk -> de_DE@collation=phonebook
13882594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_locale[ULOC_FULLNAME_CAPACITY];
13883594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int icu_locale_length = 0;
13884594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
13885594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        &icu_locale_length, &error);
13886594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (U_FAILURE(error) || icu_locale_length == 0) {
138878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return isolate->Throw(*factory->illegal_argument_string());
13888594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13889594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13890594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Maximize the locale.
13891594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
13892594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_max_locale[ULOC_FULLNAME_CAPACITY];
13893594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_addLikelySubtags(
13894594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13895594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13896594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Remove extensions from maximized locale.
13897594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_Latn_DE@collation=phonebook -> de_Latn_DE
13898594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
13899594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_getBaseName(
13900594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13901594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13902594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Get original name without extensions.
13903594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_DE@collation=phonebook -> de_DE
13904594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char icu_base_locale[ULOC_FULLNAME_CAPACITY];
13905594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_getBaseName(
13906594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
13907594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13908594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // Convert from ICU locale format to BCP47 format.
13909594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_Latn_DE -> de-Latn-DE
13910594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char base_max_locale[ULOC_FULLNAME_CAPACITY];
13911594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
13912594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       ULOC_FULLNAME_CAPACITY, FALSE, &error);
13913594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13914594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    // de_DE -> de-DE
13915594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    char base_locale[ULOC_FULLNAME_CAPACITY];
13916594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    uloc_toLanguageTag(
13917594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13918594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13919594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (U_FAILURE(error)) {
139208496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return isolate->Throw(*factory->illegal_argument_string());
13921594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
13922594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
139238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
139248496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(isolate,
13925fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        JSObject::SetOwnPropertyIgnoreAttributes(
13926594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            result,
13927594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            maximized,
139288496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org            factory->NewStringFromAsciiChecked(base_max_locale),
13929594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE));
139308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_ON_EXCEPTION(isolate,
13931fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org        JSObject::SetOwnPropertyIgnoreAttributes(
13932594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            result,
13933594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            base,
139348496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org            factory->NewStringFromAsciiChecked(base_locale),
13935594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            NONE));
13936594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    output->set(i, *result);
13937594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
13938594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
139398496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<JSArray> result = factory->NewJSArrayWithElements(output);
13940594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  result->set_length(Smi::FromInt(length));
13941594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *result;
13942594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
13943594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13944594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
13945a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
13946ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  HandleScope scope(isolate);
13947ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13948ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  ASSERT(args.length() == 1);
13949ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13950ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
13951ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
139528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (!input->IsJSObject()) return isolate->heap()->false_value();
13953ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<JSObject> obj = Handle<JSObject>::cast(input);
13954ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13955ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
139563484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
13957ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  return isolate->heap()->ToBoolean(!tag->IsTheHole());
13958ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org}
13959ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13960ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13961a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
13962ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  HandleScope scope(isolate);
13963ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13964ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  ASSERT(args.length() == 2);
13965ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13966ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
13967ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
13968ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
139698496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (!input->IsJSObject()) return isolate->heap()->false_value();
13970ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<JSObject> obj = Handle<JSObject>::cast(input);
13971ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13972ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
139733484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
13974ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  return isolate->heap()->ToBoolean(
13975ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      tag->IsString() && String::cast(*tag)->Equals(*expected_type));
13976ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org}
13977ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13978ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13979a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
13980ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  HandleScope scope(isolate);
13981ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13982ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  ASSERT(args.length() == 3);
13983ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13984ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
13985ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
13986ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
13987ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13988ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
13989ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  JSObject::SetHiddenProperty(input, marker, type);
13990ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13991ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  marker = isolate->factory()->intl_impl_object_string();
13992ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  JSObject::SetHiddenProperty(input, marker, impl);
13993ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13994ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  return isolate->heap()->undefined_value();
13995ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org}
13996ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13997ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
13998a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
13999ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  HandleScope scope(isolate);
14000ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14001ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  ASSERT(args.length() == 1);
14002ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14003ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14004ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14005ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  if (!input->IsJSObject()) {
14006ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    Vector< Handle<Object> > arguments = HandleVector(&input, 1);
14007ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    Handle<Object> type_error =
14008ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org        isolate->factory()->NewTypeError("not_intl_object", arguments);
14009ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    return isolate->Throw(*type_error);
14010ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  }
14011ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14012ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<JSObject> obj = Handle<JSObject>::cast(input);
14013ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14014ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  Handle<String> marker = isolate->factory()->intl_impl_object_string();
140153484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
14016ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  if (impl->IsTheHole()) {
14017ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
14018ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    Handle<Object> type_error =
14019ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org        isolate->factory()->NewTypeError("not_intl_object", arguments);
14020ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    return isolate->Throw(*type_error);
14021ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  }
14022ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  return *impl;
14023ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org}
14024ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14025ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
14026a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
14027594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14028594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14029594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
14030594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14031594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14032594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14033594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14034594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14035594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<ObjectTemplateInfo> date_format_template =
14036594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      I18N::GetTemplate(isolate);
14037594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14038594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Create an empty object wrapper.
140392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<JSObject> local_object;
140402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
140412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, local_object,
140422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::InstantiateObject(date_format_template));
14043594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14044594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set date time formatter as internal field of the resulting JS object.
14045594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
14046594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate, locale, options, resolved);
14047594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14048594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!date_format) return isolate->ThrowIllegalOperation();
14049594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14050594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
14051594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
140528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(isolate,
14053fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSObject::SetOwnPropertyIgnoreAttributes(
14054594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          local_object,
140558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("dateFormat"),
140568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("valid"),
14057594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          NONE));
14058594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14059594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Make object handle weak so we can delete the data format once GC kicks in.
1406032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
140614f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::MakeWeak(wrapper.location(),
140624f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          reinterpret_cast<void*>(wrapper.location()),
1406332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                          DateFormat::DeleteDateFormat);
14064594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *local_object;
14065594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14066594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14067594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14068a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_InternalDateFormat) {
14069594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14070594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14071594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
14072594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14073594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14074594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
14075594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
140762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> value;
140772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
140782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, value, Execution::ToNumber(isolate, date));
14079594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14080594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::SimpleDateFormat* date_format =
14081594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      DateFormat::UnpackDateFormat(isolate, date_format_holder);
14082594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!date_format) return isolate->ThrowIllegalOperation();
14083594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14084594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString result;
1408532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  date_format->format(value->Number(), result);
14086594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
140878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result_str;
140888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
140898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result_str,
140908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate->factory()->NewStringFromTwoByte(
140918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          Vector<const uint16_t>(
140928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              reinterpret_cast<const uint16_t*>(result.getBuffer()),
140938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              result.length())));
140948496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *result_str;
14095594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14096594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14097594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14098a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_InternalDateParse) {
14099594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14100594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14101594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
14102594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14103594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14104594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
14105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
14107594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
14108594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::SimpleDateFormat* date_format =
14109594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      DateFormat::UnpackDateFormat(isolate, date_format_holder);
14110594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!date_format) return isolate->ThrowIllegalOperation();
14111594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14112594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
14113594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UDate date = date_format->parse(u_date, status);
14114594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14115594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
141162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
141172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
141182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
141192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::NewDate(isolate, static_cast<double>(date)));
141202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSERT(result->IsJSDate());
14121594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *result;
14122594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14123594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14124594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14125a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
14126594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14127594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14128594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
14129594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14130594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14131594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14132594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14133594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<ObjectTemplateInfo> number_format_template =
14135594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      I18N::GetTemplate(isolate);
14136594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14137594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Create an empty object wrapper.
141382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<JSObject> local_object;
141392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
141402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, local_object,
141412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::InstantiateObject(number_format_template));
14142594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14143594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set number formatter as internal field of the resulting JS object.
14144594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
14145594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate, locale, options, resolved);
14146594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14147594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!number_format) return isolate->ThrowIllegalOperation();
14148594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14149594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
14150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
141518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(isolate,
14152fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSObject::SetOwnPropertyIgnoreAttributes(
14153594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          local_object,
141548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("numberFormat"),
141558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("valid"),
14156594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          NONE));
14157594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1415832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
141594f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::MakeWeak(wrapper.location(),
141604f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          reinterpret_cast<void*>(wrapper.location()),
1416132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                          NumberFormat::DeleteNumberFormat);
14162594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *local_object;
14163594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14164594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14165594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14166a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
14167594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14168594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14169594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
14170594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14171594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14172594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
14173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
141742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> value;
141752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
141762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, value, Execution::ToNumber(isolate, number));
14177594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14178594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::DecimalFormat* number_format =
14179594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14180594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!number_format) return isolate->ThrowIllegalOperation();
14181594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14182594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString result;
1418332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  number_format->format(value->Number(), result);
14184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
141858496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result_str;
141868496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
141878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result_str,
141888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate->factory()->NewStringFromTwoByte(
141898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          Vector<const uint16_t>(
141908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              reinterpret_cast<const uint16_t*>(result.getBuffer()),
141918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              result.length())));
141928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *result_str;
14193594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14194594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14195594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14196a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_InternalNumberParse) {
14197594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14198594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14199594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 2);
14200594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14201594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14202594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
14203594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14204594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
14205594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
14206594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::DecimalFormat* number_format =
14207594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!number_format) return isolate->ThrowIllegalOperation();
14209594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14210594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
14211594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Formattable result;
14212594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
14213594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // to be part of Chrome.
14214594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // TODO(cira): Include currency parsing code using parseCurrency call.
14215594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // We need to check if the formatter parses all currencies or only the
14216594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // one it was constructed with (it will impact the API - how to return ISO
14217594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // code and the value).
14218594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  number_format->parse(u_number, result, status);
14219594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14220594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14221594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  switch (result.getType()) {
14222594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  case icu::Formattable::kDouble:
14223594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return *isolate->factory()->NewNumber(result.getDouble());
14224594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  case icu::Formattable::kLong:
14225594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return *isolate->factory()->NewNumberFromInt(result.getLong());
14226594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  case icu::Formattable::kInt64:
14227594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return *isolate->factory()->NewNumber(
14228594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        static_cast<double>(result.getInt64()));
14229594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  default:
14230594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return isolate->heap()->undefined_value();
14231594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
14232594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14233594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14234594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14235a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateCollator) {
14236594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14237594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14238594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
14239594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14240594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14241594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14242594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14243594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14244594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
14245594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14246594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Create an empty object wrapper.
142472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<JSObject> local_object;
142482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
142492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, local_object, Execution::InstantiateObject(collator_template));
14250594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14251594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Set collator as internal field of the resulting JS object.
14252594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Collator* collator = Collator::InitializeCollator(
14253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      isolate, locale, options, resolved);
14254594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14255594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!collator) return isolate->ThrowIllegalOperation();
14256594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14257594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
14258594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
142598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(isolate,
14260fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSObject::SetOwnPropertyIgnoreAttributes(
14261594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          local_object,
142628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("collator"),
142638496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("valid"),
14264594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          NONE));
14265594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1426632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
142674f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::MakeWeak(wrapper.location(),
142684f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          reinterpret_cast<void*>(wrapper.location()),
1426932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                          Collator::DeleteCollator);
14270594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *local_object;
14271594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14272594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14274a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_InternalCompare) {
14275594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14276594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14277594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 3);
14278594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14279594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
14280594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
14281594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
14282594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14283594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
14284594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!collator) return isolate->ThrowIllegalOperation();
14285594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14286594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Value string_value1(v8::Utils::ToLocal(string1));
14287594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  v8::String::Value string_value2(v8::Utils::ToLocal(string2));
14288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
14289594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
14290594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UErrorCode status = U_ZERO_ERROR;
14291594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  UCollationResult result = collator->compare(u_string1,
14292594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              string_value1.length(),
14293594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              u_string2,
14294594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              string_value2.length(),
14295594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                                              status);
14296594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
14297594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14298594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *isolate->factory()->NewNumberFromInt(result);
14299594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
1430032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1430132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
14302a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_StringNormalize) {
1430357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HandleScope scope(isolate);
1430457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  static const UNormalizationMode normalizationForms[] =
1430557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
1430657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
1430757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  ASSERT(args.length() == 2);
1430857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
1430957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
1431057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
14311a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  RUNTIME_ASSERT(form_id >= 0 &&
14312a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                 static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
1431357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
1431457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
1431557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
1431657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
1431757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // TODO(mnita): check Normalizer2 (not available in ICU 46)
1431857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  UErrorCode status = U_ZERO_ERROR;
1431957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  icu::UnicodeString result;
1432057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
1432157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      result, status);
1432257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (U_FAILURE(status)) {
1432357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    return isolate->heap()->undefined_value();
1432457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
1432557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
143268496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<String> result_str;
143278496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
143288496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate, result_str,
143298496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      isolate->factory()->NewStringFromTwoByte(
143308496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          Vector<const uint16_t>(
143318496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              reinterpret_cast<const uint16_t*>(result.getBuffer()),
143328496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org              result.length())));
143338496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *result_str;
1433457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org}
1433557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
1433657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
14337a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
1433832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  HandleScope scope(isolate);
1433932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1434032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ASSERT(args.length() == 3);
1434132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1434232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
1434332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
1434432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
1434532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1434632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  Handle<ObjectTemplateInfo> break_iterator_template =
1434732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      I18N::GetTemplate2(isolate);
1434832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1434932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // Create an empty object wrapper.
143502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<JSObject> local_object;
143512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
143522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, local_object,
143532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::InstantiateObject(break_iterator_template));
1435432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1435532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // Set break iterator as internal field of the resulting JS object.
1435632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
1435732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      isolate, locale, options, resolved);
1435832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1435932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (!break_iterator) return isolate->ThrowIllegalOperation();
1436032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1436132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
1436232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // Make sure that the pointer to adopted text is NULL.
1436332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
1436432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
143658496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(isolate,
14366fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSObject::SetOwnPropertyIgnoreAttributes(
1436732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org          local_object,
143688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("breakIterator"),
143698496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          isolate->factory()->NewStringFromStaticAscii("valid"),
1437032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org          NONE));
1437132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1437232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // Make object handle weak so we can delete the break iterator once GC kicks
1437332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // in.
1437432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
143754f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  GlobalHandles::MakeWeak(wrapper.location(),
143764f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org                          reinterpret_cast<void*>(wrapper.location()),
1437732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                          BreakIterator::DeleteBreakIterator);
1437832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  return *local_object;
1437932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
1438032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1438132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
14382a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
1438332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  HandleScope scope(isolate);
1438432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1438532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ASSERT(args.length() == 2);
1438632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1438732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
1438832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
1438932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1439032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::BreakIterator* break_iterator =
1439132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
1439232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (!break_iterator) return isolate->ThrowIllegalOperation();
1439332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1439432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
1439532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      break_iterator_holder->GetInternalField(1));
1439632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  delete u_text;
1439732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1439832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  v8::String::Value text_value(v8::Utils::ToLocal(text));
1439932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  u_text = new icu::UnicodeString(
1440032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      reinterpret_cast<const UChar*>(*text_value), text_value.length());
1440132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
1440232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1440332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  break_iterator->setText(*u_text);
1440432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1440532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  return isolate->heap()->undefined_value();
1440632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
1440732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1440832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
14409a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
1441032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  HandleScope scope(isolate);
1441132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1441232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ASSERT(args.length() == 1);
1441332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1441432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
1441532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1441632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::BreakIterator* break_iterator =
1441732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
1441832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (!break_iterator) return isolate->ThrowIllegalOperation();
1441932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1442032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  return *isolate->factory()->NewNumberFromInt(break_iterator->first());
1442132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
1442232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1442332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
14424a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
1442532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  HandleScope scope(isolate);
1442632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1442732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ASSERT(args.length() == 1);
1442832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1442932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
1443032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1443132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::BreakIterator* break_iterator =
1443232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
1443332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (!break_iterator) return isolate->ThrowIllegalOperation();
1443432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1443532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  return *isolate->factory()->NewNumberFromInt(break_iterator->next());
1443632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
1443732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1443832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
14439a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
1444032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  HandleScope scope(isolate);
1444132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1444232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ASSERT(args.length() == 1);
1444332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1444432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
1444532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1444632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::BreakIterator* break_iterator =
1444732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
1444832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (!break_iterator) return isolate->ThrowIllegalOperation();
1444932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1445032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  return *isolate->factory()->NewNumberFromInt(break_iterator->current());
1445132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
1445232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1445332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
14454a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
1445532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  HandleScope scope(isolate);
1445632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1445732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ASSERT(args.length() == 1);
1445832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1445932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
1446032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1446132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::BreakIterator* break_iterator =
1446232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
1446332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (!break_iterator) return isolate->ThrowIllegalOperation();
1446432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1446532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
1446632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  icu::RuleBasedBreakIterator* rule_based_iterator =
1446732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
1446832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  int32_t status = rule_based_iterator->getRuleStatus();
1446932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  // Keep return values in sync with JavaScript BreakType enum.
1447032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
144718496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *isolate->factory()->NewStringFromStaticAscii("none");
1447232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
144738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *isolate->factory()->NewStringFromStaticAscii("number");
1447432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
144758496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *isolate->factory()->NewStringFromStaticAscii("letter");
1447632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
144778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *isolate->factory()->NewStringFromStaticAscii("kana");
1447832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
144798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *isolate->factory()->NewStringFromStaticAscii("ideo");
1448032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  } else {
144818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    return *isolate->factory()->NewStringFromStaticAscii("unknown");
1448232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
1448332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
14484594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#endif  // V8_I18N_SUPPORT
14485594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14486594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1448743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Finds the script object from the script data. NOTE: This operation uses
1448843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// heap traversal to find the function generated for the source position
1448943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for the requested break point. For lazily compiled functions several heap
1449043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// traversals might be required rendering this operation as a rather slow
1449143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// operation. However for setting break points which is normally done through
1449243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// some kind of user interaction the performance is not crucial.
1449343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic Handle<Object> Runtime_GetScriptFromScriptName(
1449443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<String> script_name) {
1449543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Scan the heap for Script objects to find the script with the requested
1449643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // script data.
1449743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Script> script;
14498d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Factory* factory = script_name->GetIsolate()->factory();
144997c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Heap* heap = script_name->GetHeap();
145007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  HeapIterator iterator(heap);
14501b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  HeapObject* obj = NULL;
14502b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  while (script.is_null() && ((obj = iterator.next()) != NULL)) {
1450343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If a script is found check if it has the script data requested.
1450443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (obj->IsScript()) {
1450543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (Script::cast(obj)->name()->IsString()) {
1450643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
1450743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          script = Handle<Script>(Script::cast(obj));
1450843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1450943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1451043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1451143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1451243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1451343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If no script with the requested script data is found return undefined.
14514d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (script.is_null()) return factory->undefined_value();
1451543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1451643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the script found.
145179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return Script::GetWrapper(script);
1451843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1451943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1452043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1452143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Get the script object from script data. NOTE: Regarding performance
1452243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// see the NOTE for GetScriptFromScriptData.
1452343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// args[0]: script data for the script to find the source for
14524a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetScript) {
14525ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1452643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1452743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(args.length() == 1);
1452843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14529f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(String, script_name, 0);
1453043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1453143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the requested script.
1453243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> result =
1453343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Runtime_GetScriptFromScriptName(Handle<String>(script_name));
1453443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
1453543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1453643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1453743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Collect the raw data for a stack trace.  Returns an array of 4
14539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// element segments each containing a receiver, function, code and
14540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// native code offset.
14541a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_CollectStackTrace) {
145426e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HandleScope scope(isolate);
145438496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 3);
14544f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
145458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
14546ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org  CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
1454786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
14548eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  // Optionally capture a more detailed stack trace for the message.
14549eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  isolate->CaptureAndSetDetailedStackTrace(error_object);
14550eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  // Capture a simple stack trace for the stack property.
14551eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org  return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
14552eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org}
1455386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
145542abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
14555fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Retrieve the stack trace.  This is the raw stack trace that yet has to
14556fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// be formatted.  Since we only need this once, clear it afterwards.
14557a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetAndClearOverflowedStackTrace) {
1455846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  HandleScope scope(isolate);
145598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
145608fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
145618fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Handle<String> key = isolate->factory()->hidden_stack_trace_string();
145623484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> result(error_object->GetHiddenProperty(key), isolate);
14563fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (result->IsTheHole()) return isolate->heap()->undefined_value();
14564fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
145658fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  JSObject::DeleteHiddenProperty(error_object, key);
145668fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  return *result;
145672abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
145682abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
145692abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
145703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Returns V8 version as a string.
14571a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetV8Version) {
145729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HandleScope scope(isolate);
145738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
145743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
145753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  const char* version_string = v8::V8::GetVersion();
145763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
145778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  return *isolate->factory()->NewStringFromAsciiChecked(version_string);
145783811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
145793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
145803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14581a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_Abort) {
1458279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14583f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(args.length() == 1);
14584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  CONVERT_SMI_ARG_CHECKED(message_id, 0);
14585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  const char* message = GetBailoutReason(
14586f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      static_cast<BailoutReason>(message_id));
14587f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  OS::PrintError("abort: %s\n", message);
14588bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  isolate->PrintStack(stderr);
1458943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  OS::Abort();
1459043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
1459143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
1459243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1459343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1459443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14595a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_AbortJS) {
145969f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  HandleScope scope(isolate);
145979f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  ASSERT(args.length() == 1);
145989f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
14599afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  OS::PrintError("abort: %s\n", message->ToCString().get());
146009f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  isolate->PrintStack(stderr);
146019f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  OS::Abort();
146029f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  UNREACHABLE();
146039f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  return NULL;
146049f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org}
146059f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
146069f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
14607a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_FlattenString) {
1460859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  HandleScope scope(isolate);
1460959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  ASSERT(args.length() == 1);
1461059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
146119e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return *String::Flatten(str);
1461259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
1461359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1461459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
14615a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
14616ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  HandleScope scope(isolate);
14617ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  ASSERT(args.length() == 0);
14618ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  isolate->heap()->NotifyContextDisposed();
14619ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  return isolate->heap()->undefined_value();
14620ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org}
14621ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
14622ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
14623a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
1462463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  HandleScope scope(isolate);
1462563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  ASSERT(args.length() == 2);
1462663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
1462763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
14628e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  RUNTIME_ASSERT((index->value() & 1) == 1);
14629e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  FieldIndex field_index =
14630e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
14631e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  if (field_index.is_inobject()) {
14632e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    RUNTIME_ASSERT(field_index.property_index() <
14633e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                   object->map()->inobject_properties());
14634e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  } else {
14635e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    RUNTIME_ASSERT(field_index.outobject_array_index() <
14636e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                   object->properties()->length());
14637e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  }
14638e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
14639f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
146403484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
1464163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org}
1464263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
1464363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
14644a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
14645594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HandleScope scope(isolate);
14646594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(args.length() == 1);
14647594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!object->IsJSObject()) return Smi::FromInt(0);
14649594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
14650594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
14651e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  // This call must not cause lazy deopts, because it's called from deferred
14652e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  // code where we can't handle lazy deopts for lack of a suitable bailout
14653e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  // ID. So we just try migration and signal failure if necessary,
14654e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  // which will also trigger a deopt.
14655a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
14656594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return *object;
14657594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
14658594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14659594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14660a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_GetFromCache) {
1466179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14662c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // This is only called from codegen, so checks might be more lax.
14663f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
146648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, key, 1);
14665c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14666e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  {
14667e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    DisallowHeapAllocation no_alloc;
14668c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14669e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    int finger_index = cache->finger_index();
14670e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Object* o = cache->get(finger_index);
14671c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    if (o == key) {
14672e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      // The fastest case: hit the same place again.
14673e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return cache->get(finger_index + 1);
14674e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
14675e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
14676e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    for (int i = finger_index - 2;
14677e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org         i >= JSFunctionResultCache::kEntriesIndex;
14678e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org         i -= 2) {
14679e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      o = cache->get(i);
14680e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      if (o == key) {
14681e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        cache->set_finger_index(i);
14682e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        return cache->get(i + 1);
14683e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      }
14684c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    }
14685c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14686e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    int size = cache->size();
14687e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    ASSERT(size <= cache->length());
14688c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14689e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    for (int i = size - 2; i > finger_index; i -= 2) {
14690e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      o = cache->get(i);
14691e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      if (o == key) {
14692e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        cache->set_finger_index(i);
14693e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        return cache->get(i + 1);
14694e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      }
14695c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    }
14696c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
14697c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
146980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // There is no value in the cache.  Invoke the function and cache result.
14699ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
147000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
147010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Handle<JSFunctionResultCache> cache_handle(cache);
1470209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> key_handle(key, isolate);
147030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Handle<Object> value;
147040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  {
147050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    Handle<JSFunction> factory(JSFunction::cast(
147060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com          cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
147070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    // TODO(antonm): consider passing a receiver when constructing a cache.
1470809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    Handle<Object> receiver(isolate->native_context()->global_object(),
1470909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                            isolate);
147100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    // This handle is nor shared, nor used later, so it's safe.
14711a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    Handle<Object> argv[] = { key_handle };
147122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
147132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, value,
147142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
147150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  }
147160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
14717c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
14718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
14719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    cache_handle->JSFunctionResultCacheVerify();
14720394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
147210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif
147220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
147230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Function invocation may have cleared the cache.  Reread all the data.
14724e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  int finger_index = cache_handle->finger_index();
14725e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  int size = cache_handle->size();
147260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
147270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // If we have spare room, put new data into it, otherwise evict post finger
147280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // entry which is likely to be the least recently used.
147290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  int index = -1;
147300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  if (size < cache_handle->length()) {
147310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
147320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    index = size;
14733c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  } else {
147340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    index = finger_index + JSFunctionResultCache::kEntrySize;
147350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com    if (index == cache_handle->length()) {
147360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      index = JSFunctionResultCache::kEntriesIndex;
14737397e23cb4f6fae2f4b020b914ce08c8b150c12e2antonm@chromium.org    }
14738c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  }
147390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
147400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(index % 2 == 0);
147410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
147420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ASSERT(index < cache_handle->length());
147430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
147440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  cache_handle->set(index, *key_handle);
147450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  cache_handle->set(index + 1, *value);
147460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  cache_handle->set_finger_index(index);
147470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
14748c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
14749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_verify_heap) {
14750394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    cache_handle->JSFunctionResultCacheVerify();
14751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
147520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif
147530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
147540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  return *value;
14755c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
14756c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
1475731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
14758a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
1475979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
147608496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
14761f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
1476231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  return Smi::FromInt(message->start_position());
1476331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
1476431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
1476531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
14766a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MessageGetScript) {
1476779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
147688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 1);
14769f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
1477031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  return message->script();
1477131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}
1477231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
1477331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
1477444510671e908d0efc639513d81efcd81e7f14240kasper.lund#ifdef DEBUG
1477544510671e908d0efc639513d81efcd81e7f14240kasper.lund// ListNatives is ONLY used by the fuzz-natives.js in debug mode
1477644510671e908d0efc639513d81efcd81e7f14240kasper.lund// Exclude the code in release mode.
14777a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ListNatives) {
14778c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate);
147796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ASSERT(args.length() == 0);
147808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#define COUNT_ENTRY(Name, argc, ressize) + 1
147818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  int entry_count = 0
147828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
147839b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      RUNTIME_HIDDEN_FUNCTION_LIST(COUNT_ENTRY)
14784eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org      INLINE_FUNCTION_LIST(COUNT_ENTRY)
14785eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org      INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
147868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#undef COUNT_ENTRY
14787ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Factory* factory = isolate->factory();
14788ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
1478943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index = 0;
14790f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  bool inline_runtime_functions = false;
14791a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#define ADD_ENTRY(Name, argc, ressize)                                       \
1479243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  {                                                                          \
14793c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    HandleScope inner(isolate);                                              \
14794f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    Handle<String> name;                                                     \
14795f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    /* Inline runtime functions have an underscore in front of the name. */  \
14796f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    if (inline_runtime_functions) {                                          \
147978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      name = factory->NewStringFromStaticAscii("_" #Name);                   \
14798f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    } else {                                                                 \
147998496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      name = factory->NewStringFromStaticAscii(#Name);                       \
14800f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    }                                                                        \
14801ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
148028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    pair_elements->set(0, *name);                                            \
148038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    pair_elements->set(1, Smi::FromInt(argc));                               \
14804ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
148058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    elements->set(index++, *pair);                                           \
1480643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
14807f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  inline_runtime_functions = false;
1480843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_FUNCTION_LIST(ADD_ENTRY)
14809eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
148109b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  // Calling hidden runtime functions should just throw.
148119b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  RUNTIME_HIDDEN_FUNCTION_LIST(ADD_ENTRY)
14812f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  inline_runtime_functions = true;
14813d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  INLINE_FUNCTION_LIST(ADD_ENTRY)
1481443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef ADD_ENTRY
148158f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  ASSERT_EQ(index, entry_count);
14816ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
1481743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *result;
1481843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1481944510671e908d0efc639513d81efcd81e7f14240kasper.lund#endif
1482043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1482143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14822a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IS_VAR) {
1482343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();  // implemented as macro in the parser
1482443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
1482543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1482643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1482743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
148284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
14829a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  RUNTIME_FUNCTION(Runtime_Has##Name) {          \
14830a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
148314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return isolate->heap()->ToBoolean(obj->Has##Name());  \
148324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
148334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
14834830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
14835830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
14836830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
148374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
14838830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
148394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
14840486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
148414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
148427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org// Properties test sitting with elements tests - not fooling anyone.
148437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
148444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
148454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
148464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
14847b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
14848af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
14849a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
14850af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14851af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
14852af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  }
14853af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14854af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgTYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14855af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14856af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14857af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14858af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14859895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
14860a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
14861895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14862895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
14863895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
14864895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
14865895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgTYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14866895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
14867895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14868895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
14869895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
14870a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_HaveSameMap) {
1487179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14872b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  ASSERT(args.length() == 2);
14873f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14874f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14875b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14876b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org}
14877b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
14878e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14879c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
14880e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  SealHandleScope shs(isolate);
14881e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  ASSERT(args.length() == 1);
14882c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  CONVERT_ARG_CHECKED(Object, obj, 0);
14883c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
14884e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org}
14885e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
14886e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
14887a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_IsObserved) {
1488879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14889e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 1);
14890b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
14891b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
148928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
1489329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  ASSERT(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
14894e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return isolate->heap()->ToBoolean(obj->map()->is_observed());
14895e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14896e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14897e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14898a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_SetIsObserved) {
14899b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  HandleScope scope(isolate);
14900169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(args.length() == 1);
14901b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
14902a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
14903a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
14904a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  RUNTIME_ASSERT(!obj->map()->is_observed());
14905594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
14906169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  ASSERT(obj->IsJSObject());
14907b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  JSObject::SetObserved(Handle<JSObject>::cast(obj));
14908b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  return isolate->heap()->undefined_value();
14909e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14910e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14911e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1491254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
1491354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  HandleScope scope(isolate);
149149f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  ASSERT(args.length() == 1);
1491554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
1491654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  isolate->EnqueueMicrotask(microtask);
1491754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  return isolate->heap()->undefined_value();
14918e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14919e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14920e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14921a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_RunMicrotasks) {
14922f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HandleScope scope(isolate);
14923f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(args.length() == 0);
1492454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  isolate->RunMicrotasks();
14925f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return isolate->heap()->undefined_value();
14926f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
14927f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
14928f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
14929a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetObservationState) {
1493079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  SealHandleScope shs(isolate);
14931e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 0);
14932e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return isolate->heap()->observation_state();
14933e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14934e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14935e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14936a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
149372f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  HandleScope scope(isolate);
14938e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ASSERT(args.length() == 0);
149392f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  // TODO(adamk): Currently this runtime function is only called three times per
149402f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  // isolate. If it's called more often, the map should be moved into the
149412f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  // strong root list.
149422f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  Handle<Map> map =
149432f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
149442f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  Handle<JSWeakMap> weakmap =
149452f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
14946a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  return *WeakCollectionInitialize(isolate, weakmap);
14947e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
14948e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14949e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
14950c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgstatic bool ContextsHaveSameOrigin(Handle<Context> context1,
14951c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                                   Handle<Context> context2) {
14952c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return context1->security_token() == context2->security_token();
14953c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
14954c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14955c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14956c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
14957e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  HandleScope scope(isolate);
14958e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  ASSERT(args.length() == 3);
14959e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
14960e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
14961c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
14962c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14963c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> observer_context(observer->context()->native_context(),
14964c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      isolate);
14965c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> object_context(object->GetCreationContext());
14966c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> record_context(record->GetCreationContext());
14967c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14968c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return isolate->heap()->ToBoolean(
14969c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      ContextsHaveSameOrigin(object_context, observer_context) &&
14970c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      ContextsHaveSameOrigin(object_context, record_context));
14971c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
14972c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14973c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14974c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
14975c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  HandleScope scope(isolate);
14976c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  ASSERT(args.length() == 1);
14977c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14978c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14979c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> creation_context(object->GetCreationContext(), isolate);
14980c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return isolate->heap()->ToBoolean(
14981c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      ContextsHaveSameOrigin(creation_context, isolate->native_context()));
14982c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
14983c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14984c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14985eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
14986c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  HandleScope scope(isolate);
14987eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  ASSERT(args.length() == 1);
14988c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14989c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14990c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> context(object->GetCreationContext(), isolate);
14991eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  return context->native_object_observe();
14992c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
14993c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14994c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
14995eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
14996c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  HandleScope scope(isolate);
14997c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  ASSERT(args.length() == 1);
14998c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14999c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
15000c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> context(object->GetCreationContext(), isolate);
15001eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  return context->native_object_get_notifier();
15002c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
15003c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
15004c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
15005eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgRUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
15006c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  HandleScope scope(isolate);
15007eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  ASSERT(args.length() == 1);
15008c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
15009c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
15010c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Context> context(object_info->GetCreationContext(), isolate);
15011eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  return context->native_object_notifier_perform_change();
15012e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org}
15013e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
15014e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
15015a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgstatic Object* ArrayConstructorCommon(Isolate* isolate,
15016dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                           Handle<JSFunction> constructor,
15017b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                           Handle<AllocationSite> site,
15018dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                           Arguments* caller_args) {
150192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  Factory* factory = isolate->factory();
150202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
15021dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool holey = false;
15022dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool can_use_type_feedback = true;
15023dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (caller_args->length() == 1) {
150242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Handle<Object> argument_one = caller_args->at<Object>(0);
15025dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (argument_one->IsSmi()) {
150262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      int value = Handle<Smi>::cast(argument_one)->value();
15027dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
15028dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        // the array is a dictionary in this case.
15029dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        can_use_type_feedback = false;
15030dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      } else if (value != 0) {
15031dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        holey = true;
15032dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      }
15033dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    } else {
15034dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      // Non-smi length argument produces a dictionary
15035dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      can_use_type_feedback = false;
15036dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
15037dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
15038dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
150392904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  Handle<JSArray> array;
15040b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!site.is_null() && can_use_type_feedback) {
15041bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ElementsKind to_kind = site->GetElementsKind();
15042dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (holey && !IsFastHoleyElementsKind(to_kind)) {
15043dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      to_kind = GetHoleyElementsKind(to_kind);
15044dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      // Update the allocation site info to reflect the advice alteration.
15045bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      site->SetElementsKind(to_kind);
15046dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
15047dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
15048bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // We should allocate with an initial map that reflects the allocation site
15049bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // advice. Therefore we use AllocateJSObjectFromMap instead of passing
15050bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // the constructor.
150512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Handle<Map> initial_map(constructor->initial_map(), isolate);
15052bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (to_kind != initial_map->elements_kind()) {
150532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      initial_map = Map::AsElementsKind(initial_map, to_kind);
15054bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    }
15055bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org
15056bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // If we don't care to track arrays of to_kind ElementsKind, then
15057bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // don't emit a memento for them.
150582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    Handle<AllocationSite> allocation_site;
150592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
150602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      allocation_site = site;
150612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    }
150622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
150632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
150642904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        initial_map, NOT_TENURED, true, allocation_site));
15065dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else {
150662904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
150672904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
15068dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    // We might need to transition to holey
15069dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    ElementsKind kind = constructor->initial_map()->elements_kind();
15070dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (holey && !IsFastHoleyElementsKind(kind)) {
15071dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      kind = GetHoleyElementsKind(kind);
150722904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      JSObject::TransitionElementsKind(array, kind);
15073dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
15074dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
15075dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
150762904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
150772904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
15078b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  ElementsKind old_kind = array->GetElementsKind();
150795b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(
150805b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      isolate, ArrayConstructInitializeElements(array, caller_args));
15081b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!site.is_null() &&
15082b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      (old_kind != array->GetElementsKind() ||
15083b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org       !can_use_type_feedback)) {
15084b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // The arguments passed in caused a transition. This kind of complexity
15085b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // can't be dealt with in the inlined hydrogen array constructor case.
15086b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // We must mark the allocationsite as un-inlinable.
15087b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    site->SetDoNotInlineCall();
15088b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
150892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  return *array;
15090dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
15091dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
15092dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
15093a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_ArrayConstructor) {
15094dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  HandleScope scope(isolate);
15095dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // If we get 2 arguments then they are the stub parameters (constructor, type
150960cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // info).  If we get 4, then the first one is a pointer to the arguments
150970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // passed by the caller, and the last one is the length of the arguments
150980cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // passed to the caller (redundant, but useful to check on the deoptimizer
150990cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // with an assert).
15100dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments empty_args(0, NULL);
15101dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool no_caller_args = args.length() == 2;
151020cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  ASSERT(no_caller_args || args.length() == 4);
15103dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int parameters_start = no_caller_args ? 0 : 1;
15104dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments* caller_args = no_caller_args
15105dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ? &empty_args
15106dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      : reinterpret_cast<Arguments*>(args[0]);
15107dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15108dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
151090cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org#ifdef DEBUG
151100cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (!no_caller_args) {
151110cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
151120cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    ASSERT(arg_count == caller_args->length());
151130cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
151140cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org#endif
15115b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
15116b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<AllocationSite> site;
15117b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!type_info.is_null() &&
151185697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org      *type_info != isolate->heap()->undefined_value()) {
151196d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    site = Handle<AllocationSite>::cast(type_info);
15120b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    ASSERT(!site->SitePointsToLiteral());
15121b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
15122b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
15123dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return ArrayConstructorCommon(isolate,
15124dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                constructor,
15125b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                site,
15126dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                caller_args);
15127dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
15128dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
15129dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
15130a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(RuntimeHidden_InternalArrayConstructor) {
15131dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  HandleScope scope(isolate);
15132dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments empty_args(0, NULL);
15133dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  bool no_caller_args = args.length() == 1;
151340cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  ASSERT(no_caller_args || args.length() == 3);
15135dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int parameters_start = no_caller_args ? 0 : 1;
15136dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Arguments* caller_args = no_caller_args
15137dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ? &empty_args
15138dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      : reinterpret_cast<Arguments*>(args[0]);
15139dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
151400cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org#ifdef DEBUG
151410cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (!no_caller_args) {
151420cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
151430cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    ASSERT(arg_count == caller_args->length());
151440cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
151450cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org#endif
15146dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return ArrayConstructorCommon(isolate,
15147dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                constructor,
15148b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                Handle<AllocationSite>::null(),
15149dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org                                caller_args);
15150dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
15151dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
15152e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
15153a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Runtime_MaxSmi) {
151548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  ASSERT(args.length() == 0);
15155ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  return Smi::FromInt(Smi::kMaxValue);
15156ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
15157ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
15158ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1515943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
1516043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Implementation of Runtime
1516143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15162d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com#define F(name, number_of_args, result_size)                             \
15163d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  { Runtime::k##name, Runtime::RUNTIME, #name,   \
15164d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
15165d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
15166d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
151679b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org#define FH(name, number_of_args, result_size)                             \
151689b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  { Runtime::kHidden##name, Runtime::RUNTIME_HIDDEN, NULL,   \
151699b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    FUNCTION_ADDR(RuntimeHidden_##name), number_of_args, result_size },
151709b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
151719b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
15172d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com#define I(name, number_of_args, result_size)                             \
15173d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  { Runtime::kInline##name, Runtime::INLINE,     \
15174d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    "_" #name, NULL, number_of_args, result_size },
1517543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
151769b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
151779b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org#define IO(name, number_of_args, result_size) \
151789b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  { Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, \
151799b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    "_" #name, FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
151809b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
151819b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
15182ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const Runtime::Function kIntrinsicFunctions[] = {
1518343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RUNTIME_FUNCTION_LIST(F)
15184eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  INLINE_OPTIMIZED_FUNCTION_LIST(F)
151859b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  RUNTIME_HIDDEN_FUNCTION_LIST(FH)
15186d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  INLINE_FUNCTION_LIST(I)
151879b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  INLINE_OPTIMIZED_FUNCTION_LIST(IO)
1518843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
1518943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
151909b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org#undef IO
15191ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org#undef I
151929b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org#undef FH
15193ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org#undef F
15194ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1519543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15196c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
15197c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                               Handle<NameDictionary> dict) {
15198c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  ASSERT(dict->NumberOfElements() == 0);
15199c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  HandleScope scope(isolate);
15200d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  for (int i = 0; i < kNumFunctions; ++i) {
152019b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    const char* name = kIntrinsicFunctions[i].name;
152029b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    if (name == NULL) continue;
15203f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<NameDictionary> new_dict = NameDictionary::Add(
15204c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        dict,
15205c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        isolate->factory()->InternalizeUtf8String(name),
15206c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        Handle<Smi>(Smi::FromInt(i), isolate),
15207c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        PropertyDetails(NONE, NORMAL, Representation::None()));
15208c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    // The dictionary does not need to grow.
15209c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    CHECK(new_dict.is_identical_to(dict));
15210d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  }
1521143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1521243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1521343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgconst Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
15215ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = name->GetHeap();
15216f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = heap->intrinsic_function_names()->FindEntry(name);
15217d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  if (entry != kNotFound) {
15218ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
15219d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    int function_index = Smi::cast(smi_index)->value();
15220d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com    return &(kIntrinsicFunctions[function_index]);
1522143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1522243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
1522343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1522443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1522543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15226ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15227d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  return &(kIntrinsicFunctions[static_cast<int>(id)]);
15228d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com}
15229d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
1523043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
15231