OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 break; | 139 break; |
140 case v8::Isolate::kMessageError: | 140 case v8::Isolate::kMessageError: |
141 level = InfoMessageLevel; | 141 level = InfoMessageLevel; |
142 break; | 142 break; |
143 default: | 143 default: |
144 NOTREACHED(); | 144 NOTREACHED(); |
145 } | 145 } |
146 return level; | 146 return level; |
147 } | 147 } |
148 | 148 |
| 149 // NOTE: when editing this, please also edit the error messages we throw when |
| 150 // the size is exceeded (see uses of the constant), which use the human-friendly |
| 151 // "4KB" text. |
149 const size_t kWasmWireBytesLimit = 1 << 12; | 152 const size_t kWasmWireBytesLimit = 1 << 12; |
150 | 153 |
151 } // namespace | 154 } // namespace |
152 | 155 |
153 void V8Initializer::messageHandlerInMainThread(v8::Local<v8::Message> message, | 156 void V8Initializer::messageHandlerInMainThread(v8::Local<v8::Message> message, |
154 v8::Local<v8::Value> data) { | 157 v8::Local<v8::Value> data) { |
155 ASSERT(isMainThread()); | 158 ASSERT(isMainThread()); |
156 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 159 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
157 | 160 |
158 if (isolate->GetEnteredContext().IsEmpty()) | 161 if (isolate->GetEnteredContext().IsEmpty()) |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 if (ExecutionContext* executionContext = toExecutionContext(context)) { | 321 if (ExecutionContext* executionContext = toExecutionContext(context)) { |
319 if (ContentSecurityPolicy* policy = | 322 if (ContentSecurityPolicy* policy = |
320 toDocument(executionContext)->contentSecurityPolicy()) | 323 toDocument(executionContext)->contentSecurityPolicy()) |
321 return policy->allowEval(ScriptState::from(context), | 324 return policy->allowEval(ScriptState::from(context), |
322 SecurityViolationReportingPolicy::Report, | 325 SecurityViolationReportingPolicy::Report, |
323 ContentSecurityPolicy::WillThrowException); | 326 ContentSecurityPolicy::WillThrowException); |
324 } | 327 } |
325 return false; | 328 return false; |
326 } | 329 } |
327 | 330 |
328 static bool allowWasmCompileCallbackInMainThread(v8::Isolate* isolate, | 331 v8::Local<v8::Value> newRangeException(v8::Isolate* isolate, |
329 v8::Local<v8::Value> source, | 332 const char* message) { |
330 bool asPromise) { | 333 return v8::Exception::RangeError( |
331 // We allow async compilation irrespective of buffer size. | 334 v8::String::NewFromOneByte(isolate, |
332 if (asPromise) | 335 reinterpret_cast<const uint8_t*>(message), |
333 return true; | 336 v8::NewStringType::kNormal) |
334 if (source->IsArrayBuffer() && | 337 .ToLocalChecked()); |
335 v8::Local<v8::ArrayBuffer>::Cast(source)->ByteLength() > | |
336 kWasmWireBytesLimit) { | |
337 return false; | |
338 } | |
339 if (source->IsArrayBufferView() && | |
340 v8::Local<v8::ArrayBufferView>::Cast(source)->ByteLength() > | |
341 kWasmWireBytesLimit) { | |
342 return false; | |
343 } | |
344 return true; | |
345 } | 338 } |
346 | 339 |
347 static bool allowWasmInstantiateCallbackInMainThread( | 340 void throwRangeException(v8::Isolate* isolate, const char* message) { |
348 v8::Isolate* isolate, | 341 isolate->ThrowException(newRangeException(isolate, message)); |
349 v8::Local<v8::Value> source, | 342 } |
350 v8::MaybeLocal<v8::Value> ffi, | 343 |
351 bool asPromise) { | 344 static bool wasmModuleOverride( |
352 // Async cases are allowed, regardless of the size of the | 345 const v8::FunctionCallbackInfo<v8::Value>& args) { |
353 // wire bytes. Note that, for instantiation, we use the wire | 346 // Return false if we want the base behavior to proceed. |
354 // bytes size as a proxy for instantiation time. We may | 347 if (!WTF::isMainThread() || args.Length() < 1) |
355 // consider using the size of the ffi (nr of properties) | 348 return false; |
356 // instead, or, even more directly, number of imports. | 349 v8::Local<v8::Value> source = args[0]; |
357 if (asPromise) | 350 if ((source->IsArrayBuffer() && |
| 351 v8::Local<v8::ArrayBuffer>::Cast(source)->ByteLength() > |
| 352 kWasmWireBytesLimit) || |
| 353 (source->IsArrayBufferView() && |
| 354 v8::Local<v8::ArrayBufferView>::Cast(source)->ByteLength() > |
| 355 kWasmWireBytesLimit)) { |
| 356 throwRangeException(args.GetIsolate(), |
| 357 "WebAssembly.Compile is disallowed on the main thread, " |
| 358 "if the buffer size is larger than 4KB. Use " |
| 359 "WebAssembly.compile, or compile on a worker thread."); |
| 360 // Return true because we injected new behavior and we do not |
| 361 // want the default behavior. |
358 return true; | 362 return true; |
359 // If it's not a promise, the source should be a wasm module | 363 } |
360 DCHECK(source->IsWebAssemblyCompiledModule()); | 364 return false; |
| 365 } |
| 366 |
| 367 static bool wasmInstanceOverride( |
| 368 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 369 // Return false if we want the base behavior to proceed. |
| 370 if (!WTF::isMainThread() || args.Length() < 1) |
| 371 return false; |
| 372 v8::Local<v8::Value> source = args[0]; |
| 373 if (!source->IsWebAssemblyCompiledModule()) |
| 374 return false; |
| 375 |
361 v8::Local<v8::WasmCompiledModule> module = | 376 v8::Local<v8::WasmCompiledModule> module = |
362 v8::Local<v8::WasmCompiledModule>::Cast(source); | 377 v8::Local<v8::WasmCompiledModule>::Cast(source); |
363 if (static_cast<size_t>(module->GetWasmWireBytes()->Length()) > | 378 if (static_cast<size_t>(module->GetWasmWireBytes()->Length()) > |
364 kWasmWireBytesLimit) { | 379 kWasmWireBytesLimit) { |
365 return false; | 380 throwRangeException( |
| 381 args.GetIsolate(), |
| 382 "WebAssembly.Instance is disallowed on the main thread, " |
| 383 "if the buffer size is larger than 4KB. Use " |
| 384 "WebAssembly.instantiate."); |
| 385 return true; |
366 } | 386 } |
367 return true; | 387 return false; |
368 } | 388 } |
369 | 389 |
370 static void initializeV8Common(v8::Isolate* isolate) { | 390 static void initializeV8Common(v8::Isolate* isolate) { |
371 isolate->AddGCPrologueCallback(V8GCController::gcPrologue); | 391 isolate->AddGCPrologueCallback(V8GCController::gcPrologue); |
372 isolate->AddGCEpilogueCallback(V8GCController::gcEpilogue); | 392 isolate->AddGCEpilogueCallback(V8GCController::gcEpilogue); |
373 std::unique_ptr<ScriptWrappableVisitor> visitor( | 393 std::unique_ptr<ScriptWrappableVisitor> visitor( |
374 new ScriptWrappableVisitor(isolate)); | 394 new ScriptWrappableVisitor(isolate)); |
375 V8PerIsolateData::from(isolate)->setScriptWrappableVisitor( | 395 V8PerIsolateData::from(isolate)->setScriptWrappableVisitor( |
376 std::move(visitor)); | 396 std::move(visitor)); |
377 isolate->SetEmbedderHeapTracer( | 397 isolate->SetEmbedderHeapTracer( |
378 V8PerIsolateData::from(isolate)->scriptWrappableVisitor()); | 398 V8PerIsolateData::from(isolate)->scriptWrappableVisitor()); |
379 | 399 |
380 isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped); | 400 isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped); |
381 | 401 |
382 isolate->SetUseCounterCallback(&useCounterCallback); | 402 isolate->SetUseCounterCallback(&useCounterCallback); |
| 403 isolate->SetWasmModuleCallback(wasmModuleOverride); |
| 404 isolate->SetWasmInstanceCallback(wasmInstanceOverride); |
383 } | 405 } |
384 | 406 |
385 namespace { | 407 namespace { |
386 | 408 |
387 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { | 409 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { |
388 // Allocate() methods return null to signal allocation failure to V8, which | 410 // Allocate() methods return null to signal allocation failure to V8, which |
389 // should respond by throwing a RangeError, per | 411 // should respond by throwing a RangeError, per |
390 // http://www.ecma-international.org/ecma-262/6.0/#sec-createbytedatablock. | 412 // http://www.ecma-international.org/ecma-262/6.0/#sec-createbytedatablock. |
391 void* Allocate(size_t size) override { | 413 void* Allocate(size_t size) override { |
392 return WTF::ArrayBufferContents::allocateMemoryOrNull( | 414 return WTF::ArrayBufferContents::allocateMemoryOrNull( |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 isolate->SetFatalErrorHandler(reportFatalErrorInMainThread); | 471 isolate->SetFatalErrorHandler(reportFatalErrorInMainThread); |
450 isolate->AddMessageListenerWithErrorLevel( | 472 isolate->AddMessageListenerWithErrorLevel( |
451 messageHandlerInMainThread, | 473 messageHandlerInMainThread, |
452 v8::Isolate::kMessageError | v8::Isolate::kMessageWarning | | 474 v8::Isolate::kMessageError | v8::Isolate::kMessageWarning | |
453 v8::Isolate::kMessageInfo | v8::Isolate::kMessageDebug | | 475 v8::Isolate::kMessageInfo | v8::Isolate::kMessageDebug | |
454 v8::Isolate::kMessageLog); | 476 v8::Isolate::kMessageLog); |
455 isolate->SetFailedAccessCheckCallbackFunction( | 477 isolate->SetFailedAccessCheckCallbackFunction( |
456 failedAccessCheckCallbackInMainThread); | 478 failedAccessCheckCallbackInMainThread); |
457 isolate->SetAllowCodeGenerationFromStringsCallback( | 479 isolate->SetAllowCodeGenerationFromStringsCallback( |
458 codeGenerationCheckCallbackInMainThread); | 480 codeGenerationCheckCallbackInMainThread); |
459 isolate->SetAllowWasmCompileCallback(allowWasmCompileCallbackInMainThread); | |
460 isolate->SetAllowWasmInstantiateCallback( | |
461 allowWasmInstantiateCallbackInMainThread); | |
462 if (RuntimeEnabledFeatures::v8IdleTasksEnabled()) { | 481 if (RuntimeEnabledFeatures::v8IdleTasksEnabled()) { |
463 V8PerIsolateData::enableIdleTasks( | 482 V8PerIsolateData::enableIdleTasks( |
464 isolate, WTF::makeUnique<V8IdleTaskRunner>(scheduler)); | 483 isolate, WTF::makeUnique<V8IdleTaskRunner>(scheduler)); |
465 } | 484 } |
466 | 485 |
467 isolate->SetPromiseRejectCallback(promiseRejectHandlerInMainThread); | 486 isolate->SetPromiseRejectCallback(promiseRejectHandlerInMainThread); |
468 | 487 |
469 if (v8::HeapProfiler* profiler = isolate->GetHeapProfiler()) { | 488 if (v8::HeapProfiler* profiler = isolate->GetHeapProfiler()) { |
470 profiler->SetWrapperClassInfoProvider( | 489 profiler->SetWrapperClassInfoProvider( |
471 WrapperTypeInfo::NodeClassId, &RetainedDOMInfo::createRetainedDOMInfo); | 490 WrapperTypeInfo::NodeClassId, &RetainedDOMInfo::createRetainedDOMInfo); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 v8::Isolate::kMessageLog); | 577 v8::Isolate::kMessageLog); |
559 isolate->SetFatalErrorHandler(reportFatalErrorInWorker); | 578 isolate->SetFatalErrorHandler(reportFatalErrorInWorker); |
560 | 579 |
561 uint32_t here; | 580 uint32_t here; |
562 isolate->SetStackLimit(reinterpret_cast<uintptr_t>(&here) - | 581 isolate->SetStackLimit(reinterpret_cast<uintptr_t>(&here) - |
563 kWorkerMaxStackSize); | 582 kWorkerMaxStackSize); |
564 isolate->SetPromiseRejectCallback(promiseRejectHandlerInWorker); | 583 isolate->SetPromiseRejectCallback(promiseRejectHandlerInWorker); |
565 } | 584 } |
566 | 585 |
567 } // namespace blink | 586 } // namespace blink |
OLD | NEW |