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