Revision: 22089
Author:   [email protected]
Date:     Mon Jun 30 11:48:20 2014 UTC
Log:      Fix stack trace accessor behavior.

[email protected]
BUG=v8:3404
LOG=N

Review URL: https://codereview.chromium.org/343563009
http://code.google.com/p/v8/source/detail?r=22089

Added:
 /branches/bleeding_edge/test/mjsunit/regress/regress-3404.js
Deleted:
/branches/bleeding_edge/test/mjsunit/runtime-gen/getandclearoverflowedstacktrace.js
Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/messages.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/test/mjsunit/runtime-gen/collectstacktrace.js
 /branches/bleeding_edge/test/mjsunit/stack-traces-overflow.js
 /branches/bleeding_edge/test/mjsunit/stack-traces.js
 /branches/bleeding_edge/tools/generate-runtime-tests.py

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-3404.js Mon Jun 30 11:48:20 2014 UTC
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function testError(error) {
+  // Reconfigure e.stack to be non-configurable
+  var desc1 = Object.getOwnPropertyDescriptor(error, "stack");
+  Object.defineProperty(error, "stack",
+ {get: desc1.get, set: desc1.set, configurable: false});
+
+  var desc2 = Object.getOwnPropertyDescriptor(error, "stack");
+  assertFalse(desc2.configurable);
+  assertEquals(desc1.get, desc2.get);
+  assertEquals(desc2.get, desc2.get);
+}
+
+function stackOverflow() {
+  function f() { f(); }
+  try { f() } catch (e) { return e; }
+}
+
+function referenceError() {
+  try { g() } catch (e) { return e; }
+}
+
+testError(referenceError());
+testError(stackOverflow());
=======================================
--- /branches/bleeding_edge/test/mjsunit/runtime-gen/getandclearoverflowedstacktrace.js Thu May 8 13:11:59 2014 UTC
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
-// Flags: --allow-natives-syntax --harmony
-var _error_object = new Object();
-%GetAndClearOverflowedStackTrace(_error_object);
=======================================
--- /branches/bleeding_edge/include/v8.h        Mon Jun 30 10:19:31 2014 UTC
+++ /branches/bleeding_edge/include/v8.h        Mon Jun 30 11:48:20 2014 UTC
@@ -5586,7 +5586,7 @@
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 160;
+  static const int kEmptyStringRootIndex = 162;

// The external allocation limit should be below 256 MB on all architectures
   // to avoid that resource-constrained embedders run low on memory.
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Fri Jun 27 13:48:37 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Mon Jun 30 11:48:20 2014 UTC
@@ -2210,6 +2210,17 @@
             Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE),
         false);
   }
+
+  // Expose the stack trace symbol to native JS.
+  RETURN_ON_EXCEPTION_VALUE(
+      isolate,
+      JSObject::SetOwnPropertyIgnoreAttributes(
+          handle(native_context->builtins(), isolate),
+          factory->InternalizeOneByteString(
+              STATIC_ASCII_VECTOR("stack_trace_symbol")),
+          factory->stack_trace_symbol(),
+          NONE),
+      false);

// Expose the debug global object in global if a name for it is specified.
   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Jun 30 10:19:31 2014 UTC
+++ /branches/bleeding_edge/src/heap.cc Mon Jun 30 11:48:20 2014 UTC
@@ -2917,6 +2917,8 @@
   set_uninitialized_symbol(*factory->NewPrivateSymbol());
   set_megamorphic_symbol(*factory->NewPrivateSymbol());
   set_observed_symbol(*factory->NewPrivateSymbol());
+  set_stack_trace_symbol(*factory->NewPrivateSymbol());
+  set_detailed_stack_trace_symbol(*factory->NewPrivateSymbol());

   Handle<SeededNumberDictionary> slow_element_dictionary =
       SeededNumberDictionary::New(isolate(), 0, TENURED);
=======================================
--- /branches/bleeding_edge/src/heap.h  Mon Jun 30 10:19:31 2014 UTC
+++ /branches/bleeding_edge/src/heap.h  Mon Jun 30 11:48:20 2014 UTC
@@ -193,6 +193,8 @@
V(Symbol, observed_symbol, ObservedSymbol) \ V(Symbol, uninitialized_symbol, UninitializedSymbol) \ V(Symbol, megamorphic_symbol, MegamorphicSymbol) \ + V(Symbol, stack_trace_symbol, StackTraceSymbol) \ + V(Symbol, detailed_stack_trace_symbol, DetailedStackTraceSymbol) \ V(FixedArray, materialized_objects, MaterializedObjects) \ V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad) \
   V(FixedArray, microtask_queue, MicrotaskQueue)
@@ -340,7 +342,6 @@
   V(strict_compare_ic_string, "===")                                     \
   V(infinity_string, "Infinity")                                         \
   V(minus_infinity_string, "-Infinity")                                  \
-  V(hidden_stack_trace_string, "v8::hidden_stack_trace")                 \
   V(query_colon_string, "(?:)")                                          \
   V(Generator_string, "Generator")                                       \
   V(throw_string, "throw")                                               \
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Mon Jun 30 06:45:23 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc      Mon Jun 30 11:48:20 2014 UTC
@@ -353,10 +353,23 @@
 }


-Handle<JSArray> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object,
-                                                 Handle<Object> caller,
-                                                 int limit) {
+Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object,
+                                                Handle<Object> caller) {
+  // Get stack trace limit.
+  Handle<Object> error = Object::GetProperty(
+      this, js_builtins_object(), "$Error").ToHandleChecked();
+  if (!error->IsJSObject()) return factory()->undefined_value();
+
+  Handle<String> stackTraceLimit =
+      factory()->InternalizeUtf8String("stackTraceLimit");
+  ASSERT(!stackTraceLimit.is_null());
+  Handle<Object> stack_trace_limit =
+      JSObject::GetDataProperty(Handle<JSObject>::cast(error),
+                                stackTraceLimit);
+  if (!stack_trace_limit->IsNumber()) return factory()->undefined_value();
+  int limit = FastD2IChecked(stack_trace_limit->Number());
   limit = Max(limit, 0);  // Ensure that limit is not negative.
+
   int initial_size = Min(limit, 10);
   Handle<FixedArray> elements =
       factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
@@ -426,13 +439,23 @@
void Isolate::CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object) {
   if (capture_stack_trace_for_uncaught_exceptions_) {
     // Capture stack trace for a detailed exception message.
-    Handle<String> key = factory()->hidden_stack_trace_string();
+    Handle<Name> key = factory()->detailed_stack_trace_symbol();
     Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
         stack_trace_for_uncaught_exceptions_frame_limit_,
         stack_trace_for_uncaught_exceptions_options_);
-    JSObject::SetHiddenProperty(error_object, key, stack_trace);
+    JSObject::SetProperty(
+        error_object, key, stack_trace, NONE, STRICT).Assert();
   }
 }
+
+
+void Isolate::CaptureAndSetSimpleStackTrace(Handle<JSObject> error_object,
+                                            Handle<Object> caller) {
+  // Capture stack trace for simple stack trace string formatting.
+  Handle<Name> key = factory()->stack_trace_symbol();
+ Handle<Object> stack_trace = CaptureSimpleStackTrace(error_object, caller); + JSObject::SetProperty(error_object, key, stack_trace, NONE, STRICT).Assert();
+}


 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
@@ -780,25 +803,7 @@
   Handle<JSObject> exception = factory()->CopyJSObject(boilerplate);
   DoThrow(*exception, NULL);

-  // Get stack trace limit.
-  Handle<Object> error = Object::GetProperty(
-      this, js_builtins_object(), "$Error").ToHandleChecked();
-  if (!error->IsJSObject()) return heap()->exception();
-
-  Handle<String> stackTraceLimit =
-      factory()->InternalizeUtf8String("stackTraceLimit");
-  ASSERT(!stackTraceLimit.is_null());
-  Handle<Object> stack_trace_limit =
-      JSObject::GetDataProperty(Handle<JSObject>::cast(error),
-                                stackTraceLimit);
-  if (!stack_trace_limit->IsNumber()) return heap()->exception();
-  int limit = FastD2IChecked(stack_trace_limit->Number());
-  if (limit < 0) limit = 0;
-  Handle<JSArray> stack_trace = CaptureSimpleStackTrace(
-      exception, factory()->undefined_value(), limit);
-  JSObject::SetHiddenProperty(exception,
-                              factory()->hidden_stack_trace_string(),
-                              stack_trace);
+  CaptureAndSetSimpleStackTrace(exception, factory()->undefined_value());
   return heap()->exception();
 }

@@ -1054,13 +1059,16 @@
       if (capture_stack_trace_for_uncaught_exceptions_) {
         if (IsErrorObject(exception_handle)) {
// We fetch the stack trace that corresponds to this error object.
-          Handle<String> key = factory()->hidden_stack_trace_string();
-          Object* stack_property =
-              JSObject::cast(*exception_handle)->GetHiddenProperty(key);
- // Property lookup may have failed. In this case it's probably not
-          // a valid Error object.
-          if (stack_property->IsJSArray()) {
- stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
+          Handle<Name> key = factory()->detailed_stack_trace_symbol();
+ // Look up as own property. If the lookup fails, the exception is + // probably not a valid Error object. In that case, we fall through
+          // and capture the stack trace at this throw site.
+          LookupIterator lookup(
+              exception_handle, key, LookupIterator::CHECK_OWN_REAL);
+          Handle<Object> stack_trace_property;
+ if (Object::GetProperty(&lookup).ToHandle(&stack_trace_property) &&
+              stack_trace_property->IsJSArray()) {
+ stack_trace_object = Handle<JSArray>::cast(stack_trace_property);
           }
         }
         if (stack_trace_object.is_null()) {
=======================================
--- /branches/bleeding_edge/src/isolate.h       Mon Jun 30 06:45:23 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h       Mon Jun 30 11:48:20 2014 UTC
@@ -697,11 +697,11 @@
   Handle<JSArray> CaptureCurrentStackTrace(
       int frame_limit,
       StackTrace::StackTraceOptions options);
-
-  Handle<JSArray> CaptureSimpleStackTrace(Handle<JSObject> error_object,
-                                          Handle<Object> caller,
-                                          int limit);
+  Handle<Object> CaptureSimpleStackTrace(Handle<JSObject> error_object,
+                                         Handle<Object> caller);
   void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
+  void CaptureAndSetSimpleStackTrace(Handle<JSObject> error_object,
+                                     Handle<Object> caller);

   // Returns if the top context may access the given global object. If
   // the result is false, the pending exception is guaranteed to be
=======================================
--- /branches/bleeding_edge/src/messages.js     Fri Jun 27 13:48:37 2014 UTC
+++ /branches/bleeding_edge/src/messages.js     Mon Jun 30 11:48:20 2014 UTC
@@ -1080,7 +1080,8 @@
 var formatting_custom_stack_trace = false;


-function FormatStackTrace(obj, error_string, frames) {
+function FormatStackTrace(obj, raw_stack) {
+  var frames = GetStackFrames(raw_stack);
if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) {
     var array = [];
     %MoveArrayContents(frames, array);
@@ -1097,7 +1098,7 @@
   }

   var lines = new InternalArray();
-  lines.push(error_string);
+  lines.push(FormatErrorString(obj));
   for (var i = 0; i < frames.length; i++) {
     var frame = frames[i];
     var line;
@@ -1132,45 +1133,45 @@
 }


-function captureStackTrace(obj, cons_opt) {
-  var stackTraceLimit = $Error.stackTraceLimit;
-  if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return;
-  if (stackTraceLimit < 0 || stackTraceLimit > 10000) {
-    stackTraceLimit = 10000;
-  }
-  var stack = %CollectStackTrace(obj,
-                                 cons_opt ? cons_opt : captureStackTrace,
-                                 stackTraceLimit);
+var stack_trace_symbol;  // Set during bootstrapping.
+var formatted_stack_trace_symbol = NEW_PRIVATE("formatted stack trace");

-  var error_string = FormatErrorString(obj);

- // Set the 'stack' property on the receiver. If the receiver is the same as - // holder of this setter, the accessor pair is turned into a data property.
-  var setter = function(v) {
-    // Set data property on the receiver (not necessarily holder).
-    %DefineDataPropertyUnchecked(this, 'stack', v, NONE);
-    if (this === obj) {
-      // Release context values if holder is the same as the receiver.
-      stack = error_string = UNDEFINED;
+// Format the stack trace if not yet done, and return it.
+// Cache the formatted stack trace on the holder.
+function StackTraceGetter() {
+ var formatted_stack_trace = GET_PRIVATE(this, formatted_stack_trace_symbol);
+  if (IS_UNDEFINED(formatted_stack_trace)) {
+    var holder = this;
+    while (!HAS_PRIVATE(holder, stack_trace_symbol)) {
+      holder = %GetPrototype(holder);
+      if (!holder) return UNDEFINED;
     }
-  };
+    var stack_trace = GET_PRIVATE(holder, stack_trace_symbol);
+    if (IS_UNDEFINED(stack_trace)) return UNDEFINED;
+    formatted_stack_trace = FormatStackTrace(holder, stack_trace);
+    SET_PRIVATE(holder, stack_trace_symbol, UNDEFINED);
+ SET_PRIVATE(holder, formatted_stack_trace_symbol, formatted_stack_trace);
+  }
+  return formatted_stack_trace;
+};

-  // The holder of this getter ('obj') may not be the receiver ('this').
- // When this getter is called the first time, we use the context values to
-  // format a stack trace string and turn this accessor pair into a data
-  // property (on the holder).
-  var getter = function() {
-    // Stack is still a raw array awaiting to be formatted.
- var result = FormatStackTrace(obj, error_string, GetStackFrames(stack));
-    // Replace this accessor to return result directly.
-    %DefineAccessorPropertyUnchecked(
-        obj, 'stack', function() { return result }, setter, DONT_ENUM);
-    // Release context values.
-    stack = error_string = UNDEFINED;
-    return result;
-  };
+
+// If the receiver equals the holder, set the formatted stack trace that the
+// getter returns.
+function StackTraceSetter(v) {
+  if (HAS_PRIVATE(this, stack_trace_symbol)) {
+    SET_PRIVATE(this, stack_trace_symbol, UNDEFINED);
+    SET_PRIVATE(this, formatted_stack_trace_symbol, v);
+  }
+};
+

- %DefineAccessorPropertyUnchecked(obj, 'stack', getter, setter, DONT_ENUM);
+function captureStackTrace(obj, cons_opt) {
+  // Define accessors first, as this may fail and throw.
+  ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
+                                       set: StackTraceSetter});
+  %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
 }


@@ -1306,40 +1307,8 @@
 function SetUpStackOverflowBoilerplate() {
   var boilerplate = MakeRangeError('stack_overflow', []);

-  var error_string = boilerplate.name + ": " + boilerplate.message;
-
- // Set the 'stack' property on the receiver. If the receiver is the same as - // holder of this setter, the accessor pair is turned into a data property.
-  var setter = function(v) {
-    %DefineDataPropertyUnchecked(this, 'stack', v, NONE);
- // Tentatively clear the hidden property. If the receiver is the same as
-    // holder, we release the raw stack trace this way.
-    %GetAndClearOverflowedStackTrace(this);
-  };
-
- // The raw stack trace is stored as a hidden property on the holder of this
-  // getter, which may not be the same as the receiver.  Find the holder to
-  // retrieve the raw stack trace and then turn this accessor pair into a
-  // data property.
-  var getter = function() {
-    var holder = this;
-    while (!IS_ERROR(holder)) {
-      holder = %GetPrototype(holder);
-      if (IS_NULL(holder)) return MakeSyntaxError('illegal_access', []);
-    }
-    var stack = %GetAndClearOverflowedStackTrace(holder);
-    // We may not have captured any stack trace.
-    if (IS_UNDEFINED(stack)) return stack;
-
- var result = FormatStackTrace(holder, error_string, GetStackFrames(stack));
-    // Replace this accessor to return result directly.
-    %DefineAccessorPropertyUnchecked(
-        holder, 'stack', function() { return result }, setter, DONT_ENUM);
-    return result;
-  };
-
   %DefineAccessorPropertyUnchecked(
-      boilerplate, 'stack', getter, setter, DONT_ENUM);
+      boilerplate, 'stack', StackTraceGetter, StackTraceSetter, DONT_ENUM);

   return boilerplate;
 }
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Jun 30 11:12:42 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Mon Jun 30 11:48:20 2014 UTC
@@ -14428,30 +14428,15 @@
 // native code offset.
 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 3);
+  ASSERT(args.length() == 2);
   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
-  CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);

   // Optionally capture a more detailed stack trace for the message.
   isolate->CaptureAndSetDetailedStackTrace(error_object);
   // Capture a simple stack trace for the stack property.
-  return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
-}
-
-
-// Retrieve the stack trace.  This is the raw stack trace that yet has to
-// be formatted.  Since we only need this once, clear it afterwards.
-RUNTIME_FUNCTION(Runtime_GetAndClearOverflowedStackTrace) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
-  Handle<String> key = isolate->factory()->hidden_stack_trace_string();
-  Handle<Object> result(error_object->GetHiddenProperty(key), isolate);
-  if (result->IsTheHole()) return isolate->heap()->undefined_value();
-  RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
-  JSObject::DeleteHiddenProperty(error_object, key);
-  return *result;
+  isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
+  return isolate->heap()->undefined_value();
 }


=======================================
--- /branches/bleeding_edge/src/runtime.h       Mon Jun 30 11:12:42 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Mon Jun 30 11:48:20 2014 UTC
@@ -196,8 +196,7 @@
   F(FunctionIsAPIFunction, 1, 1) \
   F(FunctionIsBuiltin, 1, 1) \
   F(GetScript, 1, 1) \
-  F(CollectStackTrace, 3, 1) \
-  F(GetAndClearOverflowedStackTrace, 1, 1) \
+  F(CollectStackTrace, 2, 1) \
   F(GetV8Version, 0, 1) \
   \
   F(SetCode, 2, 1) \
=======================================
--- /branches/bleeding_edge/test/mjsunit/runtime-gen/collectstacktrace.js Thu May 8 13:11:59 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/runtime-gen/collectstacktrace.js Mon Jun 30 11:48:20 2014 UTC
@@ -3,5 +3,4 @@
 // Flags: --allow-natives-syntax --harmony
 var _error_object = new Object();
 var _caller = new Object();
-var _limit = 32;
-%CollectStackTrace(_error_object, _caller, _limit);
+%CollectStackTrace(_error_object, _caller);
=======================================
--- /branches/bleeding_edge/test/mjsunit/stack-traces-overflow.js Fri Jun 20 14:27:55 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/stack-traces-overflow.js Mon Jun 30 11:48:20 2014 UTC
@@ -61,8 +61,8 @@
 function testErrorPrototype(prototype) {
   var object = {};
   object.__proto__ = prototype;
-  object.stack = "123";
-  assertEquals("123", object.stack);
+  object.stack = "123";  // Overwriting stack property fails.
+  assertEquals(prototype.stack, object.stack);
   assertTrue("123" != prototype.stack);
 }

@@ -126,6 +126,8 @@
   rec1(0);
 } catch (e) {
   assertEquals(undefined, e.stack);
+  e.stack = "abc";
+  assertEquals("abc", e.stack);
 }

 Error.stackTraceLimit = 3;
=======================================
--- /branches/bleeding_edge/test/mjsunit/stack-traces.js Fri Jul 26 11:28:08 2013 UTC +++ /branches/bleeding_edge/test/mjsunit/stack-traces.js Mon Jun 30 11:48:20 2014 UTC
@@ -331,3 +331,23 @@
 new Error().stack;

 assertEquals("custom", Error.prepareStackTrace);
+
+// Check that the formatted stack trace can be set to undefined.
+error = new Error();
+error.stack = undefined;
+assertEquals(undefined, error.stack);
+
+// Check that the stack trace accessors are not forcibly set.
+var my_error = {};
+Object.freeze(my_error);
+assertThrows(function() { Error.captureStackTrace(my_error); });
+
+my_error = {};
+Object.preventExtensions(my_error);
+assertThrows(function() { Error.captureStackTrace(my_error); });
+
+var fake_error = {};
+my_error = new Error();
+var stolen_getter = Object.getOwnPropertyDescriptor(my_error, 'stack').get;
+Object.defineProperty(fake_error, 'stack', { get: stolen_getter });
+assertEquals(undefined, fake_error.stack);
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Mon Jun 30 11:12:42 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Mon Jun 30 11:48:20 2014 UTC
@@ -47,11 +47,11 @@
# that the parser doesn't bit-rot. Change the values as needed when you add, # remove or change runtime functions, but make sure we don't lose our ability
 # to parse them!
-EXPECTED_FUNCTION_COUNT = 416
-EXPECTED_FUZZABLE_COUNT = 331
+EXPECTED_FUNCTION_COUNT = 415
+EXPECTED_FUZZABLE_COUNT = 330
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 4
-EXPECTED_BUILTINS_COUNT = 809
+EXPECTED_BUILTINS_COUNT = 811


 # Don't call these at all.

--
--
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