Skip to content

Commit

Permalink
[MERGE #4503 @thomasmo] 18-01 Security Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Moore (CHAKRA) committed Jan 5, 2018
2 parents c6d73ba + 7b59f02 commit e02b39a
Show file tree
Hide file tree
Showing 46 changed files with 480 additions and 163 deletions.
2 changes: 1 addition & 1 deletion Build/NuGet/.pack-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.5
1.7.6
8 changes: 4 additions & 4 deletions lib/Backend/BailOut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ BailOutRecord::RestoreValue(IR::BailOutKind bailOutKind, Js::JavascriptCallStack
if (boxStackInstance)
{
Js::Var oldValue = value;
value = Js::JavascriptOperators::BoxStackInstance(oldValue, scriptContext, /* allowStackFunction */ true);
value = Js::JavascriptOperators::BoxStackInstance(oldValue, scriptContext, /* allowStackFunction */ true, /* deepCopy */ false);

if (oldValue != value)
{
Expand Down Expand Up @@ -1275,7 +1275,7 @@ BailOutRecord::BailOutInlinedHelper(Js::JavascriptCallStackLayout * layout, Bail
if (inlineeFrameRecord)
{
InlinedFrameLayout* outerMostFrame = (InlinedFrameLayout *)(((uint8 *)Js::JavascriptCallStackLayout::ToFramePointer(layout)) - entryPointInfo->frameHeight);
inlineeFrameRecord->RestoreFrames(functionBody, outerMostFrame, layout);
inlineeFrameRecord->RestoreFrames(functionBody, outerMostFrame, layout, false /* deepCopy */);
}
}

Expand Down Expand Up @@ -1480,7 +1480,7 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
{
const Js::Var arg = args.Values[i];
BAILOUT_VERBOSE_TRACE(executeFunction, bailOutKind, _u("BailOut: Argument #%3u: value: 0x%p"), i, arg);
const Js::Var boxedArg = Js::JavascriptOperators::BoxStackInstance(arg, functionScriptContext, true);
const Js::Var boxedArg = Js::JavascriptOperators::BoxStackInstance(arg, functionScriptContext, /* allowStackFunction */ true, /* deepCopy */ false);
if(boxedArg != arg)
{
args.Values[i] = boxedArg;
Expand Down Expand Up @@ -1775,7 +1775,7 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
aReturn = Js::JavascriptFunction::FinishConstructor(aReturn, args.Values[0], function);

Js::Var oldValue = aReturn;
aReturn = Js::JavascriptOperators::BoxStackInstance(oldValue, functionScriptContext, /* allowStackFunction */ true);
aReturn = Js::JavascriptOperators::BoxStackInstance(oldValue, functionScriptContext, /* allowStackFunction */ true, /* deepCopy */ false);
#if ENABLE_DEBUG_CONFIG_OPTIONS
if (oldValue != aReturn)
{
Expand Down
59 changes: 38 additions & 21 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2859,7 +2859,7 @@ GlobOpt::OptTagChecks(IR::Instr *instr)

if (valueType.CanBeTaggedValue() &&
!valueType.HasBeenNumber() &&
(this->IsLoopPrePass() || !this->currentBlock->loop))
!this->IsLoopPrePass())
{
ValueType newValueType = valueType.SetCanBeTaggedValue(false);

Expand All @@ -2883,7 +2883,16 @@ GlobOpt::OptTagChecks(IR::Instr *instr)
bailOutInstr->SetSrc1(srcOpnd);
bailOutInstr->GetSrc1()->SetValueType(valueType);
instr->InsertBefore(bailOutInstr);

if (this->currentBlock->loop)
{
// Try hoisting the BailOnNotObject instr.
// But since this isn't the current instr being optimized, we need to play tricks with
// the byteCodeUse fields...
TrackByteCodeUsesForInstrAddedInOptInstr(bailOutInstr, [&]()
{
TryHoistInvariant(bailOutInstr, this->currentBlock, nullptr, value, nullptr, true, false, false, IR::BailOutOnTaggedValue);
});
}
if (symOpnd)
{
symOpnd->SetPropertyOwnerValueType(newValueType);
Expand Down Expand Up @@ -3968,25 +3977,10 @@ GlobOpt::CopyPropReplaceOpnd(IR::Instr * instr, IR::Opnd * opnd, StackSym * copy
// Try hoisting this checkObjType.
// But since this isn't the current instr being optimized, we need to play tricks with
// the byteCodeUse fields...
BVSparse<JitArenaAllocator> *currentBytecodeUses = this->byteCodeUses;
PropertySym * currentPropertySymUse = this->propertySymUse;
PropertySym * tempPropertySymUse = NULL;
this->byteCodeUses = NULL;
BVSparse<JitArenaAllocator> *tempByteCodeUse = JitAnew(this->tempAlloc, BVSparse<JitArenaAllocator>, this->tempAlloc);
#if DBG
BVSparse<JitArenaAllocator> *currentBytecodeUsesBeforeOpt = this->byteCodeUsesBeforeOpt;
this->byteCodeUsesBeforeOpt = tempByteCodeUse;
#endif
this->propertySymUse = NULL;
GlobOpt::TrackByteCodeSymUsed(checkObjTypeInstr, tempByteCodeUse, &tempPropertySymUse);

TryHoistInvariant(checkObjTypeInstr, this->currentBlock, NULL, CurrentBlockData()->FindValue(copySym), NULL, true);

this->byteCodeUses = currentBytecodeUses;
this->propertySymUse = currentPropertySymUse;
#if DBG
this->byteCodeUsesBeforeOpt = currentBytecodeUsesBeforeOpt;
#endif
TrackByteCodeUsesForInstrAddedInOptInstr(checkObjTypeInstr, [&]()
{
TryHoistInvariant(checkObjTypeInstr, this->currentBlock, NULL, CurrentBlockData()->FindValue(copySym), NULL, true);
});
}
}
}
Expand Down Expand Up @@ -7072,6 +7066,18 @@ GlobOpt::OptConstFoldUnary(
this->ToFloat64Dst(instr, dst->AsRegOpnd(), this->currentBlock);
}
}

// If this is an induction variable, then treat it the way the prepass would have if it had seen
// the assignment and the resulting change to the value number, and mark it as indeterminate.
for (Loop * loop = this->currentBlock->loop; loop; loop = loop->parent)
{
InductionVariable *iv = nullptr;
if (loop->inductionVariables && loop->inductionVariables->TryGetReference(dstSym->m_id, &iv))
{
iv->SetChangeIsIndeterminate();
}
}

return true;
}

Expand Down Expand Up @@ -12391,6 +12397,17 @@ GlobOpt::OptConstFoldBinary(
this->ToInt32Dst(instr, dst->AsRegOpnd(), this->currentBlock);
}

// If this is an induction variable, then treat it the way the prepass would have if it had seen
// the assignment and the resulting change to the value number, and mark it as indeterminate.
for (Loop * loop = this->currentBlock->loop; loop; loop = loop->parent)
{
InductionVariable *iv = nullptr;
if (loop->inductionVariables && loop->inductionVariables->TryGetReference(dstSym->m_id, &iv))
{
iv->SetChangeIsIndeterminate();
}
}

return true;
}

Expand Down
23 changes: 23 additions & 0 deletions lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,29 @@ class GlobOpt
bool DoPowIntIntTypeSpec() const;
bool DoTagChecks() const;

template <class Fn>
void TrackByteCodeUsesForInstrAddedInOptInstr(IR::Instr * trackByteCodeUseOnInstr, Fn fn)
{
BVSparse<JitArenaAllocator> *currentBytecodeUses = this->byteCodeUses;
PropertySym * currentPropertySymUse = this->propertySymUse;
PropertySym * tempPropertySymUse = NULL;
this->byteCodeUses = NULL;
BVSparse<JitArenaAllocator> *tempByteCodeUse = JitAnew(this->tempAlloc, BVSparse<JitArenaAllocator>, this->tempAlloc);
#if DBG
BVSparse<JitArenaAllocator> *currentBytecodeUsesBeforeOpt = this->byteCodeUsesBeforeOpt;
this->byteCodeUsesBeforeOpt = tempByteCodeUse;
#endif
this->propertySymUse = NULL;
GlobOpt::TrackByteCodeSymUsed(trackByteCodeUseOnInstr, tempByteCodeUse, &tempPropertySymUse);

fn();

this->byteCodeUses = currentBytecodeUses;
this->propertySymUse = currentPropertySymUse;
#if DBG
this->byteCodeUsesBeforeOpt = currentBytecodeUsesBeforeOpt;
#endif
}
private:
// GlobOptBailout.cpp
bool MayNeedBailOut(Loop * loop) const;
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/GlobOptIntBounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ void GlobOpt::TrackIntSpecializedAddSubConstant(
}
} while(false);

if(updateSourceBounds && addSubConstantInfo->Offset() != IntConstMin)
if(!this->IsLoopPrePass() && updateSourceBounds && addSubConstantInfo->Offset() != IntConstMin)
{
// Track bounds for add or sub with a constant. For instance, consider (b = a + 2). The value of 'b' should track
// that it is equal to (the value of 'a') + 2. That part has been done above. Similarly, the value of 'a' should
Expand Down
17 changes: 10 additions & 7 deletions lib/Backend/InlineeFrameInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,14 @@ void InlineeFrameRecord::Finalize(Func* inlinee, uint32 currentOffset)
Assert(this->inlineDepth != 0);
}

void InlineeFrameRecord::Restore(Js::FunctionBody* functionBody, InlinedFrameLayout *inlinedFrame, Js::JavascriptCallStackLayout * layout) const
void InlineeFrameRecord::Restore(Js::FunctionBody* functionBody, InlinedFrameLayout *inlinedFrame, Js::JavascriptCallStackLayout * layout, bool deepCopy) const
{
Assert(this->inlineDepth != 0);
Assert(inlineeStartOffset != 0);

BAILOUT_VERBOSE_TRACE(functionBody, _u("Restore function object: "));
Js::Var varFunction = this->Restore(this->functionOffset, /*isFloat64*/ false, /*isInt32*/ false, layout, functionBody);
// No deepCopy needed for just the function
Js::Var varFunction = this->Restore(this->functionOffset, /*isFloat64*/ false, /*isInt32*/ false, layout, functionBody, /*deepCopy*/ false);
Assert(Js::ScriptFunction::Is(varFunction));

Js::ScriptFunction* function = Js::ScriptFunction::FromVar(varFunction);
Expand All @@ -219,7 +220,9 @@ void InlineeFrameRecord::Restore(Js::FunctionBody* functionBody, InlinedFrameLay
bool isInt32 = losslessInt32Args.Test(i) != 0;
BAILOUT_VERBOSE_TRACE(functionBody, _u("Restore argument %d: "), i);

Js::Var var = this->Restore(this->argOffsets[i], isFloat64, isInt32, layout, functionBody);
// Forward deepCopy flag for the arguments in case their data must be guaranteed
// to have its own lifetime
Js::Var var = this->Restore(this->argOffsets[i], isFloat64, isInt32, layout, functionBody, deepCopy);
#if DBG
if (!Js::TaggedNumber::Is(var))
{
Expand All @@ -233,7 +236,7 @@ void InlineeFrameRecord::Restore(Js::FunctionBody* functionBody, InlinedFrameLay
BAILOUT_FLUSH(functionBody);
}

void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostFrame, Js::JavascriptCallStackLayout* callstack)
void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostFrame, Js::JavascriptCallStackLayout* callstack, bool deepCopy)
{
InlineeFrameRecord* innerMostRecord = this;
class AutoReverse
Expand Down Expand Up @@ -271,7 +274,7 @@ void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFr

while (currentRecord)
{
currentRecord->Restore(functionBody, currentFrame, callstack);
currentRecord->Restore(functionBody, currentFrame, callstack, deepCopy);
currentRecord = currentRecord->parent;
currentFrame = currentFrame->Next();
}
Expand All @@ -280,7 +283,7 @@ void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFr
currentFrame->callInfo.Count = 0;
}

Js::Var InlineeFrameRecord::Restore(int offset, bool isFloat64, bool isInt32, Js::JavascriptCallStackLayout * layout, Js::FunctionBody* functionBody) const
Js::Var InlineeFrameRecord::Restore(int offset, bool isFloat64, bool isInt32, Js::JavascriptCallStackLayout * layout, Js::FunctionBody* functionBody, bool deepCopy) const
{
Js::Var value;
bool boxStackInstance = true;
Expand Down Expand Up @@ -322,7 +325,7 @@ Js::Var InlineeFrameRecord::Restore(int offset, bool isFloat64, bool isInt32, Js
if (boxStackInstance)
{
Js::Var oldValue = value;
value = Js::JavascriptOperators::BoxStackInstance(oldValue, functionBody->GetScriptContext(), /* allowStackFunction */ true);
value = Js::JavascriptOperators::BoxStackInstance(oldValue, functionBody->GetScriptContext(), /* allowStackFunction */ true, deepCopy);

#if ENABLE_DEBUG_CONFIG_OPTIONS
if (oldValue != value)
Expand Down
6 changes: 3 additions & 3 deletions lib/Backend/InlineeFrameInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct InlineeFrameRecord
}

void PopulateParent(Func* func);
void RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostInlinee, Js::JavascriptCallStackLayout* callstack);
void RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostInlinee, Js::JavascriptCallStackLayout* callstack, bool deepCopy);
void Finalize(Func* inlinee, uint currentOffset);
#if DBG_DUMP
void Dump() const;
Expand All @@ -123,8 +123,8 @@ struct InlineeFrameRecord
}

private:
void Restore(Js::FunctionBody* functionBody, InlinedFrameLayout *outerMostFrame, Js::JavascriptCallStackLayout * layout) const;
Js::Var Restore(int offset, bool isFloat64, bool isInt32, Js::JavascriptCallStackLayout * layout, Js::FunctionBody* functionBody) const;
void Restore(Js::FunctionBody* functionBody, InlinedFrameLayout *outerMostFrame, Js::JavascriptCallStackLayout * layout, bool deepCopy) const;
Js::Var Restore(int offset, bool isFloat64, bool isInt32, Js::JavascriptCallStackLayout * layout, Js::FunctionBody* functionBody, bool deepCopy) const;
InlineeFrameRecord* Reverse();
};

Expand Down
4 changes: 2 additions & 2 deletions lib/Backend/JITThunkEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ JITThunkEmitter<TAlloc>::CreateThunk(uintptr_t entryPoint)

if (IsThunkPageEmpty(pageStartAddress))
{
if (this->codeAllocator->Alloc((PVOID)pageStartAddress, AutoSystemInfo::PageSize, MEM_COMMIT, PAGE_EXECUTE, true) == nullptr)
if (this->codeAllocator->AllocPages((PVOID)pageStartAddress, 1, MEM_COMMIT, PAGE_EXECUTE, true) == nullptr)
{
this->codeAllocator->FreeLocal(localPageAddress);
return NULL;
Expand Down Expand Up @@ -165,7 +165,7 @@ JITThunkEmitter<TAlloc>::EnsureInitialized()
// check again because we did the first one outside of lock
if (this->baseAddress == NULL)
{
this->baseAddress = (uintptr_t)this->codeAllocator->Alloc(nullptr, TotalThunkSize, MEM_RESERVE, PAGE_EXECUTE, true);
this->baseAddress = (uintptr_t)this->codeAllocator->AllocPages(nullptr, PageCount, MEM_RESERVE, PAGE_EXECUTE, true);
}
}
return this->baseAddress;
Expand Down
35 changes: 33 additions & 2 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8330,7 +8330,7 @@ Lowerer::LowerAddLeftDeadForString(IR::Instr *instr)
InsertCompareBranch(
regLeftCharLengthOpnd,
IR::IntConstOpnd::New(Js::JavascriptString::MaxCharLength, TyUint32, m_func),
Js::OpCode::BrGt_A,
Js::OpCode::BrGe_A,
labelHelper,
insertBeforeInstr);

Expand Down Expand Up @@ -14702,6 +14702,29 @@ IR::BranchInstr *Lowerer::InsertTestBranch(
return InsertBranch(branchOpCode, isUnsigned, target, insertBeforeInstr);
}

/* Inserts add with an overflow check, if we overflow throw OOM
* add dst, src
* jno $continueLabel
* overflow code
* $continueLabel : fall through
*/
void Lowerer::InsertAddWithOverflowCheck(
const bool needFlags,
IR::Opnd *const dst,
IR::Opnd *src1,
IR::Opnd *src2,
IR::Instr *const insertBeforeInstr,
IR::Instr **const onOverflowInsertBeforeInstrRef)
{
Func * func = insertBeforeInstr->m_func;
InsertAdd(needFlags, dst, src1, src2, insertBeforeInstr);

IR::LabelInstr *const continueLabel = IR::LabelInstr::New(Js::OpCode::Label, func, false);
InsertBranch(LowererMD::MDNotOverflowBranchOpcode, continueLabel, insertBeforeInstr);

*onOverflowInsertBeforeInstrRef = continueLabel;
}

IR::Instr *Lowerer::InsertAdd(
const bool needFlags,
IR::Opnd *const dst,
Expand Down Expand Up @@ -23210,7 +23233,15 @@ Lowerer::LowerSetConcatStrMultiItem(IR::Instr * instr)
srcLength = IR::RegOpnd::New(TyUint32, func);
InsertMove(srcLength, IR::IndirOpnd::New(srcOpnd, Js::ConcatStringMulti::GetOffsetOfcharLength(), TyUint32, func), instr);
}
InsertAdd(false, dstLength, dstLength, srcLength, instr);

IR::Instr *onOverflowInsertBeforeInstr;
InsertAddWithOverflowCheck(false, dstLength, dstLength, srcLength, instr, &onOverflowInsertBeforeInstr);
IR::Instr* callInstr = IR::Instr::New(Js::OpCode::Call, func);
callInstr->SetSrc1(IR::HelperCallOpnd::New(IR::HelperOp_OutOfMemoryError, func));

instr->InsertBefore(onOverflowInsertBeforeInstr);
onOverflowInsertBeforeInstr->InsertBefore(callInstr);
this->m_lowererMD.LowerCall(callInstr, 0);

dstOpnd->SetOffset(dstOpnd->GetOffset() * sizeof(Js::JavascriptString *) + Js::ConcatStringMulti::GetOffsetOfSlots());

Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/Lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ class Lowerer

public:
static void InsertDecUInt32PreventOverflow(IR::Opnd *const dst, IR::Opnd *const src, IR::Instr *const insertBeforeInstr, IR::Instr * *const onOverflowInsertBeforeInstrRef = nullptr);
static void InsertAddWithOverflowCheck(const bool needFlags, IR::Opnd *const dst, IR::Opnd *src1, IR::Opnd *src2, IR::Instr *const insertBeforeInstr, IR::Instr **const onOverflowInsertBeforeInstrRef);

void InsertFloatCheckForZeroOrNanBranch(IR::Opnd *const src, const bool branchOnZeroOrNan, IR::LabelInstr *const target, IR::LabelInstr *const fallthroughLabel, IR::Instr *const insertBeforeInstr);

public:
Expand Down
2 changes: 1 addition & 1 deletion lib/Common/ChakraCoreVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// ChakraCore version number definitions (used in ChakraCore binary metadata)
#define CHAKRA_CORE_MAJOR_VERSION 1
#define CHAKRA_CORE_MINOR_VERSION 7
#define CHAKRA_CORE_PATCH_VERSION 5
#define CHAKRA_CORE_PATCH_VERSION 6
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.

// -------------
Expand Down
10 changes: 8 additions & 2 deletions lib/Common/ConfigFlagsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ PHASE(All)
#define DEFAULT_CONFIG_ES7ValuesEntries (true)
#define DEFAULT_CONFIG_ESObjectGetOwnPropertyDescriptors (true)

#define DEFAULT_CONFIG_ESSharedArrayBuffer (true)
#define DEFAULT_CONFIG_ESSharedArrayBuffer (false)

#define DEFAULT_CONFIG_ES6Verbose (false)
#define DEFAULT_CONFIG_ES6All (false)
Expand All @@ -611,6 +611,7 @@ PHASE(All)
#define DEFAULT_CONFIG_TraceAsyncDebugCalls (false)
#define DEFAULT_CONFIG_ForcePostLowerGlobOptInstrString (false)
#define DEFAULT_CONFIG_EnumerateSpecialPropertiesInDebugger (true)
#define DEFAULT_CONFIG_ESDynamicImport (false)
#endif

#define DEFAULT_CONFIG_MaxJITFunctionBytecodeByteLength (4800000)
Expand Down Expand Up @@ -1029,6 +1030,11 @@ FLAGPR (Boolean, ES6, ES7TrailingComma , "Enable ES7 trailing co
FLAGPR (Boolean, ES6, ES6IsConcatSpreadable , "Enable ES6 isConcatSpreadable Symbol" , DEFAULT_CONFIG_ES6IsConcatSpreadable)
FLAGPR (Boolean, ES6, ES6Math , "Enable ES6 Math extensions" , DEFAULT_CONFIG_ES6Math)

#ifndef COMPILE_DISABLE_ESDynamicImport
#define COMPILE_DISABLE_ESDynamicImport 0
#endif
FLAGPR_REGOVR_EXP(Boolean, ES6, ESDynamicImport , "Enable dynamic import" , DEFAULT_CONFIG_ESDynamicImport)

FLAGPR (Boolean, ES6, ES6Module , "Enable ES6 Modules" , DEFAULT_CONFIG_ES6Module)
FLAGPR (Boolean, ES6, ES6Object , "Enable ES6 Object extensions" , DEFAULT_CONFIG_ES6Object)
FLAGPR (Boolean, ES6, ES6Number , "Enable ES6 Number extensions" , DEFAULT_CONFIG_ES6Number)
Expand Down Expand Up @@ -1078,7 +1084,7 @@ FLAGPR (Boolean, ES6, ESObjectGetOwnPropertyDescriptors, "Enable Objec
#ifndef COMPILE_DISABLE_ESSharedArrayBuffer
#define COMPILE_DISABLE_ESSharedArrayBuffer 0
#endif
FLAGPRA (Boolean, ES6, ESSharedArrayBuffer , sab , "Enable SharedArrayBuffer" , DEFAULT_CONFIG_ESSharedArrayBuffer)
FLAGPR_REGOVR_EXP(Boolean, ES6, ESSharedArrayBuffer , "Enable SharedArrayBuffer" , DEFAULT_CONFIG_ESSharedArrayBuffer)

// /ES6 (BLUE+1) features/flags

Expand Down
2 changes: 2 additions & 0 deletions lib/Common/Core/SysInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class AutoSystemInfo : public SYSTEM_INFO
#endif
static DWORD const PageSize = 4096;

static size_t const MaxPageCount = SIZE_MAX / PageSize;

#ifdef STACK_ALIGN
static DWORD const StackAlign = STACK_ALIGN;
#else
Expand Down
Loading

0 comments on commit e02b39a

Please sign in to comment.