Commit 6eba6b4b authored by binji's avatar binji Committed by Commit bot

Add Isolate parameter to disallow Atomics.wait

Atomics.wait is a function which may block, which is not allowed on the
main thread. Since V8 doesn't know whether a particular isolate is the
"main thread", this CL adds an option to Isolate::CreateParams to choose
whether this function is allowed.

Review-Url: https://codereview.chromium.org/2642293002
Cr-Commit-Position: refs/heads/master@{#42611}
parent 67244dce
......@@ -6345,7 +6345,8 @@ class V8_EXPORT Isolate {
create_histogram_callback(nullptr),
add_histogram_sample_callback(nullptr),
array_buffer_allocator(nullptr),
external_references(nullptr) {}
external_references(nullptr),
allow_atomics_wait(true) {}
/**
* The optional entry_hook allows the host application to provide the
......@@ -6401,6 +6402,12 @@ class V8_EXPORT Isolate {
* entire lifetime of the isolate.
*/
intptr_t* external_references;
/**
* Whether calling Atomics.wait (a function that may block) is allowed in
* this isolate.
*/
bool allow_atomics_wait;
};
......
......@@ -8121,6 +8121,7 @@ Isolate* Isolate::New(const Isolate::CreateParams& params) {
}
isolate->set_api_external_references(params.external_references);
isolate->set_allow_atomics_wait(params.allow_atomics_wait);
SetResourceConstraints(isolate, params.constraints);
// TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
Isolate::Scope isolate_scope(v8_isolate);
......
......@@ -1194,6 +1194,9 @@ class Isolate {
base::Mutex* simulator_i_cache_mutex() { return &simulator_i_cache_mutex_; }
#endif
void set_allow_atomics_wait(bool set) { allow_atomics_wait_ = set; }
bool allow_atomics_wait() { return allow_atomics_wait_; }
protected:
explicit Isolate(bool enable_serializer);
bool IsArrayOrObjectPrototype(Object* object);
......@@ -1472,6 +1475,8 @@ class Isolate {
base::Mutex simulator_i_cache_mutex_;
#endif
bool allow_atomics_wait_;
friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class HeapTester;
......
......@@ -269,6 +269,7 @@ class ErrorUtils : public AllStatic {
"ArrayBuffer subclass returned this from species constructor") \
T(ArrayFunctionsOnFrozen, "Cannot modify frozen array elements") \
T(ArrayFunctionsOnSealed, "Cannot add/remove sealed array elements") \
T(AtomicsWaitNotAllowed, "Atomics.wait cannot be called in this context") \
T(CalledNonCallable, "% is not a function") \
T(CalledOnNonObject, "% called on non-object") \
T(CalledOnNullOrUndefined, "% called on null or undefined") \
......
......@@ -29,6 +29,11 @@ RUNTIME_FUNCTION(Runtime_AtomicsWait) {
CHECK_EQ(sta->type(), kExternalInt32Array);
CHECK(timeout == V8_INFINITY || !std::isnan(timeout));
if (!isolate->allow_atomics_wait()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kAtomicsWaitNotAllowed));
}
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
......@@ -65,5 +70,14 @@ RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
return FutexEmulation::NumWaitersForTesting(isolate, array_buffer, addr);
}
RUNTIME_FUNCTION(Runtime_SetAllowAtomicsWait) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_BOOLEAN_ARG_CHECKED(set, 0);
isolate->set_allow_atomics_wait(set);
return isolate->heap()->undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -73,7 +73,8 @@ namespace internal {
F(AtomicsIsLockFree, 1, 1) \
F(AtomicsWait, 4, 1) \
F(AtomicsWake, 3, 1) \
F(AtomicsNumWaitersForTesting, 2, 1)
F(AtomicsNumWaitersForTesting, 2, 1) \
F(SetAllowAtomicsWait, 1, 1)
#define FOR_EACH_INTRINSIC_CLASSES(F) \
F(ThrowUnsupportedSuperError, 0, 1) \
......
......@@ -88,7 +88,7 @@ bytecodes: [
B(TestEqualStrict), R(12), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(12),
B(LdaConstant), U8(9),
B(Star), R(13),
......@@ -233,7 +233,7 @@ bytecodes: [
B(TestEqualStrict), R(13), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(13),
B(LdaConstant), U8(9),
B(Star), R(14),
......@@ -391,7 +391,7 @@ bytecodes: [
B(TestEqualStrict), R(12), U8(22),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(12),
B(LdaConstant), U8(9),
B(Star), R(13),
......@@ -539,7 +539,7 @@ bytecodes: [
B(TestEqualStrict), R(11), U8(24),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(11),
B(LdaConstant), U8(11),
B(Star), R(12),
......
......@@ -497,7 +497,7 @@ bytecodes: [
B(TestEqualStrict), R(11), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(11),
B(LdaConstant), U8(14),
B(Star), R(12),
......
......@@ -95,6 +95,15 @@
assertEquals("timed-out", Atomics.wait(i32a, 0, 0, -Infinity));
})();
(function TestWaitNotAllowed() {
%SetAllowAtomicsWait(false);
var i32a = new Int32Array(new SharedArrayBuffer(16));
assertThrows(function() {
Atomics.wait(i32a, 0, 0, -1);
});
%SetAllowAtomicsWait(true);
})();
//// WORKER ONLY TESTS
if (this.Worker) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment