Skip to content

Commit fc5b62c

Browse files
committed
[MERGE chakra-core#2199 @Cellule] WScript.Flag
Merge pull request chakra-core#2199 from Cellule:flags Add WScript.Flag to change config flag from javascript The main reason for this is to allows to change the behavior of WebAssembly features from javascript to support the spec tests which needs different config within a single file
2 parents 23a2c41 + 68c9172 commit fc5b62c

15 files changed

Lines changed: 248 additions & 19 deletions

bin/ch/WScriptJsrt.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ bool WScriptJsrt::Initialize()
836836
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "RequestAsyncBreak", RequestAsyncBreakCallback));
837837
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadBinaryFile", LoadBinaryFileCallback));
838838
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "LoadTextFile", LoadTextFileCallback));
839+
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Flag", FlagCallback));
839840

840841
// ToDo Remove
841842
IfFalseGo(WScriptJsrt::InstallObjectsOnObject(wscript, "Edit", EmptyCallback));
@@ -1027,6 +1028,28 @@ JsValueRef __stdcall WScriptJsrt::LoadBinaryFileCallback(JsValueRef callee,
10271028
return returnValue;
10281029
}
10291030

1031+
JsValueRef __stdcall WScriptJsrt::FlagCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
1032+
{
1033+
HRESULT hr = E_FAIL;
1034+
JsValueRef returnValue = JS_INVALID_REFERENCE;
1035+
JsErrorCode errorCode = JsNoError;
1036+
1037+
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
1038+
1039+
#if ENABLE_DEBUG_CONFIG_OPTIONS
1040+
if (argumentCount > 1)
1041+
{
1042+
AutoString cmd;
1043+
IfJsrtErrorSetGo(cmd.Initialize(arguments[1]));
1044+
char16* argv[] = { nullptr, cmd.GetWideString() };
1045+
ChakraRTInterface::SetConfigFlags(2, argv, nullptr);
1046+
}
1047+
#endif
1048+
1049+
Error:
1050+
return returnValue;
1051+
}
1052+
10301053
bool WScriptJsrt::PrintException(LPCSTR fileName, JsErrorCode jsErrorCode)
10311054
{
10321055
LPCWSTR errorTypeString = ConvertErrorCodeToMessage(jsErrorCode);

bin/ch/WScriptJsrt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class WScriptJsrt
111111

112112
static JsValueRef __stdcall LoadBinaryFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
113113
static JsValueRef __stdcall LoadTextFileCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
114+
static JsValueRef __stdcall FlagCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState);
114115

115116
static MessageQueue *messageQueue;
116117
static DWORD_PTR sourceContext;

lib/Common/Core/CmdParser.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ CmdLineArgsParser::ParseInteger()
234234
///----------------------------------------------------------------------------
235235

236236
void
237-
CmdLineArgsParser::ParseRange(Js::Range *pRange)
237+
CmdLineArgsParser::ParseRange(Js::Range *pRange, Js::Range *oppositeRange)
238238
{
239239
SourceFunctionNode r1 = ParseSourceFunctionIds();
240240
SourceFunctionNode r2;
@@ -254,12 +254,12 @@ CmdLineArgsParser::ParseRange(Js::Range *pRange)
254254
throw Exception(_u("Left functionId must be smaller than the Right functionId when Source file is the same"));
255255
}
256256

257-
pRange->Add(r1, r2);
257+
pRange->Add(r1, r2, oppositeRange);
258258
switch(CurChar())
259259
{
260260
case ',':
261261
NextChar();
262-
ParseRange(pRange);
262+
ParseRange(pRange, oppositeRange);
263263
break;
264264

265265
case ' ':
@@ -272,14 +272,14 @@ CmdLineArgsParser::ParseRange(Js::Range *pRange)
272272
break;
273273

274274
case ',':
275-
pRange->Add(r1);
275+
pRange->Add(r1, oppositeRange);
276276
NextChar();
277-
ParseRange(pRange);
277+
ParseRange(pRange, oppositeRange);
278278
break;
279279

280280
case ' ':
281281
case 0:
282-
pRange->Add(r1);
282+
pRange->Add(r1, oppositeRange);
283283
break;
284284

285285
default:
@@ -350,7 +350,7 @@ CmdLineArgsParser::ParseNumberRange(Js::NumberRange *pRange)
350350
///----------------------------------------------------------------------------
351351

352352
void
353-
CmdLineArgsParser::ParsePhase(Js::Phases *pPhaseList)
353+
CmdLineArgsParser::ParsePhase(Js::Phases *pPhaseList, Js::Phases *oppositePhase)
354354
{
355355
char16 buffer[MaxTokenSize];
356356
ZeroMemory(buffer, sizeof(buffer));
@@ -365,14 +365,32 @@ CmdLineArgsParser::ParsePhase(Js::Phases *pPhaseList)
365365
switch(CurChar())
366366
{
367367
case ':':
368+
{
368369
NextChar();
369-
ParseRange(pPhaseList->GetRange(phase));
370+
Js::Range* oppositeRange = nullptr;
371+
if (oppositePhase && oppositePhase->IsEnabled(phase))
372+
{
373+
oppositeRange = oppositePhase->GetRange(phase);
374+
}
375+
ParseRange(pPhaseList->GetRange(phase), oppositeRange);
370376
break;
377+
}
371378
case ',':
372379
NextChar();
373-
ParsePhase(pPhaseList);
380+
if (oppositePhase)
381+
{
382+
// The whole phase is turned on/off so disable the opposite
383+
oppositePhase->Disable(phase);
384+
}
385+
ParsePhase(pPhaseList, oppositePhase);
374386
break;
375387
default:
388+
if (oppositePhase)
389+
{
390+
// The whole phase is turned on/off so disable the opposite
391+
oppositePhase->Disable(phase);
392+
}
393+
pPhaseList->GetRange(phase)->Clear();
376394
break;
377395
}
378396
}
@@ -512,8 +530,17 @@ CmdLineArgsParser::ParseFlag()
512530
switch(flagType)
513531
{
514532
case FlagPhases:
515-
ParsePhase(this->flagTable.GetAsPhase(flag));
533+
{
534+
Flag oppositeFlag = this->flagTable.GetOppositePhaseFlag(flag);
535+
Phases* oppositePhase = nullptr;
536+
if (oppositeFlag != InvalidFlag)
537+
{
538+
this->flagTable.Enable(oppositeFlag);
539+
oppositePhase = this->flagTable.GetAsPhase(oppositeFlag);
540+
}
541+
ParsePhase(this->flagTable.GetAsPhase(flag), oppositePhase);
516542
break;
543+
}
517544

518545
case FlagString:
519546
*this->flagTable.GetAsString(flag) = ParseString(buffer, MaxTokenSize, false);

lib/Common/Core/CmdParser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class CmdLineArgsParser : private ICmdLineArgsParser
6767
LPWSTR ParseString(__inout_ecount(ceBuffer) LPWSTR buffer, size_t ceBuffer = MaxTokenSize, bool fTreatColonAsSeparator = true);
6868
int ParseInteger();
6969
Js::SourceFunctionNode ParseSourceFunctionIds();
70-
void ParsePhase(Js::Phases *pPhase);
71-
void ParseRange(Js::Range *range);
70+
void ParsePhase(Js::Phases *pPhase, Js::Phases *oppositePhase);
71+
void ParseRange(Js::Range *range, Js::Range *oppositeRange);
7272
void ParseNumberRange(Js::NumberRange *range);
7373
void ParseFlag();
7474
void ParseNumberSet(Js::NumberSet * numberSet);

lib/Common/Core/ConfigFlagsTable.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,41 @@ namespace Js
141141
return false;
142142
}
143143

144+
template <>
145+
Js::RangeUnit<Js::SourceFunctionNode> GetFullRange()
146+
{
147+
RangeUnit<SourceFunctionNode> unit;
148+
unit.i.sourceContextId = 0;
149+
unit.j.sourceContextId = UINT_MAX;
150+
unit.i.functionId = 0;
151+
unit.j.functionId = (uint)-3;
152+
return unit;
153+
}
154+
155+
template <>
156+
SourceFunctionNode GetPrevious(SourceFunctionNode unit)
157+
{
158+
SourceFunctionNode prevUnit = unit;
159+
prevUnit.functionId--;
160+
if (prevUnit.functionId == UINT_MAX)
161+
{
162+
prevUnit.sourceContextId--;
163+
}
164+
return prevUnit;
165+
}
166+
167+
template <>
168+
SourceFunctionNode GetNext(SourceFunctionNode unit)
169+
{
170+
SourceFunctionNode nextUnit = unit;
171+
nextUnit.functionId++;
172+
if (nextUnit.functionId == 0)
173+
{
174+
nextUnit.sourceContextId++;
175+
}
176+
return nextUnit;
177+
}
178+
144179
///----------------------------------------------------------------------------
145180
///----------------------------------------------------------------------------
146181
///
@@ -181,6 +216,13 @@ namespace Js
181216
this->phaseList[(int)phase].valid = true;
182217
}
183218

219+
void
220+
Phases::Disable(Phase phase)
221+
{
222+
this->phaseList[(int)phase].valid = false;
223+
this->phaseList[(int)phase].range.Clear();
224+
}
225+
184226
Phase
185227
Phases::GetFirstPhase()
186228
{
@@ -308,6 +350,19 @@ namespace Js
308350
return reinterpret_cast<Phases*>(GetProperty(flag));
309351
}
310352

353+
Flag
354+
ConfigFlagsTable::GetOppositePhaseFlag(Flag flag) const
355+
{
356+
#if ENABLE_DEBUG_CONFIG_OPTIONS
357+
switch (flag)
358+
{
359+
case OnFlag: return OffFlag;
360+
case OffFlag: return OnFlag;
361+
}
362+
#endif
363+
return InvalidFlag;
364+
}
365+
311366
Boolean *
312367
ConfigFlagsTable::GetAsBoolean(Flag flag) const
313368
{

0 commit comments

Comments
 (0)