Skip to content

Commit edd1d35

Browse files
committed
[MERGE #2684 @curtisman] Avoid calling CompileScriptException::ProcessError in the catch handler, where the stack is not unwounded.
Merge pull request #2684 from curtisman:parseerr If we are hitting a stack overflow, we should unwind the stack before running more code (like ProcessError) Also clean up ErrHandler, which really does nothing but throw ParseException. Change it to directly throw ParseException. Clean up some debug only ifdef and disable background parsing code in release build, which is not enabled by default. Fixes VSO: 11101148
2 parents b1f36e3 + bc33f65 commit edd1d35

File tree

15 files changed

+70
-82
lines changed

15 files changed

+70
-82
lines changed

lib/Common/CommonDefines.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@
201201
#define ENABLE_PROFILE_INFO 1
202202

203203
#define ENABLE_BACKGROUND_JOB_PROCESSOR 1
204-
#define ENABLE_BACKGROUND_PARSING 1
205204
#define ENABLE_COPYONACCESS_ARRAY 1
206205
#ifndef DYNAMIC_INTERPRETER_THUNK
207206
#if defined(_M_IX86_OR_ARM32) || defined(_M_X64_OR_ARM64)
@@ -210,6 +209,12 @@
210209
#define DYNAMIC_INTERPRETER_THUNK 0
211210
#endif
212211
#endif
212+
213+
// Don't enable background parser in release build.
214+
#if ENABLE_DEBUG_CONFIG_OPTIONS
215+
#define ENABLE_BACKGROUND_PARSING 1
216+
#endif
217+
213218
#endif
214219

215220
#if ENABLE_NATIVE_CODEGEN

lib/Common/Memory/HeapInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,8 @@ HeapInfo::Rescan(RescanFlags flags)
10371037
return scannedPageCount;
10381038
}
10391039

1040+
#ifdef DUMP_FRAGMENTATION_STATS
1041+
10401042
template <ObjectInfoBits TBucketType, class TBlockAttributes>
10411043
void DumpBucket(uint bucketIndex, typename SmallHeapBlockType<TBucketType, TBlockAttributes>::BucketType& bucket)
10421044
{
@@ -1048,7 +1050,6 @@ void DumpBucket(uint bucketIndex, typename SmallHeapBlockType<TBucketType, TBloc
10481050
Output::Print(_u("%d,%d,%d,%d,%d,%d,%d\n"), stats.totalBlockCount, stats.finalizeBlockCount, stats.emptyBlockCount, stats.objectCount, stats.finalizeCount, stats.objectByteCount, stats.totalByteCount);
10491051
}
10501052

1051-
#ifdef DUMP_FRAGMENTATION_STATS
10521053
void
10531054
HeapInfo::DumpFragmentationStats()
10541055
{

lib/Parser/BackgroundParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"Cannot use this member of BackgroundParser from thread other than the creating context's current thread")
99

1010
#if ENABLE_NATIVE_CODEGEN
11+
#if ENABLE_BACKGROUND_PARSING
1112
BackgroundParser::BackgroundParser(Js::ScriptContext *scriptContext)
1213
: JsUtil::WaitableJobManager(scriptContext->GetThreadContext()->GetJobProcessor()),
1314
scriptContext(scriptContext),
@@ -292,3 +293,4 @@ void BackgroundParseItem::AddRegExpNode(ParseNode *const pnode, ArenaAllocator *
292293
regExpNodes->Append(pnode);
293294
}
294295
#endif
296+
#endif

lib/Parser/Hash.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ const HashTbl::ReservedWordInfo HashTbl::s_reservedWordInfo[tkID] =
2626
#include "keywords.h"
2727
};
2828

29-
HashTbl * HashTbl::Create(uint cidHash, ErrHandler * perr)
29+
HashTbl * HashTbl::Create(uint cidHash)
3030
{
3131
HashTbl * phtbl;
3232

33-
if (nullptr == (phtbl = HeapNewNoThrow(HashTbl,perr)))
33+
if (nullptr == (phtbl = HeapNewNoThrow(HashTbl)))
3434
return nullptr;
3535
if (!phtbl->Init(cidHash))
3636
{
@@ -301,12 +301,12 @@ IdentPtr HashTbl::PidHashNameLenWithHash(_In_reads_(cch) CharType const * prgch,
301301
FAILED(ULongToLong(Len, &cb)))
302302
{
303303
cb = 0;
304-
m_perr->Throw(ERRnoMemory);
304+
OutOfMemory();
305305
}
306306

307307

308308
if (nullptr == (pid = (IdentPtr)m_noReleaseAllocator.Alloc(cb)))
309-
m_perr->Throw(ERRnoMemory);
309+
OutOfMemory();
310310

311311
/* Insert the identifier into the hash list */
312312
*ppid = pid;
@@ -466,3 +466,8 @@ tokens HashTbl::TkFromNameLen(_In_reads_(cch) LPCOLESTR prgch, uint32 cch, bool
466466
}
467467

468468
#pragma warning(pop)
469+
470+
__declspec(noreturn) void HashTbl::OutOfMemory()
471+
{
472+
throw ParseExceptionObject(ERRnoMemory);
473+
}

lib/Parser/Hash.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ struct Ident
324324
class HashTbl
325325
{
326326
public:
327-
static HashTbl * Create(uint cidHash, ErrHandler * perr);
327+
static HashTbl * Create(uint cidHash);
328328

329329
void Release(void)
330330
{
@@ -394,14 +394,12 @@ class HashTbl
394394
Ident ** m_prgpidName; // hash table for names
395395

396396
uint32 m_luMask; // hash mask
397-
uint32 m_luCount; // count of the number of entires in the hash table
398-
ErrHandler * m_perr; // error handler to use
397+
uint32 m_luCount; // count of the number of entires in the hash table
399398
IdentPtr m_rpid[tkLimKwd];
400399

401-
HashTbl(ErrHandler * perr)
400+
HashTbl()
402401
{
403402
m_prgpidName = nullptr;
404-
m_perr = perr;
405403
memset(&m_rpid, 0, sizeof(m_rpid));
406404
}
407405
~HashTbl(void) {}
@@ -481,6 +479,7 @@ class HashTbl
481479
static const KWD * KwdOfTok(tokens tk)
482480
{ return (unsigned int)tk < tkLimKwd ? g_mptkkwd + tk : nullptr; }
483481

482+
static __declspec(noreturn) void OutOfMemory();
484483
#if PROFILE_DICTIONARY
485484
DictionaryStats *stats;
486485
#endif

lib/Parser/Parse.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ void Parser::OutOfMemory()
172172

173173
void Parser::Error(HRESULT hr)
174174
{
175-
Assert(FAILED(hr));
176-
m_err.Throw(hr);
175+
throw ParseExceptionObject(hr);
177176
}
178177

179178
void Parser::Error(HRESULT hr, ParseNodePtr pnode)
@@ -247,7 +246,6 @@ HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isG
247246
HRESULT hr;
248247
SmartFPUControl smartFpuControl;
249248

250-
DebugOnly( m_err.fInited = TRUE; )
251249
BOOL fDeferSave = m_deferringAST;
252250
try
253251
{
@@ -321,10 +319,13 @@ HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isG
321319
catch(ParseExceptionObject& e)
322320
{
323321
m_deferringAST = fDeferSave;
324-
m_err.m_hr = e.GetError();
325-
hr = pse->ProcessError( m_pscan, m_err.m_hr, /* pnodeBase */ NULL);
322+
hr = e.GetError();
326323
}
327324

325+
if (nullptr != pse && FAILED(hr))
326+
{
327+
hr = pse->ProcessError(m_pscan, hr, /* pnodeBase */ NULL);
328+
}
328329
return hr;
329330
}
330331

@@ -360,8 +361,6 @@ HRESULT Parser::ParseSourceInternal(
360361
HRESULT hr;
361362
SmartFPUControl smartFpuControl;
362363

363-
DebugOnly( m_err.fInited = TRUE; )
364-
365364
try
366365
{
367366
this->PrepareScanner(fromExternal);
@@ -405,8 +404,12 @@ HRESULT Parser::ParseSourceInternal(
405404
}
406405
catch(ParseExceptionObject& e)
407406
{
408-
m_err.m_hr = e.GetError();
409-
hr = pse->ProcessError( m_pscan, m_err.m_hr, pnodeBase);
407+
hr = e.GetError();
408+
}
409+
410+
if (FAILED(hr))
411+
{
412+
hr = pse->ProcessError(m_pscan, hr, pnodeBase);
410413
}
411414

412415
if (this->m_hasParallelJob)
@@ -11246,12 +11249,12 @@ void Parser::PrepareScanner(bool fromExternal)
1124611249
// heap allocation for the colorizer interface.
1124711250

1124811251
// create the hash table and init PID members
11249-
if (nullptr == (m_phtbl = HashTbl::Create(HASH_TABLE_SIZE, &m_err)))
11252+
if (nullptr == (m_phtbl = HashTbl::Create(HASH_TABLE_SIZE)))
1125011253
Error(ERRnoMemory);
1125111254
InitPids();
1125211255

1125311256
// create the scanner
11254-
if (nullptr == (m_pscan = Scanner_t::Create(this, m_phtbl, &m_token, &m_err, m_scriptContext)))
11257+
if (nullptr == (m_pscan = Scanner_t::Create(this, m_phtbl, &m_token, m_scriptContext)))
1125511258
Error(ERRnoMemory);
1125611259

1125711260
if (fromExternal)
@@ -11298,7 +11301,6 @@ void Parser::AddBackgroundRegExpNode(ParseNodePtr const pnode)
1129811301

1129911302
currBackgroundParseItem->AddRegExpNode(pnode, &m_nodeAllocator);
1130011303
}
11301-
#endif
1130211304

1130311305
HRESULT Parser::ParseFunctionInBackground(ParseNodePtr pnodeFnc, ParseContext *parseContext, bool topLevelDeferred, CompileScriptException *pse)
1130411306
{
@@ -11309,7 +11311,6 @@ HRESULT Parser::ParseFunctionInBackground(ParseNodePtr pnodeFnc, ParseContext *p
1130911311
uint nextFunctionId = pnodeFnc->sxFnc.functionId + 1;
1131011312

1131111313
this->RestoreContext(parseContext);
11312-
DebugOnly( m_err.fInited = TRUE; )
1131311314
m_nextFunctionId = &nextFunctionId;
1131411315
m_deferringAST = topLevelDeferred;
1131511316
m_inDeferredNestedFunc = false;
@@ -11383,8 +11384,12 @@ HRESULT Parser::ParseFunctionInBackground(ParseNodePtr pnodeFnc, ParseContext *p
1138311384
}
1138411385
catch(ParseExceptionObject& e)
1138511386
{
11386-
m_err.m_hr = e.GetError();
11387-
hr = pse->ProcessError( m_pscan, m_err.m_hr, nullptr);
11387+
hr = e.GetError();
11388+
}
11389+
11390+
if (FAILED(hr))
11391+
{
11392+
hr = pse->ProcessError(m_pscan, hr, nullptr);
1138811393
}
1138911394

1139011395
if (IsStrictMode())
@@ -11404,6 +11409,8 @@ HRESULT Parser::ParseFunctionInBackground(ParseNodePtr pnodeFnc, ParseContext *p
1140411409
return hr;
1140511410
}
1140611411

11412+
#endif
11413+
1140711414
HRESULT Parser::ParseSourceWithOffset(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
1140811415
bool isCesu8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo,
1140911416
Js::ParseableFunctionInfo* functionInfo)

lib/Parser/Parse.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ class Parser
209209
protected:
210210
Js::ScriptContext* m_scriptContext;
211211
HashTbl * m_phtbl;
212-
ErrHandler m_err;
213212

214213
static const uint HASH_TABLE_SIZE = 256;
215214

@@ -310,12 +309,14 @@ class Parser
310309
void PrepareScanner(bool fromExternal);
311310
void PrepareForBackgroundParse();
312311
void AddFastScannedRegExpNode(ParseNodePtr const pnode);
312+
#if ENABLE_BACKGROUND_PARSING
313313
void AddBackgroundRegExpNode(ParseNodePtr const pnode);
314314
void AddBackgroundParseItem(BackgroundParseItem *const item);
315315
void FinishBackgroundRegExpNodes();
316316
void FinishBackgroundPidRefs(BackgroundParseItem *const item, bool isOtherParser);
317317
void WaitForBackgroundJobs(BackgroundParser *bgp, CompileScriptException *pse);
318318
HRESULT ParseFunctionInBackground(ParseNodePtr pnodeFunc, ParseContext *parseContext, bool topLevelDeferred, CompileScriptException *pse);
319+
#endif
319320

320321
void CheckPidIsValid(IdentPtr pid, bool autoArgumentsObject = false);
321322
void AddVarDeclToBlock(ParseNode *pnode);

lib/Parser/Scan.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,14 @@ IdentPtr Token::CreateIdentifier(HashTbl * hashTbl)
124124
}
125125

126126
template <typename EncodingPolicy>
127-
Scanner<EncodingPolicy>::Scanner(Parser* parser, HashTbl *phtbl, Token *ptoken, ErrHandler *perr, Js::ScriptContext* scriptContext)
127+
Scanner<EncodingPolicy>::Scanner(Parser* parser, HashTbl *phtbl, Token *ptoken, Js::ScriptContext* scriptContext)
128128
{
129129
AssertMem(phtbl);
130130
AssertMem(ptoken);
131-
AssertMem(perr);
132131
m_parser = parser;
133132
m_phtbl = phtbl;
134133
m_ptoken = ptoken;
135134
m_cMinLineMultiUnits = 0;
136-
m_perr = perr;
137135
m_fHadEol = FALSE;
138136

139137
m_doubleQuoteOnLastTkStrCon = FALSE;

lib/Parser/Scan.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,9 @@ class Scanner : public IScanner, public EncodingPolicy
364364
typedef typename EncodingPolicy::EncodedCharPtr EncodedCharPtr;
365365

366366
public:
367-
static Scanner * Create(Parser* parser, HashTbl *phtbl, Token *ptoken, ErrHandler *perr, Js::ScriptContext *scriptContext)
367+
static Scanner * Create(Parser* parser, HashTbl *phtbl, Token *ptoken, Js::ScriptContext *scriptContext)
368368
{
369-
return HeapNewNoThrow(Scanner, parser, phtbl, ptoken, perr, scriptContext);
369+
return HeapNewNoThrow(Scanner, parser, phtbl, ptoken, scriptContext);
370370
}
371371
void Release(void)
372372
{
@@ -677,7 +677,6 @@ class Scanner : public IScanner, public EncodingPolicy
677677
EncodedCharPtr m_pchPrevLine; // beginning of previous line
678678
size_t m_cMinTokMultiUnits; // number of multi-unit characters previous to m_pchMinTok
679679
size_t m_cMinLineMultiUnits; // number of multi-unit characters previous to m_pchMinLine
680-
ErrHandler *m_perr; // error handler to use
681680
uint16 m_fStringTemplateDepth; // we should treat } as string template middle starting character (depth instead of flag)
682681
BOOL m_fHadEol;
683682
BOOL m_fIsModuleCode : 1;
@@ -711,7 +710,7 @@ class Scanner : public IScanner, public EncodingPolicy
711710
tokens m_tkPrevious;
712711
size_t m_iecpLimTokPrevious;
713712

714-
Scanner(Parser* parser, HashTbl *phtbl, Token *ptoken, ErrHandler *perr, Js::ScriptContext *scriptContext);
713+
Scanner(Parser* parser, HashTbl *phtbl, Token *ptoken, Js::ScriptContext *scriptContext);
715714
~Scanner(void);
716715

717716
template <bool forcePid>
@@ -729,11 +728,9 @@ class Scanner : public IScanner, public EncodingPolicy
729728

730729
__declspec(noreturn) void Error(HRESULT hr)
731730
{
732-
Assert(FAILED(hr));
733731
m_pchMinTok = m_currentCharacter;
734732
m_cMinTokMultiUnits = this->m_cMultiUnits;
735-
AssertMem(m_perr);
736-
m_perr->Throw(hr);
733+
throw ParseExceptionObject(hr);
737734
}
738735

739736
const EncodedCharPtr PchBase(void)

lib/Parser/cmperr.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,8 @@
44
//-------------------------------------------------------------------------------------------------------
55
#include "ParserPch.h"
66

7-
#if DEBUG
8-
#include <stdarg.h>
9-
#endif //DEBUG
10-
11-
void ErrHandler::Throw(HRESULT hr)
7+
ParseExceptionObject::ParseExceptionObject(HRESULT hr) : m_hr(hr)
128
{
13-
Assert(fInited);
149
Assert(FAILED(hr));
15-
m_hr = hr;
16-
throw ParseExceptionObject(hr);
1710
}
11+

lib/Parser/cmperr.h

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,8 @@ enum
1717
class ParseExceptionObject
1818
{
1919
public:
20-
ParseExceptionObject(HRESULT hr) : m_hr(hr) {}
20+
ParseExceptionObject(HRESULT hr);
2121
HRESULT GetError() { return m_hr; }
2222
private:
2323
HRESULT m_hr;
2424
};
25-
26-
typedef void (*ErrorCallback)(void *data, HRESULT hr);
27-
28-
class ErrHandler
29-
{
30-
public:
31-
HRESULT m_hr;
32-
33-
void *m_data;
34-
ErrorCallback m_callback;
35-
36-
__declspec(noreturn) void Throw(HRESULT hr);
37-
38-
#if DEBUG
39-
BOOL fInited;
40-
ErrHandler()
41-
{ fInited = FALSE; }
42-
#endif //DEBUG
43-
};
44-

lib/Parser/screrror.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,6 @@ void CompileScriptException::Free()
245245

246246
HRESULT CompileScriptException::ProcessError(IScanner * pScan, HRESULT hr, ParseNode * pnodeBase)
247247
{
248-
if (nullptr == this)
249-
return hr;
250-
251248
// fill in the ScriptException structure
252249
Clear();
253250
ei.scode = GetScode(MapHr(hr));

lib/Parser/screrror.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
/***************************************************************************
88
Exception blocks
99
***************************************************************************/
10-
class ErrHandler;
1110
struct ParseNode;
1211
class COleScript;
1312
interface IScanner;

0 commit comments

Comments
 (0)