| 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 |