Revision: 24472
Author:   [email protected]
Date:     Wed Oct  8 14:48:48 2014 UTC
Log:      Classes: Add support for toString

BUG=v8:3330
LOG=Y
[email protected]

Review URL: https://codereview.chromium.org/624013005
https://code.google.com/p/v8/source/detail?r=24472

Modified:
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/full-codegen.cc
 /branches/bleeding_edge/src/heap/heap.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/preparser.h
 /branches/bleeding_edge/src/runtime/runtime-classes.cc
 /branches/bleeding_edge/src/runtime/runtime.h
 /branches/bleeding_edge/src/v8natives.js
 /branches/bleeding_edge/test/mjsunit/harmony/classes.js

=======================================
--- /branches/bleeding_edge/src/ast.h   Wed Oct  8 09:15:09 2014 UTC
+++ /branches/bleeding_edge/src/ast.h   Wed Oct  8 14:48:48 2014 UTC
@@ -2536,22 +2536,26 @@
   Expression* extends() const { return extends_; }
   Expression* constructor() const { return constructor_; }
   ZoneList<Property*>* properties() const { return properties_; }
+  int start_position() const { return position(); }
+  int end_position() const { return end_position_; }

  protected:
   ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
                Expression* constructor, ZoneList<Property*>* properties,
-               int position, IdGen* id_gen)
-      : Expression(zone, position, id_gen),
+               int start_position, int end_position, IdGen* id_gen)
+      : Expression(zone, start_position, id_gen),
         raw_name_(name),
         extends_(extends),
         constructor_(constructor),
-        properties_(properties) {}
+        properties_(properties),
+        end_position_(end_position) {}

  private:
   const AstRawString* raw_name_;
   Expression* extends_;
   Expression* constructor_;
   ZoneList<Property*>* properties_;
+  int end_position_;
 };


@@ -3550,9 +3554,10 @@
ClassLiteral* NewClassLiteral(const AstRawString* name, Expression* extends,
                                 Expression* constructor,
ZoneList<ObjectLiteral::Property*>* properties,
-                                int position) {
-    ClassLiteral* lit = new (zone_) ClassLiteral(
-        zone_, name, extends, constructor, properties, position, id_gen_);
+                                int start_position, int end_position) {
+    ClassLiteral* lit =
+ new (zone_) ClassLiteral(zone_, name, extends, constructor, properties,
+                                 start_position, end_position, id_gen_);
     VISIT_AND_RETURN(ClassLiteral, lit)
   }

=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Tue Oct  7 16:24:59 2014 UTC
+++ /branches/bleeding_edge/src/full-codegen.cc Wed Oct  8 14:48:48 2014 UTC
@@ -1541,30 +1541,34 @@
 }


-void FullCodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
+void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
   Comment cmnt(masm_, "[ ClassLiteral");

-  if (expr->raw_name() != NULL) {
-    __ Push(expr->name());
+  if (lit->raw_name() != NULL) {
+    __ Push(lit->name());
   } else {
     __ Push(isolate()->factory()->undefined_value());
   }

-  if (expr->extends() != NULL) {
-    VisitForStackValue(expr->extends());
+  if (lit->extends() != NULL) {
+    VisitForStackValue(lit->extends());
   } else {
     __ Push(isolate()->factory()->the_hole_value());
   }

-  if (expr->constructor() != NULL) {
-    VisitForStackValue(expr->constructor());
+  if (lit->constructor() != NULL) {
+    VisitForStackValue(lit->constructor());
   } else {
     __ Push(isolate()->factory()->undefined_value());
   }
+
+  __ Push(script());
+  __ Push(Smi::FromInt(lit->start_position()));
+  __ Push(Smi::FromInt(lit->end_position()));

   // TODO(arv): Process methods

-  __ CallRuntime(Runtime::kDefineClass, 3);
+  __ CallRuntime(Runtime::kDefineClass, 6);
   context()->Plug(result_register());
 }

=======================================
--- /branches/bleeding_edge/src/heap/heap.h     Wed Oct  8 11:51:57 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.h     Wed Oct  8 14:48:48 2014 UTC
@@ -340,7 +340,10 @@
   V(intl_initialized_marker_symbol) \
   V(intl_impl_object_symbol)        \
   V(promise_debug_marker_symbol)    \
-  V(promise_has_handler_symbol)
+  V(promise_has_handler_symbol)     \
+  V(class_script_symbol)            \
+  V(class_start_position_symbol)    \
+  V(class_end_position_symbol)

 // Forward declarations.
 class HeapStats;
=======================================
--- /branches/bleeding_edge/src/parser.cc       Tue Oct  7 16:24:59 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Wed Oct  8 14:48:48 2014 UTC
@@ -648,9 +648,10 @@

 Expression* ParserTraits::ClassExpression(
     const AstRawString* name, Expression* extends, Expression* constructor,
-    ZoneList<ObjectLiteral::Property*>* properties, int pos,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
- return factory->NewClassLiteral(name, extends, constructor, properties, pos);
+    ZoneList<ObjectLiteral::Property*>* properties, int start_position,
+    int end_position, AstNodeFactory<AstConstructionVisitor>* factory) {
+  return factory->NewClassLiteral(name, extends, constructor, properties,
+                                  start_position, end_position);
 }

 Literal* ParserTraits::ExpressionFromLiteral(
=======================================
--- /branches/bleeding_edge/src/parser.h        Tue Oct  7 16:24:59 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Wed Oct  8 14:48:48 2014 UTC
@@ -558,7 +558,7 @@
Expression* ClassExpression(const AstRawString* name, Expression* extends,
                               Expression* constructor,
ZoneList<ObjectLiteral::Property*>* properties,
-                              int pos,
+                              int start_position, int end_position,
AstNodeFactory<AstConstructionVisitor>* factory);

   Literal* ExpressionFromLiteral(
=======================================
--- /branches/bleeding_edge/src/preparser.h     Tue Oct  7 16:24:59 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h     Wed Oct  8 14:48:48 2014 UTC
@@ -1102,7 +1102,7 @@
                                       PreParserExpression extends,
                                       PreParserExpression constructor,
                                       PreParserExpressionList properties,
-                                      int position) {
+ int start_position, int end_position) {
     return PreParserExpression::Default();
   }

@@ -1334,12 +1334,10 @@
     return PreParserExpression::Super();
   }

-  static PreParserExpression ClassExpression(PreParserIdentifier name,
-                                             PreParserExpression extends,
- PreParserExpression constructor, - PreParserExpressionList properties,
-                                             int position,
-                                             PreParserFactory* factory) {
+  static PreParserExpression ClassExpression(
+      PreParserIdentifier name, PreParserExpression extends,
+      PreParserExpression constructor, PreParserExpressionList properties,
+      int start_position, int end_position, PreParserFactory* factory) {
     return PreParserExpression::Default();
   }

@@ -2805,10 +2803,12 @@
       fni_->Leave();
     }
   }
+
+  int end_pos = peek_position();
   Expect(Token::RBRACE, CHECK_OK);

   return this->ClassExpression(name, extends, constructor, properties, pos,
-                               factory());
+                               end_pos + 1, factory());
 }


=======================================
--- /branches/bleeding_edge/src/runtime/runtime-classes.cc Tue Oct 7 16:24:59 2014 UTC +++ /branches/bleeding_edge/src/runtime/runtime-classes.cc Wed Oct 8 14:48:48 2014 UTC
@@ -155,10 +155,13 @@

 RUNTIME_FUNCTION(Runtime_DefineClass) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
+  DCHECK(args.length() == 6);
   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
   CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1);
   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Script, script, 3);
+  CONVERT_SMI_ARG_CHECKED(start_position, 4);
+  CONVERT_SMI_ARG_CHECKED(end_position, 5);

   Handle<Object> prototype_parent;
   Handle<Object> constructor_parent;
@@ -228,7 +231,58 @@
JSObject::AddProperty(prototype, isolate->factory()->constructor_string(),
                         ctor, DONT_ENUM);

+ // Install private properties that are used to construct the FunctionToString.
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate,
+      Object::SetProperty(ctor, isolate->factory()->class_script_symbol(),
+                          script, STRICT));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, Object::SetProperty(
+                   ctor, isolate->factory()->class_start_position_symbol(),
+                   handle(Smi::FromInt(start_position), isolate), STRICT));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate,
+ Object::SetProperty(ctor, isolate->factory()->class_end_position_symbol(), + handle(Smi::FromInt(end_position), isolate), STRICT));
+
   return *ctor;
 }
+
+
+RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+
+  Handle<Object> script;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, script,
+      Object::GetProperty(fun, isolate->factory()->class_script_symbol()));
+  if (!script->IsScript()) {
+    return isolate->heap()->undefined_value();
+  }
+
+  Handle<Symbol> start_position_symbol(
+      isolate->heap()->class_start_position_symbol());
+  Handle<Object> start_position;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, start_position, Object::GetProperty(fun, start_position_symbol));
+
+  Handle<Symbol> end_position_symbol(
+      isolate->heap()->class_end_position_symbol());
+  Handle<Object> end_position;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, end_position, Object::GetProperty(fun, end_position_symbol));
+
+  if (!start_position->IsSmi() || !end_position->IsSmi() ||
+      !Handle<Script>::cast(script)->HasValidSource()) {
+    return isolate->ThrowIllegalOperation();
+  }
+
+ Handle<String> source(String::cast(Handle<Script>::cast(script)->source()));
+  return *isolate->factory()->NewSubString(
+      source, Handle<Smi>::cast(start_position)->value(),
+      Handle<Smi>::cast(end_position)->value());
+}
 }
 }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/runtime/runtime.h Tue Oct 7 16:24:59 2014 UTC +++ /branches/bleeding_edge/src/runtime/runtime.h Wed Oct 8 14:48:48 2014 UTC
@@ -193,7 +193,8 @@
   F(LoadKeyedFromSuper, 3, 1)                              \
   F(StoreToSuper_Strict, 4, 1)                             \
   F(StoreToSuper_Sloppy, 4, 1)                             \
-  F(DefineClass, 3, 1)
+  F(DefineClass, 6, 1)                                     \
+  F(ClassGetSourceCode, 1, 1)


 #define RUNTIME_FUNCTION_LIST_ALWAYS_2(F)              \
=======================================
--- /branches/bleeding_edge/src/v8natives.js    Mon Sep 29 07:30:41 2014 UTC
+++ /branches/bleeding_edge/src/v8natives.js    Wed Oct  8 14:48:48 2014 UTC
@@ -1738,6 +1738,11 @@
   if (!IS_FUNCTION(func)) {
     throw new $TypeError('Function.prototype.toString is not generic');
   }
+
+  var classSource = %ClassGetSourceCode(func);
+  if (IS_STRING(classSource)) {
+    return classSource;
+  }

   var source = %FunctionGetSourceCode(func);
   if (!IS_STRING(source) || %FunctionIsBuiltin(func)) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/classes.js Tue Oct 7 16:24:59 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/harmony/classes.js Wed Oct 8 14:48:48 2014 UTC
@@ -165,3 +165,15 @@
   new C();
 })();
 */
+
+
+(function TestToString() {
+  class C {}
+  assertEquals('class C {}', C.toString());
+
+  class D { constructor() { 42; } }
+  assertEquals('class D { constructor() { 42; } }', D.toString());
+
+  class E { x() { 42; } }
+  assertEquals('class E { x() { 42; } }', E.toString());
+})();

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to