• 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 MaxSimple;
16var MinSimple;
17var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
18
19utils.Import(function(from) {
20  MaxSimple = from.MaxSimple;
21  MinSimple = from.MinSimple;
22});
23
24// -------------------------------------------------------------------
25
26
27function CheckSharedIntegerTypedArray(ia) {
28  if (!%IsSharedIntegerTypedArray(ia)) {
29    throw %make_type_error(kNotIntegerSharedTypedArray, ia);
30  }
31}
32
33function CheckSharedInteger32TypedArray(ia) {
34  CheckSharedIntegerTypedArray(ia);
35  if (!%IsSharedInteger32TypedArray(ia)) {
36    throw %make_type_error(kNotInt32SharedTypedArray, ia);
37  }
38}
39
40// https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess
41function ValidateIndex(index, length) {
42  var numberIndex = TO_NUMBER(index);
43  var accessIndex = TO_INTEGER(numberIndex);
44  if (numberIndex !== accessIndex) {
45    throw %make_range_error(kInvalidAtomicAccessIndex);
46  }
47  if (accessIndex < 0 || accessIndex >= length) {
48    throw %make_range_error(kInvalidAtomicAccessIndex);
49  }
50  return accessIndex;
51}
52
53//-------------------------------------------------------------------
54
55function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
56  CheckSharedIntegerTypedArray(sta);
57  index = ValidateIndex(index, %_TypedArrayGetLength(sta));
58  oldValue = TO_NUMBER(oldValue);
59  newValue = TO_NUMBER(newValue);
60  return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
61}
62
63function AtomicsAddJS(ia, index, value) {
64  CheckSharedIntegerTypedArray(ia);
65  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
66  value = TO_NUMBER(value);
67  return %_AtomicsAdd(ia, index, value);
68}
69
70function AtomicsSubJS(ia, index, value) {
71  CheckSharedIntegerTypedArray(ia);
72  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
73  value = TO_NUMBER(value);
74  return %_AtomicsSub(ia, index, value);
75}
76
77function AtomicsAndJS(ia, index, value) {
78  CheckSharedIntegerTypedArray(ia);
79  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
80  value = TO_NUMBER(value);
81  return %_AtomicsAnd(ia, index, value);
82}
83
84function AtomicsOrJS(ia, index, value) {
85  CheckSharedIntegerTypedArray(ia);
86  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
87  value = TO_NUMBER(value);
88  return %_AtomicsOr(ia, index, value);
89}
90
91function AtomicsXorJS(ia, index, value) {
92  CheckSharedIntegerTypedArray(ia);
93  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
94  value = TO_NUMBER(value);
95  return %_AtomicsXor(ia, index, value);
96}
97
98function AtomicsExchangeJS(ia, index, value) {
99  CheckSharedIntegerTypedArray(ia);
100  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
101  value = TO_NUMBER(value);
102  return %_AtomicsExchange(ia, index, value);
103}
104
105function AtomicsIsLockFreeJS(size) {
106  return %_AtomicsIsLockFree(TO_INTEGER(size));
107}
108
109function AtomicsWaitJS(ia, index, value, timeout) {
110  CheckSharedInteger32TypedArray(ia);
111  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
112  if (IS_UNDEFINED(timeout)) {
113    timeout = INFINITY;
114  } else {
115    timeout = TO_NUMBER(timeout);
116    if (NUMBER_IS_NAN(timeout)) {
117      timeout = INFINITY;
118    } else {
119      timeout = MaxSimple(0, timeout);
120    }
121  }
122  return %AtomicsWait(ia, index, value, timeout);
123}
124
125function AtomicsWakeJS(ia, index, count) {
126  CheckSharedInteger32TypedArray(ia);
127  index = ValidateIndex(index, %_TypedArrayGetLength(ia));
128  if (IS_UNDEFINED(count)) {
129    count = kMaxUint32;
130  } else {
131    // Clamp to [0, kMaxUint32].
132    count = MinSimple(MaxSimple(0, TO_INTEGER(count)), kMaxUint32);
133  }
134  return %AtomicsWake(ia, index, count);
135}
136
137// -------------------------------------------------------------------
138
139var Atomics = global.Atomics;
140
141// The Atomics global is defined by the bootstrapper.
142
143%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
144
145utils.InstallFunctions(Atomics, DONT_ENUM, [
146  // TODO(binji): remove the rest of the (non futex) Atomics functions as they
147  // become builtins.
148  "compareExchange", AtomicsCompareExchangeJS,
149  "add", AtomicsAddJS,
150  "sub", AtomicsSubJS,
151  "and", AtomicsAndJS,
152  "or", AtomicsOrJS,
153  "xor", AtomicsXorJS,
154  "exchange", AtomicsExchangeJS,
155  "isLockFree", AtomicsIsLockFreeJS,
156  "wait", AtomicsWaitJS,
157  "wake", AtomicsWakeJS,
158]);
159
160})
161