• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 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 GlobalObject = global.Object;
15var MakeTypeError;
16var MaxSimple;
17var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
18
19utils.Import(function(from) {
20  MakeTypeError = from.MakeTypeError;
21  MaxSimple = from.MaxSimple;
22});
23
24// -------------------------------------------------------------------
25
26
27function CheckSharedIntegerTypedArray(ia) {
28  if (!%IsSharedIntegerTypedArray(ia)) {
29    throw MakeTypeError(kNotIntegerSharedTypedArray, ia);
30  }
31}
32
33function CheckSharedInteger32TypedArray(ia) {
34  CheckSharedIntegerTypedArray(ia);
35  if (!%IsSharedInteger32TypedArray(ia)) {
36    throw MakeTypeError(kNotInt32SharedTypedArray, ia);
37  }
38}
39
40//-------------------------------------------------------------------
41
42function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
43  CheckSharedIntegerTypedArray(sta);
44  index = TO_INTEGER(index);
45  if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
46    return UNDEFINED;
47  }
48  oldValue = TO_NUMBER(oldValue);
49  newValue = TO_NUMBER(newValue);
50  return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
51}
52
53function AtomicsLoadJS(sta, index) {
54  CheckSharedIntegerTypedArray(sta);
55  index = TO_INTEGER(index);
56  if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
57    return UNDEFINED;
58  }
59  return %_AtomicsLoad(sta, index);
60}
61
62function AtomicsStoreJS(sta, index, value) {
63  CheckSharedIntegerTypedArray(sta);
64  index = TO_INTEGER(index);
65  if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
66    return UNDEFINED;
67  }
68  value = TO_NUMBER(value);
69  return %_AtomicsStore(sta, index, value);
70}
71
72function AtomicsAddJS(ia, index, value) {
73  CheckSharedIntegerTypedArray(ia);
74  index = TO_INTEGER(index);
75  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
76    return UNDEFINED;
77  }
78  value = TO_NUMBER(value);
79  return %_AtomicsAdd(ia, index, value);
80}
81
82function AtomicsSubJS(ia, index, value) {
83  CheckSharedIntegerTypedArray(ia);
84  index = TO_INTEGER(index);
85  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
86    return UNDEFINED;
87  }
88  value = TO_NUMBER(value);
89  return %_AtomicsSub(ia, index, value);
90}
91
92function AtomicsAndJS(ia, index, value) {
93  CheckSharedIntegerTypedArray(ia);
94  index = TO_INTEGER(index);
95  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
96    return UNDEFINED;
97  }
98  value = TO_NUMBER(value);
99  return %_AtomicsAnd(ia, index, value);
100}
101
102function AtomicsOrJS(ia, index, value) {
103  CheckSharedIntegerTypedArray(ia);
104  index = TO_INTEGER(index);
105  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
106    return UNDEFINED;
107  }
108  value = TO_NUMBER(value);
109  return %_AtomicsOr(ia, index, value);
110}
111
112function AtomicsXorJS(ia, index, value) {
113  CheckSharedIntegerTypedArray(ia);
114  index = TO_INTEGER(index);
115  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
116    return UNDEFINED;
117  }
118  value = TO_NUMBER(value);
119  return %_AtomicsXor(ia, index, value);
120}
121
122function AtomicsExchangeJS(ia, index, value) {
123  CheckSharedIntegerTypedArray(ia);
124  index = TO_INTEGER(index);
125  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
126    return UNDEFINED;
127  }
128  value = TO_NUMBER(value);
129  return %_AtomicsExchange(ia, index, value);
130}
131
132function AtomicsIsLockFreeJS(size) {
133  return %_AtomicsIsLockFree(size);
134}
135
136// Futexes
137
138function AtomicsFutexWaitJS(ia, index, value, timeout) {
139  CheckSharedInteger32TypedArray(ia);
140  index = TO_INTEGER(index);
141  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
142    return UNDEFINED;
143  }
144  if (IS_UNDEFINED(timeout)) {
145    timeout = INFINITY;
146  } else {
147    timeout = TO_NUMBER(timeout);
148    if (NUMBER_IS_NAN(timeout)) {
149      timeout = INFINITY;
150    } else {
151      timeout = MaxSimple(0, timeout);
152    }
153  }
154  return %AtomicsFutexWait(ia, index, value, timeout);
155}
156
157function AtomicsFutexWakeJS(ia, index, count) {
158  CheckSharedInteger32TypedArray(ia);
159  index = TO_INTEGER(index);
160  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
161    return UNDEFINED;
162  }
163  count = MaxSimple(0, TO_INTEGER(count));
164  return %AtomicsFutexWake(ia, index, count);
165}
166
167function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
168  CheckSharedInteger32TypedArray(ia);
169  index1 = TO_INTEGER(index1);
170  count = MaxSimple(0, TO_INTEGER(count));
171  value = TO_INT32(value);
172  index2 = TO_INTEGER(index2);
173  if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||
174      index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) {
175    return UNDEFINED;
176  }
177  return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2);
178}
179
180// -------------------------------------------------------------------
181
182function AtomicsConstructor() {}
183
184var Atomics = new AtomicsConstructor();
185
186%InternalSetPrototype(Atomics, GlobalObject.prototype);
187%AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM);
188%FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics');
189
190%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
191
192// These must match the values in src/futex-emulation.h
193utils.InstallConstants(Atomics, [
194  "OK", 0,
195  "NOTEQUAL", -1,
196  "TIMEDOUT", -2,
197]);
198
199utils.InstallFunctions(Atomics, DONT_ENUM, [
200  "compareExchange", AtomicsCompareExchangeJS,
201  "load", AtomicsLoadJS,
202  "store", AtomicsStoreJS,
203  "add", AtomicsAddJS,
204  "sub", AtomicsSubJS,
205  "and", AtomicsAndJS,
206  "or", AtomicsOrJS,
207  "xor", AtomicsXorJS,
208  "exchange", AtomicsExchangeJS,
209  "isLockFree", AtomicsIsLockFreeJS,
210  "futexWait", AtomicsFutexWaitJS,
211  "futexWake", AtomicsFutexWakeJS,
212  "futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS,
213]);
214
215})
216