From 6ea922cd8edf3c44bf49a5b4fd5e58bfc5985640 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa <arai_a@mac.com> Date: Wed, 31 May 2023 01:26:44 +0000 Subject: [PATCH] Bug 1834483 - Part 1: Add NativeStackLimit field to FrontendContext. r=bthrall Differential Revision: https://phabricator.services.mozilla.com/D179002 --- js/public/Stack.h | 7 +++++++ js/src/frontend/FrontendContext.cpp | 14 ++++++++++++++ js/src/frontend/FrontendContext.h | 13 ++++++++++--- js/src/jsapi.cpp | 5 +---- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/js/public/Stack.h b/js/public/Stack.h index 061b28396cd0c..6f01b2b7289eb 100644 --- a/js/public/Stack.h +++ b/js/public/Stack.h @@ -36,6 +36,13 @@ constexpr NativeStackLimit NativeStackLimitMin = UINTPTR_MAX; constexpr NativeStackLimit NativeStackLimitMax = 0; #endif +#ifdef __wasi__ +// We build with the "stack-first" wasm-ld option, so the stack grows downward +// toward zero. Let's set a limit just a bit above this so that we catch an +// overflow before a Wasm trap occurs. +constexpr NativeStackLimit WASINativeStackLimit = 1024; +#endif // __wasi__ + inline NativeStackLimit GetNativeStackLimit(NativeStackBase base, NativeStackSize size) { #if JS_STACK_GROWTH_DIRECTION > 0 diff --git a/js/src/frontend/FrontendContext.cpp b/js/src/frontend/FrontendContext.cpp index 979b7e95c6a12..312d265ae01cf 100644 --- a/js/src/frontend/FrontendContext.cpp +++ b/js/src/frontend/FrontendContext.cpp @@ -11,6 +11,7 @@ #include "js/friend/StackLimits.h" // js::ReportOverRecursed #include "js/Modules.h" #include "util/DifferentialTesting.h" +#include "util/NativeStack.h" // GetNativeStackBase #include "vm/JSContext.h" using namespace js; @@ -42,6 +43,18 @@ bool FrontendContext::setSupportedImportAssertions( return true; } +void FrontendContext::setStackQuota(JS::NativeStackSize stackSize) { +#ifdef __wasi__ + stackLimit_ = JS::WASINativeStackLimit; +#else // __wasi__ + if (stackSize == 0) { + stackLimit_ = JS::NativeStackLimitMax; + } else { + stackLimit_ = JS::GetNativeStackLimit(GetNativeStackBase(), stackSize - 1); + } +#endif // !__wasi__ +} + bool FrontendContext::allocateOwnedPool() { MOZ_ASSERT(!nameCollectionPool_); @@ -137,6 +150,7 @@ void FrontendContext::setCurrentJSContext(JSContext* cx) { maybeCx_ = cx; nameCollectionPool_ = &cx->frontendCollectionPool(); scriptDataTableHolder_ = &cx->runtime()->scriptDataTableHolder(); + stackLimit_ = cx->stackLimitForCurrentPrincipal(); } void FrontendContext::convertToRuntimeError( diff --git a/js/src/frontend/FrontendContext.h b/js/src/frontend/FrontendContext.h index 247864465badb..d9db91fabfb81 100644 --- a/js/src/frontend/FrontendContext.h +++ b/js/src/frontend/FrontendContext.h @@ -13,9 +13,10 @@ #include <stddef.h> // size_t -#include "js/AllocPolicy.h" // SystemAllocPolicy, AllocFunction -#include "js/ErrorReport.h" // JSErrorCallback, JSErrorFormatString -#include "js/Modules.h" // JS::ImportAssertionVector +#include "js/AllocPolicy.h" // SystemAllocPolicy, AllocFunction +#include "js/ErrorReport.h" // JSErrorCallback, JSErrorFormatString +#include "js/Modules.h" // JS::ImportAssertionVector +#include "js/Stack.h" // JS::NativeStackSize, JS::NativeStackLimit, JS::NativeStackLimitMax #include "js/Vector.h" // Vector #include "vm/ErrorReporting.h" // CompileError #include "vm/MallocProvider.h" // MallocProvider @@ -73,6 +74,8 @@ class FrontendContext { JS::ImportAssertionVector supportedImportAssertions_; + JS::NativeStackLimit stackLimit_ = JS::NativeStackLimitMax; + protected: // (optional) Current JSContext to support main-thread-specific // handling for error reporting, GC, and memory allocation. @@ -89,6 +92,9 @@ class FrontendContext { supportedImportAssertions_() {} ~FrontendContext(); + void setStackQuota(JS::NativeStackSize stackSize); + JS::NativeStackLimit stackLimit() const { return stackLimit_; } + bool allocateOwnedPool(); frontend::NameCollectionPool& nameCollectionPool() { @@ -109,6 +115,7 @@ class FrontendContext { // * js::frontend::NameCollectionPool for reusing allocation // * js::SharedScriptDataTableHolder for de-duplicating bytecode // within given runtime + // * Copy the native stack limit from the JSContext // // And also this JSContext can be retrieved by maybeCurrentJSContext below. void setCurrentJSContext(JSContext* cx); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 1fc92856427a4..90ba9bcf0857c 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1471,10 +1471,7 @@ JS_GetExternalStringCallbacks(JSString* str) { static void SetNativeStackSize(JSContext* cx, JS::StackKind kind, JS::NativeStackSize stackSize) { #ifdef __wasi__ - // WASI makes this easy: we build with the "stack-first" wasm-ld option, so - // the stack grows downward toward zero. Let's set a limit just a bit above - // this so that we catch an overflow before a Wasm trap occurs. - cx->nativeStackLimit[kind] = 1024; + cx->nativeStackLimit[kind] = JS::WASINativeStackLimit; #else // __wasi__ if (stackSize == 0) { cx->nativeStackLimit[kind] = JS::NativeStackLimitMax; -- GitLab