Skip to content

Commit

Permalink
Enable es6toprimitive under experimental
Browse files Browse the repository at this point in the history
Enable es6toprimitive under experimental flag.
Update following areas to be spec-compliant:

ToPrimitive (abstract operation)
Date.prototype[@@toprimitive]()
Symbol.prototype[@@toprimitive]()

Update unit tests with coverage on:

ToNumber (abstract operation)
ToString (abstract operation)
ToPropertyKey (abstract operation)
Abstract rational comparison (abstract operation)
Abstract equality comparison (abstract operation)
+ operator
Date() constructor
Date.prototype.toJSON()
  • Loading branch information
Suwei Chen committed Jul 22, 2016
1 parent e965552 commit bf80652
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 22 deletions.
5 changes: 4 additions & 1 deletion lib/Common/ConfigFlagsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,10 @@ FLAGPR (Boolean, ES6, ES6StringPrototypeFixes, "Enable ES6 String.prot
#define COMPILE_DISABLE_ES6PrototypeChain 0
#endif
FLAGPR_REGOVR_EXP(Boolean, ES6, ES6PrototypeChain , "Enable ES6 prototypes (Example: Date prototype is object)", DEFAULT_CONFIG_ES6PrototypeChain)
FLAGPR (Boolean, ES6, ES6ToPrimitive , "Enable ES6 ToPrimitive symbol" , DEFAULT_CONFIG_ES6ToPrimitive)
#ifndef COMPILE_DISABLE_ES6ToPrimitive
#define COMPILE_DISABLE_ES6ToPrimitive 0
#endif
FLAGPR_REGOVR_EXP(Boolean, ES6, ES6ToPrimitive , "Enable ES6 ToPrimitive symbol" , DEFAULT_CONFIG_ES6ToPrimitive)
FLAGPR (Boolean, ES6, ES6ToLength , "Enable ES6 ToLength fixes" , DEFAULT_CONFIG_ES6ToLength)
FLAGPR (Boolean, ES6, ES6ToStringTag , "Enable ES6 ToStringTag symbol" , DEFAULT_CONFIG_ES6ToStringTag)
FLAGPR (Boolean, ES6, ES6TypedArrayExtensions, "Enable ES6 TypedArray extensions" , DEFAULT_CONFIG_ES6TypedArrayExtensions)
Expand Down
2 changes: 1 addition & 1 deletion lib/Runtime/Language/JavascriptConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ namespace Js
}
}
// If result is an ECMAScript language value and Type(result) is not Object, then return result.
if (TaggedInt::Is(result) || JavascriptOperators::IsExposedType(JavascriptOperators::GetTypeId(result)))
if (TaggedInt::Is(result) || !JavascriptOperators::IsObjectType(JavascriptOperators::GetTypeId(result)))
{
return result;
}
Expand Down
10 changes: 5 additions & 5 deletions lib/Runtime/Library/JavascriptDate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ namespace Js
//The allowed values for hint are "default", "number", and "string"
if (args.Info.Count == 2)
{
if (!JavascriptOperators::IsObjectType(JavascriptOperators::GetTypeId(args[0])))
{
JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedObject, _u("Date[Symbol.toPrimitive]"));
}

if (JavascriptString::Is(args[1]))
{
JavascriptString* StringObject = JavascriptString::FromVar(args[1]);
Expand All @@ -267,11 +272,6 @@ namespace Js
//anything else should throw a type error
}
}
else if (args.Info.Count == 1)
{
//7.1.1 ToPrimitive Note: Date objects treat no hint as if the hint were String.
return JavascriptConversion::OrdinaryToPrimitive(args[0], JavascriptHint::HintString/*tryFirst*/, scriptContext);
}

JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_Invalid, _u("Date[Symbol.toPrimitive]"));
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Runtime/Library/JavascriptSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ namespace Js
}
else
{
JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_Invalid, _u("Symbol[Symbol.toPrimitive]"));
JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedSymbol, _u("Symbol[Symbol.toPrimitive]"));
}
}

Expand Down
12 changes: 6 additions & 6 deletions test/es6/ES6Symbol.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ var tests = [
assert.areEqual(x, Symbol.prototype[Symbol.toPrimitive].call(x), "x == Symbol.prototype[Symbol.toPrimitive].call(x)");

// TypeError scenarios
assert.throws(function () { x[Symbol.toPrimitive].call("x") }, TypeError, "x[Symbol.toPrimitive].call('x'), toPrimitive throws TypeError for values that does not have SymbolData", "Symbol[Symbol.toPrimitive]: invalid argument");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive]() }, TypeError, "toPrimitive throws TypeError if no arguments are passed", "Symbol[Symbol.toPrimitive]: invalid argument");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call("") }, TypeError, "toPrimitive throws TypeError for values that does not have SymbolData", "Symbol[Symbol.toPrimitive]: invalid argument");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call(null) }, TypeError, "toPrimitive throws TypeError for null", "Symbol[Symbol.toPrimitive]: invalid argument");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call(undefined) }, TypeError, "toPrimitive throws TypeError for undefined", "Symbol[Symbol.toPrimitive]: invalid argument");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call({}) }, TypeError, "toPrimitive throws TypeError for object", "Symbol[Symbol.toPrimitive]: invalid argument");
assert.throws(function () { x[Symbol.toPrimitive].call("x") }, TypeError, "x[Symbol.toPrimitive].call('x'), toPrimitive throws TypeError for values that does not have SymbolData", "Symbol[Symbol.toPrimitive]: 'this' is not a Symbol object");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive]() }, TypeError, "toPrimitive throws TypeError if no arguments are passed", "Symbol[Symbol.toPrimitive]: 'this' is not a Symbol object");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call("") }, TypeError, "toPrimitive throws TypeError for values that does not have SymbolData", "Symbol[Symbol.toPrimitive]: 'this' is not a Symbol object");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call(null) }, TypeError, "toPrimitive throws TypeError for null", "Symbol[Symbol.toPrimitive]: 'this' is not a Symbol object");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call(undefined) }, TypeError, "toPrimitive throws TypeError for undefined", "Symbol[Symbol.toPrimitive]: 'this' is not a Symbol object");
assert.throws(function () { Symbol.prototype[Symbol.toPrimitive].call({}) }, TypeError, "toPrimitive throws TypeError for object", "Symbol[Symbol.toPrimitive]: 'this' is not a Symbol object");

var z = Object(y);
assert.areEqual(y, Symbol.prototype[Symbol.toPrimitive].call(z), "y == Symbol.prototype[Symbol.toPrimitive].call(z)");
Expand Down
2 changes: 1 addition & 1 deletion test/es6/rlexe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<test>
<default>
<files>toPrimitive.js</files>
<compile-flags>-es6toprimitive -es6functionname -args summary -endargs</compile-flags>
<compile-flags>-es6regexsymbols -es6toprimitive -es6hasInstance -es6isconcatspreadable -es6tostringtag -es6functionname -args summary -endargs</compile-flags>
</default>
</test>
<test>
Expand Down
Loading

0 comments on commit bf80652

Please sign in to comment.