Skip to content

Commit ed98335

Browse files
committedOct 2, 2018
[MERGE #5734 @wyrichte] Fixes #5576 - Chakra should not redeclare "undefined" keyword
Merge pull request #5734 from wyrichte:build/wyrichte/5576_1 Fixed by adding opcode OP_EnsureNoRootRedeclFunc that enforces the section of #sec-globaldeclarationinstantiation where #CanDeclareGlobalFunction is called. This enforces that when a global function that is not configurable, not writable, and not enumerable is overwritten a TypeError is thrown.
2 parents b9b758c + 8ecdb9e commit ed98335

26 files changed

+1074
-817
lines changed
 

‎lib/Backend/JnHelperMethodList.h

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ HELPERCALLCHK(Op_LdElemUndefDynamic, Js::JavascriptOperators::OP_LoadUndefinedTo
6666
HELPERCALLCHK(Op_LdElemUndefScoped, Js::JavascriptOperators::OP_LoadUndefinedToElementScoped, AttrCanNotBeReentrant)
6767
HELPERCALLCHK(Op_EnsureNoRootProperty, Js::JavascriptOperators::OP_EnsureNoRootProperty, AttrCanThrow | AttrCanNotBeReentrant)
6868
HELPERCALLCHK(Op_EnsureNoRootRedeclProperty, Js::JavascriptOperators::OP_EnsureNoRootRedeclProperty, AttrCanThrow | AttrCanNotBeReentrant)
69+
HELPERCALLCHK(Op_EnsureCanDeclGloFunc, Js::JavascriptOperators::OP_EnsureCanDeclGloFunc, AttrCanThrow | AttrCanNotBeReentrant)
6970
HELPERCALLCHK(Op_EnsureNoRedeclPropertyScoped, Js::JavascriptOperators::OP_ScopedEnsureNoRedeclProperty, AttrCanThrow | AttrCanNotBeReentrant)
7071

7172
HELPERCALLCHK(Op_ToSpreadedFunctionArgument, Js::JavascriptOperators::OP_LdCustomSpreadIteratorList, AttrCanThrow)

‎lib/Backend/Lower.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2491,6 +2491,10 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
24912491
this->LowerElementUndefined(instr, IR::HelperOp_EnsureNoRootRedeclProperty);
24922492
break;
24932493

2494+
case Js::OpCode::EnsureCanDeclGloFunc:
2495+
this->LowerElementUndefined(instr, IR::HelperOp_EnsureCanDeclGloFunc);
2496+
break;
2497+
24942498
case Js::OpCode::ScopedEnsureNoRedeclFld:
24952499
this->LowerElementUndefinedScoped(instr, IR::HelperOp_EnsureNoRedeclPropertyScoped);
24962500
break;

‎lib/Parser/rterrors.h

+1
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ RT_ERROR_MSG(JSERR_RegExpTooManyCapturingGroups, 5675, "", "Regular expression c
370370
RT_ERROR_MSG(JSERR_ProxyHandlerReturnedFalse, 5676, "Proxy %s handler returned false", "Proxy handler returned false", kjstTypeError, 0)
371371
RT_ERROR_MSG(JSERR_UnicodeRegExpRangeContainsCharClass, 5677, "%s", "Character classes not allowed in a RegExp class range.", kjstSyntaxError, 0)
372372
RT_ERROR_MSG(JSERR_DuplicateKeysFromOwnPropertyKeys, 5678, "%s", "Proxy's ownKeys trap returned duplicate keys", kjstTypeError, 0)
373+
RT_ERROR_MSG(JSERR_InvalidGloFuncDecl, 5679, "The global property %s is not configurable, writable, nor enumerable, therefore cannot be declared as a function", "", kjstTypeError, 0)
373374

374375
//Host errors
375376
RT_ERROR_MSG(JSERR_HostMaybeMissingPromiseContinuationCallback, 5700, "", "Host may not have set any promise continuation callback. Promises may not be executed.", kjstTypeError, 0)

‎lib/Runtime/ByteCode/ByteCodeCacheReleaseFileVersion.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
//-------------------------------------------------------------------------------------------------------
55
// NOTE: If there is a merge conflict the correct fix is to make a new GUID.
66

7-
// {BFA0BED0-7B1A-4018-83DA-B1D989D38BFD}
7+
// {9FAAF688-ACBA-4092-BA5B-77D97D3CD53A}
88
const GUID byteCodeCacheReleaseFileVersion =
9-
{ 0xBFA0BED0, 0x7B1A, 0x4018, { 0x83, 0xDA, 0xB1, 0xD9, 0x89, 0xD3, 0x8B, 0xFD } };
9+
{ 0x9FAAF688, 0xACBA, 0x4092, { 0xBA, 0x5B, 0x77, 0xD9, 0x7D, 0x3C, 0xD5, 0x3A } };

‎lib/Runtime/ByteCode/ByteCodeDumper.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,11 @@ namespace Js
630630
Output::Print(_u(" root.%s"), pPropertyName->GetBuffer());
631631
break;
632632
}
633+
case OpCode::EnsureCanDeclGloFunc:
634+
{
635+
Output::Print(_u(" root.%s"), pPropertyName->GetBuffer());
636+
break;
637+
}
633638
case OpCode::LdLocalElemUndef:
634639
{
635640
Output::Print(_u(" %s = undefined"), pPropertyName->GetBuffer());

‎lib/Runtime/ByteCode/ByteCodeEmitter.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -5588,10 +5588,17 @@ void ByteCodeGenerator::EnsureNoRedeclarations(ParseNodeBlock *pnodeBlock, FuncI
55885588
});
55895589
}
55905590

5591-
auto emitRedeclCheck = [this](Symbol * sym, FuncInfo * funcInfo)
5591+
auto emitRedeclCheck = [this](Symbol * sym, FuncInfo * funcInfo, bool isFncDecl = false)
55925592
{
55935593
Js::PropertyId propertyId = sym->EnsurePosition(this);
55945594

5595+
// Global function declarations must pass #sec-candeclareglobalfunction
5596+
// which is enforced by EnsureCanDeclGloFunc
5597+
if (isFncDecl)
5598+
{
5599+
this->m_writer.ElementRootU(Js::OpCode::EnsureCanDeclGloFunc, funcInfo->FindOrAddReferencedPropertyId(propertyId));
5600+
}
5601+
55955602
if (this->flags & fscrEval)
55965603
{
55975604
if (!funcInfo->byteCodeFunction->GetIsStrictMode())
@@ -5615,7 +5622,7 @@ void ByteCodeGenerator::EnsureNoRedeclarations(ParseNodeBlock *pnodeBlock, FuncI
56155622
case knopFncDecl:
56165623
if (pnode->AsParseNodeFnc()->IsDeclaration())
56175624
{
5618-
emitRedeclCheck(pnode->AsParseNodeFnc()->pnodeName->sym, funcInfo);
5625+
emitRedeclCheck(pnode->AsParseNodeFnc()->pnodeName->sym, funcInfo, true);
56195626
}
56205627

56215628
pnode = pnode->AsParseNodeFnc()->pnodeNext;

‎lib/Runtime/ByteCode/OpCodes.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@
7171
MACRO_WMS_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
7272

7373
#define MACRO_EXTENDED_ROOT(opcode, layout, attr) \
74-
MACRO_EXTENDED_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
74+
MACRO_EXTEND_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
7575

7676
#define MACRO_EXTEND_WMS_ROOT(opcode, layout, attr) \
77-
MACRO_EXTENDED_WMS_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
77+
MACRO_EXTEND_WMS_WITH_DBG_ATTR(opcode, layout, attr, OpDbgAttr_LoadRoot)
7878

7979
#define MACRO_WMS_PROFILED( opcode, layout, attr) \
8080
MACRO_WMS(opcode, layout, OpHasProfiled|attr) \
@@ -354,6 +354,7 @@ MACRO_WMS( ChkUndecl, Reg1, OpSideEffect
354354

355355
MACRO_WMS_ROOT( EnsureNoRootFld, ElementRootU, OpSideEffect)
356356
MACRO_WMS_ROOT( EnsureNoRootRedeclFld, ElementRootU, OpSideEffect)
357+
MACRO_EXTEND_WMS_ROOT( EnsureCanDeclGloFunc, ElementRootU, OpSideEffect)
357358
MACRO_WMS( ScopedEnsureNoRedeclFld, ElementScopedC, OpSideEffect)
358359

359360
MACRO_WMS( InitUndecl, Reg1, OpCanCSE)

‎lib/Runtime/Language/InterpreterHandler.inl

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ EXDEF2_WMS(A2toXX, SetComputedNameVar, JavascriptOperat
142142
DEF2_WMS(XXtoA1, InitUndecl, OP_InitUndecl)
143143
DEF2_WMS(ELEM_RtU_to_XX, EnsureNoRootFld, OP_EnsureNoRootProperty)
144144
DEF2_WMS(ELEM_RtU_to_XX, EnsureNoRootRedeclFld, OP_EnsureNoRootRedeclProperty)
145+
EXDEF2_WMS(ELEM_RtU_to_XX, EnsureCanDeclGloFunc, OP_EnsureCanDeclGloFunc)
145146
DEF2_WMS(ELEM_C2_to_XX, ScopedEnsureNoRedeclFld, OP_ScopedEnsureNoRedeclProperty)
146147
DEF2_WMS(A1toA1Profiled, ProfiledBeginSwitch, PROFILEDOP(ProfiledSwitch<true>, ProfiledSwitch<false>))
147148
DEF2_WMS(XXtoA1Mem, LdC_A_Null, JavascriptOperators::OP_LdNull)

‎lib/Runtime/Language/InterpreterStackFrame.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -6526,6 +6526,12 @@ namespace Js
65266526
JavascriptOperators::OP_EnsureNoRootRedeclProperty(instance, this->m_functionBody->GetReferencedPropertyId(propertyIdIndex));
65276527
}
65286528

6529+
void InterpreterStackFrame::OP_EnsureCanDeclGloFunc(uint propertyIdIndex)
6530+
{
6531+
Var instance = this->GetRootObject();
6532+
JavascriptOperators::OP_EnsureCanDeclGloFunc(instance, this->m_functionBody->GetReferencedPropertyId(propertyIdIndex));
6533+
}
6534+
65296535
void InterpreterStackFrame::OP_ScopedEnsureNoRedeclProperty(Var aValue, uint propertyIdIndex, Var aValue2)
65306536
{
65316537
Js::PropertyId propertyId = this->m_functionBody->GetReferencedPropertyId(propertyIdIndex);

‎lib/Runtime/Language/InterpreterStackFrame.h

+1
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ namespace Js
656656

657657
void OP_EnsureNoRootProperty(uint propertyIdIndex);
658658
void OP_EnsureNoRootRedeclProperty(uint propertyIdIndex);
659+
void OP_EnsureCanDeclGloFunc(uint propertyIdIndex);
659660
void OP_ScopedEnsureNoRedeclProperty(Var aValue, uint propertyIdIndex, Var aValue2);
660661
Var OP_InitUndecl();
661662
void OP_InitUndeclSlot(Var aValue, int32 slot);

‎lib/Runtime/Language/JavascriptOperators.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -7572,6 +7572,15 @@ using namespace Js;
75727572
JIT_HELPER_END(Op_EnsureNoRootRedeclProperty);
75737573
}
75747574

7575+
void JavascriptOperators::OP_EnsureCanDeclGloFunc(Var instance, PropertyId propertyId)
7576+
{
7577+
JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Op_EnsureCanDeclGloFunc);
7578+
Assert(VarIs<RootObjectBase>(instance));
7579+
RootObjectBase *obj = VarTo<RootObjectBase>(instance);
7580+
obj->EnsureCanDeclGloFunc(propertyId);
7581+
JIT_HELPER_END(Op_EnsureCanDeclGloFunc);
7582+
}
7583+
75757584
void JavascriptOperators::OP_ScopedEnsureNoRedeclProperty(FrameDisplay *pDisplay, PropertyId propertyId, Var defaultInstance)
75767585
{
75777586
JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Op_EnsureNoRedeclPropertyScoped);

‎lib/Runtime/Language/JavascriptOperators.h

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ namespace Js
173173
static BOOL EnsureProperty(Var instance, PropertyId propertyId);
174174
static void OP_EnsureNoRootProperty(Var instance, PropertyId propertyId);
175175
static void OP_EnsureNoRootRedeclProperty(Var instance, PropertyId propertyId);
176+
static void OP_EnsureCanDeclGloFunc(Var instance, PropertyId propertyId);
176177
static void OP_ScopedEnsureNoRedeclProperty(FrameDisplay *pDisplay, PropertyId propertyId, Var instanceDefault);
177178
static JavascriptArray* GetOwnPropertyNames(Var instance, ScriptContext *scriptContext);
178179
static JavascriptArray* GetOwnPropertySymbols(Var instance, ScriptContext *scriptContext);

‎lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h

+131-131
Large diffs are not rendered by default.

‎lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h

+130-130
Large diffs are not rendered by default.

‎lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h

+128-128
Large diffs are not rendered by default.

‎lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h

+128-128
Large diffs are not rendered by default.

‎lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.bc.32b.h

+74-74
Large diffs are not rendered by default.

‎lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.bc.64b.h

+74-74
Large diffs are not rendered by default.

‎lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.nojit.bc.32b.h

+73-73
Large diffs are not rendered by default.

‎lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js.nojit.bc.64b.h

+73-73
Large diffs are not rendered by default.

‎lib/Runtime/Library/RootObjectBase.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ namespace Js
133133
return true;
134134
}
135135

136+
void
137+
RootObjectBase::EnsureCanDeclGloFunc(PropertyId propertyId)
138+
{
139+
// #sec-candeclareglobalfunction states that if an exisiting property is
140+
// not configurable, not writable, and not enumerable, return false.
141+
if (!IsConfigurable(propertyId) && !IsWritable(propertyId) && !IsEnumerable(propertyId))
142+
{
143+
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidGloFuncDecl,
144+
GetScriptContext()->GetPropertyName(propertyId)->GetBuffer());
145+
}
146+
}
147+
136148
BOOL
137149
RootObjectBase::HasOwnPropertyCheckNoRedecl(PropertyId propertyId)
138150
{

‎lib/Runtime/Library/RootObjectBase.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace Js
3232
virtual BOOL EnsureProperty(PropertyId propertyId) override;
3333
virtual BOOL EnsureNoRedeclProperty(PropertyId propertyId) override sealed;
3434
virtual BOOL HasOwnPropertyCheckNoRedecl(PropertyId propertyId) override sealed;
35+
void EnsureCanDeclGloFunc(PropertyId propertyId);
3536

3637
// These are special "Root" versions of the property APIs that allow access
3738
// to global let and const variables, which are stored as properties on the
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// #sec-candeclareglobalfunction states that redeclaration of global functions
7+
// that are not configurable, not writable, and not enumerable should fail.
8+
// #sec-globaldeclarationinstantiation states that if #sec-candeclareglobalfunction
9+
// fails, a TypeError should be thrown. The following properties predefined in
10+
// the global object are not configurable, not writable, and not enumerable are
11+
// undefined, Infinity, and NaN. Because these TypeErrors can only occur in the
12+
// global scope, eval statements are used. A non eval statement can be found in
13+
// CanDeclareGlobalFunctionNonEval.js
14+
15+
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
16+
17+
var tests = [
18+
{
19+
name: "Redeclaring a global function that is not configurable, not writable, and not enumerable",
20+
body: function () {
21+
assert.throws(
22+
function () {
23+
eval("function undefined(){}")
24+
},
25+
TypeError,
26+
"undefined in the global scope is not configurable, not writable, and not \
27+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
28+
"The global property undefined is not configurable, writable, \
29+
nor enumerable, therefore cannot be declared as a function"
30+
);
31+
assert.throws(
32+
function () {
33+
eval("function Infinity(){}")
34+
},
35+
TypeError,
36+
"Infinity in the global scope is not configurable, not writable, and not \
37+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
38+
"The global property Infinity is not configurable, writable, \
39+
nor enumerable, therefore cannot be declared as a function"
40+
);
41+
assert.throws(
42+
function () {
43+
eval("function NaN(){}")
44+
},
45+
TypeError,
46+
"NaN in the global scope is not configurable, not writable, and not \
47+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
48+
"The global property NaN is not configurable, writable, \
49+
nor enumerable, therefore cannot be declared as a function"
50+
);
51+
assert.throws(
52+
function () {
53+
eval(`
54+
Object.defineProperty(this, "a", {
55+
writable: false,
56+
enumerable: false,
57+
configurable: false
58+
});
59+
WScript.LoadScript("function a(){}", "self");
60+
`);
61+
},
62+
TypeError,
63+
"The property \"a\" is defined to be not configurable, not writable, and not \
64+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown when \
65+
\"a\" is defined as a function",
66+
"The global property a is not configurable, writable, \
67+
nor enumerable, therefore cannot be declared as a function"
68+
);
69+
}
70+
},
71+
{
72+
name: "Redeclaring a global async function that is not configurable, not writable, and not enumerable",
73+
body: function () {
74+
assert.throws(
75+
function () {
76+
eval("async function undefined(){}")
77+
},
78+
TypeError,
79+
"undefined in the global scope is not configurable, not writable, and not \
80+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
81+
"The global property undefined is not configurable, writable, \
82+
nor enumerable, therefore cannot be declared as a function"
83+
);
84+
assert.throws(
85+
function () {
86+
eval("async function Infinity(){}")
87+
},
88+
TypeError,
89+
"Infinity in the global scope is not configurable, not writable, and not \
90+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
91+
"The global property Infinity is not configurable, writable, \
92+
nor enumerable, therefore cannot be declared as a function"
93+
);
94+
assert.throws(
95+
function () {
96+
eval("async function NaN(){}")
97+
},
98+
TypeError,
99+
"NaN in the global scope is not configurable, not writable, and not \
100+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
101+
"The global property NaN is not configurable, writable, \
102+
nor enumerable, therefore cannot be declared as a function"
103+
);
104+
}
105+
},
106+
{
107+
name: "Redeclaring a global generator function that is not configurable, not writable, and not enumerable",
108+
body: function () {
109+
assert.throws(
110+
function () {
111+
eval("function* undefined(){}")
112+
},
113+
TypeError,
114+
"undefined in the global scope is not configurable, not writable, and not \
115+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
116+
"The global property undefined is not configurable, writable, \
117+
nor enumerable, therefore cannot be declared as a function"
118+
);
119+
assert.throws(
120+
function () {
121+
eval("function* Infinity(){}")
122+
},
123+
TypeError,
124+
"Infinity in the global scope is not configurable, not writable, and not \
125+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
126+
"The global property Infinity is not configurable, writable, \
127+
nor enumerable, therefore cannot be declared as a function"
128+
);
129+
assert.throws(
130+
function () {
131+
eval("function* NaN(){}")
132+
},
133+
TypeError,
134+
"NaN in the global scope is not configurable, not writable, and not \
135+
enumerable, thus #sec-globaldeclarationinstantiation states a TypeError should be thrown",
136+
"The global property NaN is not configurable, writable, \
137+
nor enumerable, therefore cannot be declared as a function"
138+
);
139+
}
140+
},
141+
{
142+
name: "Redeclaring a global function that is configurable, writable, or enumerable should not throw a TypeError",
143+
body: function () {
144+
eval("function Array(){}");
145+
eval("function ArrayBuffer(){}");
146+
eval("function Boolean(){}");
147+
eval("function DataView(){}");
148+
eval("function Date(){}");
149+
eval("function Function(){}");
150+
eval("function Map(){}");
151+
eval("function Math(){}");
152+
eval("function Number(){}");
153+
eval("function Object(){}");
154+
eval("function Promise(){}");
155+
eval("function RegExp(){}");
156+
eval("function Symbol(){}");
157+
eval("function TypeError(){}");
158+
eval("function Uin16Array(){}");
159+
eval("function WeakMap(){}");
160+
eval("function decodeURI(){}");
161+
eval("function escape(){}");
162+
eval("function print(){}");
163+
eval("function parseInt(){}");
164+
eval("function readbuffer(){}");
165+
eval("function readline(){}");
166+
eval("function unescape(){}");
167+
}
168+
},
169+
{
170+
name: "Redeclaring a global function that is not configurable, not writable, \
171+
and not enumerable while not in the global scope should not throw a TypeError",
172+
body: function () {
173+
function undefined() { }
174+
function Infinity() { }
175+
function NaN() { }
176+
}
177+
}
178+
]
179+
180+
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
TypeError: The global property undefined is not configurable, writable, nor enumerable, therefore cannot be declared as a function
2+
at Global code (CanDeclareGlobalFunctionNonEval.js:1:1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// #sec-candeclareglobalfunction states that redeclaration of global functions
7+
// that are not configurable, not writable, and not enumerable should fail.
8+
// #sec-globaldeclarationinstantiation states that if #sec-candeclareglobalfunction
9+
// fails, a TypeError should be thrown. The global property "undefined" is not
10+
// configurable, not writable, and not enumerable. More tests can be found in
11+
// CanDeclareGlobalFunction.js
12+
13+
function undefined() { }

‎test/GlobalFunctions/rlexe.xml

+12
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,16 @@
8383
<baseline>toString.baseline</baseline>
8484
</default>
8585
</test>
86+
<test>
87+
<default>
88+
<files>CanDeclareGlobalFunction.js</files>
89+
<compile-flags>-args summary -endargs</compile-flags>
90+
</default>
91+
</test>
92+
<test>
93+
<default>
94+
<files>CanDeclareGlobalFunctionNonEval.js</files>
95+
<baseline>CanDeclareGlobalFunctionNonEval.baseline</baseline>
96+
</default>
97+
</test>
8698
</regress-exe>

0 commit comments

Comments
 (0)
Please sign in to comment.