[es6] Implement Date.prototype[@@toPrimitive] as C++ builtin.
authorbmeurer <bmeurer@chromium.org>
Mon, 31 Aug 2015 12:52:59 +0000 (05:52 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 31 Aug 2015 12:53:10 +0000 (12:53 +0000)
This way we don't need to expose JSReceiver::OrdinaryToPrimitive
as runtime function, and we don't need the separate JS trampoline.

This also adds tests for ToPrimitive on date objects, which are
special.

R=mstarzinger@chromium.org
BUG=v8:4307
LOG=n

Review URL: https://codereview.chromium.org/1324713002

Cr-Commit-Position: refs/heads/master@{#30473}

13 files changed:
src/bootstrapper.cc
src/builtins.cc
src/builtins.h
src/compiler/linkage.cc
src/date.js
src/objects.cc
src/objects.h
src/runtime/runtime-object.cc
src/runtime/runtime.h
test/mjsunit/harmony/to-name.js
test/mjsunit/harmony/to-number.js
test/mjsunit/harmony/to-primitive.js
test/mjsunit/harmony/to-string.js

index 93f9151117605b757bbf6ef8db6d32942bd4c9bc..06bd125127a11fdb6dcde79bb14f48cf5aacd356 100644 (file)
@@ -380,26 +380,43 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) {
 }
 
 
 }
 
 
-static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
-                                          const char* name, InstanceType type,
-                                          int instance_size,
-                                          MaybeHandle<JSObject> maybe_prototype,
-                                          Builtins::Name call,
-                                          bool strict_function_map = false) {
+namespace {
+
+Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
+                                   InstanceType type, int instance_size,
+                                   MaybeHandle<JSObject> maybe_prototype,
+                                   Builtins::Name call,
+                                   PropertyAttributes attributes,
+                                   bool strict_function_map = false) {
   Isolate* isolate = target->GetIsolate();
   Factory* factory = isolate->factory();
   Isolate* isolate = target->GetIsolate();
   Factory* factory = isolate->factory();
-  Handle<String> internalized_name = factory->InternalizeUtf8String(name);
+  Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
   Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
   Handle<JSObject> prototype;
   static const bool kReadOnlyPrototype = false;
   static const bool kInstallConstructor = false;
   Handle<JSFunction> function =
       maybe_prototype.ToHandle(&prototype)
   Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
   Handle<JSObject> prototype;
   static const bool kReadOnlyPrototype = false;
   static const bool kInstallConstructor = false;
   Handle<JSFunction> function =
       maybe_prototype.ToHandle(&prototype)
-          ? factory->NewFunction(internalized_name, call_code, prototype, type,
+          ? factory->NewFunction(name_string, call_code, prototype, type,
                                  instance_size, kReadOnlyPrototype,
                                  kInstallConstructor, strict_function_map)
                                  instance_size, kReadOnlyPrototype,
                                  kInstallConstructor, strict_function_map)
-          : factory->NewFunctionWithoutPrototype(internalized_name, call_code,
+          : factory->NewFunctionWithoutPrototype(name_string, call_code,
                                                  strict_function_map);
                                                  strict_function_map);
+  JSObject::AddProperty(target, name, function, attributes);
+  if (target->IsJSGlobalObject()) {
+    function->shared()->set_instance_class_name(*name_string);
+  }
+  function->shared()->set_native(true);
+  return function;
+}
+
+
+Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name,
+                                   InstanceType type, int instance_size,
+                                   MaybeHandle<JSObject> maybe_prototype,
+                                   Builtins::Name call,
+                                   bool strict_function_map = false) {
+  Factory* const factory = target->GetIsolate()->factory();
   PropertyAttributes attributes;
   if (target->IsJSBuiltinsObject()) {
     attributes =
   PropertyAttributes attributes;
   if (target->IsJSBuiltinsObject()) {
     attributes =
@@ -407,14 +424,13 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
   } else {
     attributes = DONT_ENUM;
   }
   } else {
     attributes = DONT_ENUM;
   }
-  JSObject::AddProperty(target, internalized_name, function, attributes);
-  if (target->IsJSGlobalObject()) {
-    function->shared()->set_instance_class_name(*internalized_name);
-  }
-  function->shared()->set_native(true);
-  return function;
+  return InstallFunction(target, factory->InternalizeUtf8String(name), type,
+                         instance_size, maybe_prototype, call, attributes,
+                         strict_function_map);
 }
 
 }
 
+}  // namespace
+
 
 void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
                                             FunctionMode function_mode) {
 
 void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
                                             FunctionMode function_mode) {
@@ -2291,6 +2307,29 @@ bool Genesis::InstallNatives(ContextType context_type) {
   native_context()->set_string_function_prototype_map(
       HeapObject::cast(string_function->initial_map()->prototype())->map());
 
   native_context()->set_string_function_prototype_map(
       HeapObject::cast(string_function->initial_map()->prototype())->map());
 
+  // Install Date.prototype[@@toPrimitive].
+  {
+    Handle<String> key = factory()->Date_string();
+    Handle<JSFunction> date = Handle<JSFunction>::cast(
+        Object::GetProperty(handle(native_context()->global_object()), key)
+            .ToHandleChecked());
+    Handle<JSObject> proto =
+        Handle<JSObject>(JSObject::cast(date->instance_prototype()));
+
+    // Install the @@toPrimitive function.
+    Handle<JSFunction> to_primitive =
+        InstallFunction(proto, factory()->to_primitive_symbol(), JS_OBJECT_TYPE,
+                        JSObject::kHeaderSize, MaybeHandle<JSObject>(),
+                        Builtins::kDateToPrimitive,
+                        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
+
+    // Set the expected parameters for @@toPrimitive to 1; required by builtin.
+    to_primitive->shared()->set_internal_formal_parameter_count(1);
+
+    // Set the length for the function to satisfy ECMA-262.
+    to_primitive->shared()->set_length(1);
+  }
+
   // Install Function.prototype.call and apply.
   {
     Handle<String> key = factory()->Function_string();
   // Install Function.prototype.call and apply.
   {
     Handle<String> key = factory()->Function_string();
index 8fe53d95761c9eb24bc5fe79af56865a9c3af8bb..a9690a78307b0dfc7a1441f08d29ccbf7783832c 100644 (file)
@@ -739,6 +739,30 @@ BUILTIN(ArrayConcat) {
 }
 
 
 }
 
 
+// -----------------------------------------------------------------------------
+//
+
+
+// 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint )
+BUILTIN(DateToPrimitive) {
+  HandleScope scope(isolate);
+  DCHECK_EQ(2, args.length());
+  if (!args.receiver()->IsJSReceiver()) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
+                              isolate->factory()->NewStringFromAsciiChecked(
+                                  "Date.prototype [ @@toPrimitive ]"),
+                              args.receiver()));
+  }
+  Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
+  Handle<Object> hint = args.at<Object>(1);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     JSDate::ToPrimitive(receiver, hint));
+  return *result;
+}
+
+
 // -----------------------------------------------------------------------------
 // Throwers for restricted function properties and strict arguments object
 // properties
 // -----------------------------------------------------------------------------
 // Throwers for restricted function properties and strict arguments object
 // properties
index 5c78877803d1d8c17959872d51032f8b532ee7d5..694273afd99fa99064374f49f4030db1e045f820 100644 (file)
@@ -57,6 +57,8 @@ enum BuiltinExtraArguments {
   V(ArraySplice, NO_EXTRA_ARGUMENTS)                         \
   V(ArrayConcat, NO_EXTRA_ARGUMENTS)                         \
                                                              \
   V(ArraySplice, NO_EXTRA_ARGUMENTS)                         \
   V(ArrayConcat, NO_EXTRA_ARGUMENTS)                         \
                                                              \
+  V(DateToPrimitive, NO_EXTRA_ARGUMENTS)                     \
+                                                             \
   V(HandleApiCall, NEEDS_CALLED_FUNCTION)                    \
   V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION)           \
   V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS)             \
   V(HandleApiCall, NEEDS_CALLED_FUNCTION)                    \
   V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION)           \
   V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS)             \
index 4b4bcee585d80b2b7f7b19854b9aaea493c5c13a..3d3083004aebf036251d493a67be5c6c9764470a 100644 (file)
@@ -248,7 +248,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
     case Runtime::kInlineToPrimitive:
     case Runtime::kInlineToPrimitive_Number:
     case Runtime::kInlineToPrimitive_String:
     case Runtime::kInlineToPrimitive:
     case Runtime::kInlineToPrimitive_Number:
     case Runtime::kInlineToPrimitive_String:
-    case Runtime::kInlineOrdinaryToPrimitive:
     case Runtime::kInlineToNumber:
     case Runtime::kInlineToString:
     case Runtime::kInlineToName:
     case Runtime::kInlineToNumber:
     case Runtime::kInlineToString:
     case Runtime::kInlineToName:
index 5df3afa98b7d5207c86c525f83070ad4c12919c3..4f49565e603b0acbd0b2a8215874d4abfa410da5 100644 (file)
@@ -365,21 +365,6 @@ function DateToLocaleTimeString() {
 }
 
 
 }
 
 
-// 20.3.4.45 Date.prototype [ @@toPrimitive ] ( hint )
-function DateToPrimitive(hint) {
-  if (!IS_SPEC_OBJECT(this)) {
-    throw MakeTypeError(kIncompatibleMethodReceiver,
-                        "Date.prototype [ @@toPrimitive ]", this);
-  }
-  if (hint === "default") {
-    hint = "string";
-  } else if (hint !== "number" && hint !== "string") {
-    throw MakeTypeError(kInvalidHint, hint);
-  }
-  return %OrdinaryToPrimitive(this, hint);
-}
-
-
 // ECMA 262 - 15.9.5.8
 function DateValueOf() {
   CHECK_DATE(this);
 // ECMA 262 - 15.9.5.8
 function DateValueOf() {
   CHECK_DATE(this);
@@ -848,9 +833,6 @@ utils.InstallFunctions(GlobalDate, DONT_ENUM, [
 
 // Set up non-enumerable constructor property of the Date prototype object.
 %AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM);
 
 // Set up non-enumerable constructor property of the Date prototype object.
 %AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM);
-utils.SetFunctionName(DateToPrimitive, toPrimitiveSymbol);
-%AddNamedProperty(GlobalDate.prototype, toPrimitiveSymbol, DateToPrimitive,
-                  DONT_ENUM | READ_ONLY);
 
 // Set up non-enumerable functions of the Date prototype object and
 // set their names.
 
 // Set up non-enumerable functions of the Date prototype object and
 // set their names.
index 260a64b91d2b436c796b61493770445f6e9b154f..8d572712d9cc52923f57ba3d26ba9c2933a9da33 100644 (file)
@@ -37,6 +37,7 @@
 #include "src/objects-inl.h"
 #include "src/prototype.h"
 #include "src/safepoint-table.h"
 #include "src/objects-inl.h"
 #include "src/prototype.h"
 #include "src/safepoint-table.h"
+#include "src/string-builder.h"
 #include "src/string-search.h"
 #include "src/string-stream.h"
 #include "src/utils.h"
 #include "src/string-search.h"
 #include "src/string-stream.h"
 #include "src/utils.h"
@@ -6041,25 +6042,26 @@ MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
                     Object);
   }
                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
                     Object);
   }
-  return OrdinaryToPrimitive(receiver,
-                             (hint == ToPrimitiveHint::kString)
-                                 ? isolate->factory()->string_string()
-                                 : isolate->factory()->number_string());
+  return OrdinaryToPrimitive(receiver, (hint == ToPrimitiveHint::kString)
+                                           ? OrdinaryToPrimitiveHint::kString
+                                           : OrdinaryToPrimitiveHint::kNumber);
 }
 
 
 // static
 }
 
 
 // static
-MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(Handle<JSReceiver> receiver,
-                                                    Handle<String> hint) {
+MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
+    Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint) {
   Isolate* const isolate = receiver->GetIsolate();
   Handle<String> method_names[2];
   Isolate* const isolate = receiver->GetIsolate();
   Handle<String> method_names[2];
-  if (hint.is_identical_to(isolate->factory()->number_string())) {
-    method_names[0] = isolate->factory()->valueOf_string();
-    method_names[1] = isolate->factory()->toString_string();
-  } else {
-    DCHECK(hint.is_identical_to(isolate->factory()->string_string()));
-    method_names[0] = isolate->factory()->toString_string();
-    method_names[1] = isolate->factory()->valueOf_string();
+  switch (hint) {
+    case OrdinaryToPrimitiveHint::kNumber:
+      method_names[0] = isolate->factory()->valueOf_string();
+      method_names[1] = isolate->factory()->toString_string();
+      break;
+    case OrdinaryToPrimitiveHint::kString:
+      method_names[0] = isolate->factory()->toString_string();
+      method_names[1] = isolate->factory()->valueOf_string();
+      break;
   }
   for (Handle<String> name : method_names) {
     Handle<Object> method;
   }
   for (Handle<String> name : method_names) {
     Handle<Object> method;
@@ -8350,6 +8352,21 @@ bool String::LooksValid() {
 }
 
 
 }
 
 
+// static
+MaybeHandle<String> Name::ToFunctionName(Handle<Name> name) {
+  if (name->IsString()) return Handle<String>::cast(name);
+  // ES6 section 9.2.11 SetFunctionName, step 4.
+  Isolate* const isolate = name->GetIsolate();
+  Handle<Object> description(Handle<Symbol>::cast(name)->name(), isolate);
+  if (description->IsUndefined()) return isolate->factory()->empty_string();
+  IncrementalStringBuilder builder(isolate);
+  builder.AppendCharacter('[');
+  builder.AppendString(Handle<String>::cast(description));
+  builder.AppendCharacter(']');
+  return builder.Finish();
+}
+
+
 namespace {
 
 bool AreDigits(const uint8_t* s, int from, int to) {
 namespace {
 
 bool AreDigits(const uint8_t* s, int from, int to) {
@@ -15866,6 +15883,27 @@ void JSDate::SetValue(Object* value, bool is_value_nan) {
 }
 
 
 }
 
 
+// static
+MaybeHandle<Object> JSDate::ToPrimitive(Handle<JSReceiver> receiver,
+                                        Handle<Object> hint) {
+  Isolate* const isolate = receiver->GetIsolate();
+  if (hint->IsString()) {
+    Handle<String> hint_string = Handle<String>::cast(hint);
+    if (hint_string->Equals(isolate->heap()->number_string())) {
+      return JSReceiver::OrdinaryToPrimitive(receiver,
+                                             OrdinaryToPrimitiveHint::kNumber);
+    }
+    if (hint_string->Equals(isolate->heap()->default_string()) ||
+        hint_string->Equals(isolate->heap()->string_string())) {
+      return JSReceiver::OrdinaryToPrimitive(receiver,
+                                             OrdinaryToPrimitiveHint::kString);
+    }
+  }
+  THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kInvalidHint, hint),
+                  Object);
+}
+
+
 void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   int days = DateCache::DaysFromTime(local_time_ms);
   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
 void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
   int days = DateCache::DaysFromTime(local_time_ms);
   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
index f7aea06f9510966644b8235f3ba394fa765b3a74..03db209f13050d943702f10fffbca0a49e7b229c 100644 (file)
@@ -173,6 +173,11 @@ enum KeyedAccessStoreMode {
 enum class ToPrimitiveHint { kDefault, kNumber, kString };
 
 
 enum class ToPrimitiveHint { kDefault, kNumber, kString };
 
 
+// Valid hints for the abstract operation OrdinaryToPrimitive,
+// implemented according to ES6, section 7.1.1.
+enum class OrdinaryToPrimitiveHint { kNumber, kString };
+
+
 enum TypeofMode { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
 
 enum TypeofMode { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
 
@@ -1679,7 +1684,7 @@ class JSReceiver: public HeapObject {
       Handle<JSReceiver> receiver,
       ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
   MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
       Handle<JSReceiver> receiver,
       ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
   MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
-      Handle<JSReceiver> receiver, Handle<String> hint);
+      Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
 
   // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
   MUST_USE_RESULT static inline Maybe<bool> HasProperty(
 
   // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
   MUST_USE_RESULT static inline Maybe<bool> HasProperty(
@@ -7265,6 +7270,9 @@ class JSDate: public JSObject {
 
   void SetValue(Object* value, bool is_value_nan);
 
 
   void SetValue(Object* value, bool is_value_nan);
 
+  // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ]
+  static MUST_USE_RESULT MaybeHandle<Object> ToPrimitive(
+      Handle<JSReceiver> receiver, Handle<Object> hint);
 
   // Dispatched behavior.
   DECLARE_PRINTER(JSDate)
 
   // Dispatched behavior.
   DECLARE_PRINTER(JSDate)
@@ -8115,6 +8123,10 @@ class Name: public HeapObject {
   static inline Handle<Name> Flatten(Handle<Name> name,
                                      PretenureFlag pretenure = NOT_TENURED);
 
   static inline Handle<Name> Flatten(Handle<Name> name,
                                      PretenureFlag pretenure = NOT_TENURED);
 
+  // Return a string version of this name that is converted according to the
+  // rules described in ES6 section 9.2.11.
+  MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(Handle<Name> name);
+
   DECLARE_CAST(Name)
 
   DECLARE_PRINTER(Name)
   DECLARE_CAST(Name)
 
   DECLARE_PRINTER(Name)
index aa2e9c0744bd696a9fbbe24685f7d865404a8d47..7acffc9e1e9937aab1083951703abdac7e79a639 100644 (file)
@@ -1461,18 +1461,6 @@ RUNTIME_FUNCTION(Runtime_ToPrimitive_String) {
 }
 
 
 }
 
 
-RUNTIME_FUNCTION(Runtime_OrdinaryToPrimitive) {
-  HandleScope scope(isolate);
-  DCHECK_EQ(2, args.length());
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, hint, 1);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSReceiver::OrdinaryToPrimitive(receiver, hint));
-  return *result;
-}
-
-
 RUNTIME_FUNCTION(Runtime_ToNumber) {
   HandleScope scope(isolate);
   DCHECK_EQ(1, args.length());
 RUNTIME_FUNCTION(Runtime_ToNumber) {
   HandleScope scope(isolate);
   DCHECK_EQ(1, args.length());
index f359e8f0b4895309bd4dcf8f4ba266e6e396c228..4ae9b8846ad5054d42de92b5c9eed94e55ec43e2 100644 (file)
@@ -495,7 +495,6 @@ namespace internal {
   F(ToPrimitive, 1, 1)                               \
   F(ToPrimitive_Number, 1, 1)                        \
   F(ToPrimitive_String, 1, 1)                        \
   F(ToPrimitive, 1, 1)                               \
   F(ToPrimitive_Number, 1, 1)                        \
   F(ToPrimitive_String, 1, 1)                        \
-  F(OrdinaryToPrimitive, 2, 1)                       \
   F(ToNumber, 1, 1)                                  \
   F(ToString, 1, 1)                                  \
   F(ToName, 1, 1)                                    \
   F(ToNumber, 1, 1)                                  \
   F(ToString, 1, 1)                                  \
   F(ToName, 1, 1)                                    \
index c15bfb5d29a92f28a919e8a2f3688c6c8f58729e..6d5d64e5e418766880937fcb47357c1eb9cfd52e 100644 (file)
@@ -48,3 +48,7 @@ var d = {
 };
 assertEquals("string", %ToName(d));
 assertEquals("string", %_ToName(d));
 };
 assertEquals("string", %ToName(d));
 assertEquals("string", %_ToName(d));
+
+var e = new Date(0);
+assertEquals(e.toString(), %ToName(e));
+assertEquals(e.toString(), %_ToName(e));
index 7125766840babebb57fa9e9b14e6797635d36f89..6dc4db59a27c6ef968127b30be04f3047dc66194 100644 (file)
@@ -55,3 +55,7 @@ var d = {
 };
 assertEquals(987654321, %ToNumber(d));
 assertEquals(987654321, %_ToNumber(d));
 };
 assertEquals(987654321, %ToNumber(d));
 assertEquals(987654321, %_ToNumber(d));
+
+var e = new Date(0);
+assertEquals(0, %ToNumber(e));
+assertEquals(0, %_ToNumber(e));
index 755742519807e5d8039544d2514cf05d8f08737c..09280bf1ee7c426f775679ad2e79224c507ce7a3 100644 (file)
@@ -67,10 +67,6 @@ assertEquals("xyz", %ToPrimitive_String(a));
 assertEquals("xyz", %_ToPrimitive(a));
 assertEquals("xyz", %_ToPrimitive_Number(a));
 assertEquals("xyz", %_ToPrimitive_String(a));
 assertEquals("xyz", %_ToPrimitive(a));
 assertEquals("xyz", %_ToPrimitive_Number(a));
 assertEquals("xyz", %_ToPrimitive_String(a));
-assertEquals("xyz", %OrdinaryToPrimitive(a, "number"));
-assertEquals("xyz", %OrdinaryToPrimitive(a, "string"));
-assertEquals("xyz", %_OrdinaryToPrimitive(a, "number"));
-assertEquals("xyz", %_OrdinaryToPrimitive(a, "string"));
 
 var b = { valueOf: function() { return 42 }};
 assertEquals(42, %ToPrimitive(b));
 
 var b = { valueOf: function() { return 42 }};
 assertEquals(42, %ToPrimitive(b));
@@ -79,10 +75,6 @@ assertEquals("[object Object]", %ToPrimitive_String(b));
 assertEquals(42, %_ToPrimitive(b));
 assertEquals(42, %_ToPrimitive_Number(b));
 assertEquals("[object Object]", %_ToPrimitive_String(b));
 assertEquals(42, %_ToPrimitive(b));
 assertEquals(42, %_ToPrimitive_Number(b));
 assertEquals("[object Object]", %_ToPrimitive_String(b));
-assertEquals(42, %OrdinaryToPrimitive(b, "number"));
-assertEquals("[object Object]", %OrdinaryToPrimitive(b, "string"));
-assertEquals(42, %_OrdinaryToPrimitive(b, "number"));
-assertEquals("[object Object]", %_OrdinaryToPrimitive(b, "string"));
 
 var c = {
   toString: function() { return "x"},
 
 var c = {
   toString: function() { return "x"},
@@ -94,10 +86,6 @@ assertEquals("x", %ToPrimitive_String(c));
 assertEquals(123, %_ToPrimitive(c));
 assertEquals(123, %_ToPrimitive_Number(c));
 assertEquals("x", %_ToPrimitive_String(c));
 assertEquals(123, %_ToPrimitive(c));
 assertEquals(123, %_ToPrimitive_Number(c));
 assertEquals("x", %_ToPrimitive_String(c));
-assertEquals(123, %OrdinaryToPrimitive(c, "number"));
-assertEquals("x", %OrdinaryToPrimitive(c, "string"));
-assertEquals(123, %_OrdinaryToPrimitive(c, "number"));
-assertEquals("x", %_OrdinaryToPrimitive(c, "string"));
 
 var d = {
   [Symbol.toPrimitive]: function(hint) { return hint }
 
 var d = {
   [Symbol.toPrimitive]: function(hint) { return hint }
@@ -108,3 +96,11 @@ assertEquals("string", %ToPrimitive_String(d));
 assertEquals("default", %_ToPrimitive(d));
 assertEquals("number", %_ToPrimitive_Number(d));
 assertEquals("string", %_ToPrimitive_String(d));
 assertEquals("default", %_ToPrimitive(d));
 assertEquals("number", %_ToPrimitive_Number(d));
 assertEquals("string", %_ToPrimitive_String(d));
+
+var e = new Date(0);
+assertEquals(e.toString(), %ToPrimitive(e));
+assertEquals(0, %ToPrimitive_Number(e));
+assertEquals(e.toString(), %ToPrimitive_String(e));
+assertEquals(e.toString(), %_ToPrimitive(e));
+assertEquals(0, %_ToPrimitive_Number(e));
+assertEquals(e.toString(), %_ToPrimitive_String(e));
index 4f03c466ea4ceea8c559f406f380b4e2f99e287c..103ba89d1dca1787488eedc9684363c35b459e42 100644 (file)
@@ -48,3 +48,7 @@ var d = {
 };
 assertEquals("string", %ToString(d));
 assertEquals("string", %_ToString(d));
 };
 assertEquals("string", %ToString(d));
 assertEquals("string", %_ToString(d));
+
+var e = new Date(0);
+assertEquals(e.toString(), %ToName(e));
+assertEquals(e.toString(), %_ToName(e));