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