1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5(function(global, utils) {
6
7"use strict";
8
9%CheckIsBootstrapping();
10
11// -------------------------------------------------------------------
12// Imports
13
14var GlobalMap = global.Map;
15var GlobalSet = global.Set;
16var iteratorSymbol = utils.ImportNow("iterator_symbol");
17var MapIterator = utils.ImportNow("MapIterator");
18var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
19var SetIterator = utils.ImportNow("SetIterator");
20
21// -------------------------------------------------------------------
22
23function SetIteratorConstructor(set, kind) {
24  %SetIteratorInitialize(this, set, kind);
25}
26
27
28function SetIteratorNextJS() {
29  if (!IS_SET_ITERATOR(this)) {
30    throw %make_type_error(kIncompatibleMethodReceiver,
31                        'Set Iterator.prototype.next', this);
32  }
33
34  var value_array = [UNDEFINED, UNDEFINED];
35  var result = %_CreateIterResultObject(value_array, false);
36  switch (%SetIteratorNext(this, value_array)) {
37    case 0:
38      result.value = UNDEFINED;
39      result.done = true;
40      break;
41    case ITERATOR_KIND_VALUES:
42      result.value = value_array[0];
43      break;
44    case ITERATOR_KIND_ENTRIES:
45      value_array[1] = value_array[0];
46      break;
47  }
48
49  return result;
50}
51
52
53function SetEntries() {
54  if (!IS_SET(this)) {
55    throw %make_type_error(kIncompatibleMethodReceiver,
56                        'Set.prototype.entries', this);
57  }
58  return new SetIterator(this, ITERATOR_KIND_ENTRIES);
59}
60
61
62function SetValues() {
63  if (!IS_SET(this)) {
64    throw %make_type_error(kIncompatibleMethodReceiver,
65                        'Set.prototype.values', this);
66  }
67  return new SetIterator(this, ITERATOR_KIND_VALUES);
68}
69
70// -------------------------------------------------------------------
71
72%SetCode(SetIterator, SetIteratorConstructor);
73%FunctionSetInstanceClassName(SetIterator, 'Set Iterator');
74utils.InstallFunctions(SetIterator.prototype, DONT_ENUM, [
75  'next', SetIteratorNextJS
76]);
77
78%AddNamedProperty(SetIterator.prototype, toStringTagSymbol,
79    "Set Iterator", READ_ONLY | DONT_ENUM);
80
81utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
82  'entries', SetEntries,
83  'keys', SetValues,
84  'values', SetValues
85]);
86
87%AddNamedProperty(GlobalSet.prototype, iteratorSymbol, SetValues, DONT_ENUM);
88
89// -------------------------------------------------------------------
90
91function MapIteratorConstructor(map, kind) {
92  %MapIteratorInitialize(this, map, kind);
93}
94
95
96function MapIteratorNextJS() {
97  if (!IS_MAP_ITERATOR(this)) {
98    throw %make_type_error(kIncompatibleMethodReceiver,
99                        'Map Iterator.prototype.next', this);
100  }
101
102  var value_array = [UNDEFINED, UNDEFINED];
103  var result = %_CreateIterResultObject(value_array, false);
104  switch (%MapIteratorNext(this, value_array)) {
105    case 0:
106      result.value = UNDEFINED;
107      result.done = true;
108      break;
109    case ITERATOR_KIND_KEYS:
110      result.value = value_array[0];
111      break;
112    case ITERATOR_KIND_VALUES:
113      result.value = value_array[1];
114      break;
115    // ITERATOR_KIND_ENTRIES does not need any processing.
116  }
117
118  return result;
119}
120
121
122function MapEntries() {
123  if (!IS_MAP(this)) {
124    throw %make_type_error(kIncompatibleMethodReceiver,
125                        'Map.prototype.entries', this);
126  }
127  return new MapIterator(this, ITERATOR_KIND_ENTRIES);
128}
129
130
131function MapKeys() {
132  if (!IS_MAP(this)) {
133    throw %make_type_error(kIncompatibleMethodReceiver,
134                        'Map.prototype.keys', this);
135  }
136  return new MapIterator(this, ITERATOR_KIND_KEYS);
137}
138
139
140function MapValues() {
141  if (!IS_MAP(this)) {
142    throw %make_type_error(kIncompatibleMethodReceiver,
143                        'Map.prototype.values', this);
144  }
145  return new MapIterator(this, ITERATOR_KIND_VALUES);
146}
147
148// -------------------------------------------------------------------
149
150%SetCode(MapIterator, MapIteratorConstructor);
151%FunctionSetInstanceClassName(MapIterator, 'Map Iterator');
152utils.InstallFunctions(MapIterator.prototype, DONT_ENUM, [
153  'next', MapIteratorNextJS
154]);
155
156%AddNamedProperty(MapIterator.prototype, toStringTagSymbol,
157    "Map Iterator", READ_ONLY | DONT_ENUM);
158
159
160utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
161  'entries', MapEntries,
162  'keys', MapKeys,
163  'values', MapValues
164]);
165
166%AddNamedProperty(GlobalMap.prototype, iteratorSymbol, MapEntries, DONT_ENUM);
167
168// -------------------------------------------------------------------
169// Exports
170
171utils.Export(function(to) {
172  to.MapEntries = MapEntries;
173  to.MapIteratorNext = MapIteratorNextJS;
174  to.SetIteratorNext = SetIteratorNextJS;
175  to.SetValues = SetValues;
176});
177
178})
179