Reviewers: rossberg,

Message:
PTAL.

Description:
Harden a few builtins

Introducing BUILTIN_ASSERT, builtins' equivalent of RUNTIME_ASSERT.

Please review this at https://codereview.chromium.org/292173011/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+34, -15 lines):
  M src/macros.py
  M src/messages.js
  M src/objects.cc
  M src/promise.js
  M src/runtime.h
  M src/runtime.cc
  M src/uri.js
  A + test/mjsunit/runtime-gen/issequentialstring.js
  M tools/generate-runtime-tests.py


Index: src/macros.py
diff --git a/src/macros.py b/src/macros.py
index 39881fe76317401b93698e358f5b0d922db5bbc4..ed0d7afa65fbd13cd1ec16a3de36bdfb9302e2ee 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -128,6 +128,7 @@ macro IS_DATAVIEW(arg) = (%_ClassOf(arg) === 'DataView');
 macro IS_GENERATOR(arg)         = (%_ClassOf(arg) === 'Generator');
 macro IS_UNDETECTABLE(arg)      = (%_IsUndetectableObject(arg));
 macro FLOOR(arg)                = $floor(arg);
+macro IS_SEQUENTIAL_STRING(arg) = (%IsSequentialString(arg));

 # Macro for ECMAScript 5 queries of the type:
 # "Type(O) is object."
@@ -147,6 +148,10 @@ macro IS_SPEC_FUNCTION(arg) = (%_ClassOf(arg) === 'Function'); # Will throw a TypeError of the form "[functionName] called on null or undefined". macro CHECK_OBJECT_COERCIBLE(arg, functionName) = if (IS_NULL_OR_UNDEFINED(arg) && !IS_UNDETECTABLE(arg)) throw MakeTypeError('called_on_null_or_undefined', [functionName]);

+# Equivalent of RUNTIME_ASSERT. Used to check for error conditions that should
+# not be triggerable from user code (just tests).
+macro BUILTIN_ASSERT(condition) = if (!(condition)) throw MakeInternalError();
+
# Indices in bound function info retrieved by %BoundFunctionGetBindings(...).
 const kBoundFunctionIndex = 0;
 const kBoundThisIndex = 1;
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index d20b34b07e26e587ef9e9e1e03637750fb1f8e33..44ae4b8c849dcb748d44c21f986bd026489a792b 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -162,7 +162,9 @@ var kMessages = {
symbol_to_primitive: ["Cannot convert a Symbol wrapper object to a primitive value"], invalid_module_path: ["Module does not export '", "%0", "', or export is not itself a module"],
   module_type_error:             ["Module '", "%0", "' used improperly"],
- module_export_undefined: ["Export '", "%0", "' is not defined in module"] + module_export_undefined: ["Export '", "%0", "' is not defined in module"],
+  // Internal error.
+  internal_error:                ["Internal error"]
 };


@@ -349,6 +351,11 @@ function MakeError(type, args) {
   return MakeGenericError($Error, type, args);
 }

+
+function MakeInternalError() {
+  return MakeGenericError($InternalError, "internal_error");
+}
+
 /**
  * Find a line number given a specific source position.
  * @param {number} position The source position.
@@ -1184,7 +1191,7 @@ function SetUpError() {
     %SetProperty(global, name, f, DONT_ENUM);
%SetProperty(builtins, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
     // Configure the error function.
-    if (name == 'Error') {
+    if (name === 'Error') {
       // The prototype of the Error object must itself be an error.
       // However, it can't be an instance of the Error object because
       // it hasn't been properly configured yet.  Instead we create a
@@ -1193,7 +1200,7 @@ function SetUpError() {
       %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
       %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
       %FunctionSetPrototype(f, new ErrorPrototype());
-    } else {
+    } else if (name !== 'InternalError') {
       %FunctionSetPrototype(f, new $Error());
     }
     %FunctionSetInstanceClassName(f, 'Error');
@@ -1224,6 +1231,7 @@ function SetUpError() {
   DefineError(function ReferenceError() { });
   DefineError(function EvalError() { });
   DefineError(function URIError() { });
+  DefineError(function InternalError() { });
 }

 SetUpError();
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index a1ca34ead8dc83ec02d448eeb23d0953409df07a..0e6d58d67f49a5c895b3a7e9f639731d959e343c 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -14196,7 +14196,7 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
     case FAST_HOLEY_DOUBLE_ELEMENTS: {
       int length = IsJSArray() ?
           Smi::cast(JSArray::cast(this)->length())->value() :
-          FixedDoubleArray::cast(elements())->length();
+          FixedArrayBase::cast(elements())->length();
       for (int i = 0; i < length; i++) {
         if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
           if (storage != NULL) {
Index: src/promise.js
diff --git a/src/promise.js b/src/promise.js
index d202f2886166af38985140786888831c0ba25be5..3c97441694cab90afe8aaed426c4e322dbfb9365 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -151,6 +151,7 @@ function PromiseCatch(onReject) {
 }

 function PromiseEnqueue(value, tasks) {
+  BUILTIN_ASSERT(IS_ARRAY(tasks));
   %EnqueueMicrotask(function() {
     for (var i = 0; i < tasks.length; i += 2) {
       PromiseHandle(value, tasks[i], tasks[i + 1])
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index c3610fbe3ffb6df22c959dd2384d79759cc3011c..fcc6fbafba2d5396af2e118a94da6234ebeaf4e1 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -14567,6 +14567,14 @@ RUNTIME_FUNCTION(Runtime_FlattenString) {
 }


+RUNTIME_FUNCTION(Runtime_IsSequentialString) {
+  SealHandleScope shs(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsSeqString());
+}
+
+
 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 0);
Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index 1a93bf0bcb8cee851855c65941f7f6d481a0e493..24282464759319e782d38d798e7b9e58bf2d016a 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -78,6 +78,7 @@ namespace internal {
   F(DebugPromiseHandlePrologue, 1, 1) \
   F(DebugPromiseHandleEpilogue, 0, 1) \
   F(FlattenString, 1, 1) \
+  F(IsSequentialString, 1, 1) \
   F(LoadMutableDouble, 2, 1) \
   F(TryMigrateInstance, 1, 1) \
   F(NotifyContextDisposed, 0, 1) \
Index: src/uri.js
diff --git a/src/uri.js b/src/uri.js
index fb9742fa873d30ebccc7dae2560bdb89cc434ef8..0bb8644501b869bfe5cebfbd7cee91078bb9a74a 100644
--- a/src/uri.js
+++ b/src/uri.js
@@ -84,7 +84,7 @@ function URIHexCharsToCharCode(highChar, lowChar) {


 function URIDecodeOctets(octets, result, index) {
-  if (!IS_STRING(result)) throw new $URIError("Internal error");
+  BUILTIN_ASSERT(IS_SEQUENTIAL_STRING(result));
   var value;
   var o0 = octets[0];
   if (o0 < 0x80) {
@@ -149,15 +149,11 @@ function URIDecodeOctets(octets, result, index) {
     throw new $URIError("URI malformed");
   }
   if (value < 0x10000) {
-    if (index < 0 || index >= result.length) {
-      throw new $URIError("Internal error");
-    }
+    BUILTIN_ASSERT(index >= 0 && index < result.length);
     %_TwoByteSeqStringSetChar(result, index++, value);
     return index;
   } else {
-    if (index < 0 || index >= result.length - 1) {
-      throw new $URIError("Internal error");
-    }
+    BUILTIN_ASSERT(index >= 0 && index < result.length - 1);
     %_TwoByteSeqStringSetChar(result, index++, (value >> 10) + 0xd7c0);
     %_TwoByteSeqStringSetChar(result, index++, (value & 0x3ff) + 0xdc00);
     return index;
Index: test/mjsunit/runtime-gen/issequentialstring.js
diff --git a/test/mjsunit/runtime-gen/classof.js b/test/mjsunit/runtime-gen/issequentialstring.js
similarity index 88%
copy from test/mjsunit/runtime-gen/classof.js
copy to test/mjsunit/runtime-gen/issequentialstring.js
index 59fdde86e948f8690c68e245ec362d191773e170..4157fdc34f6cf18418f3664383fd45b379a1fa02 100644
--- a/test/mjsunit/runtime-gen/classof.js
+++ b/test/mjsunit/runtime-gen/issequentialstring.js
@@ -2,4 +2,4 @@
 // AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
 // Flags: --allow-natives-syntax --harmony
 var _obj = new Object();
-%_ClassOf(_obj);
+%IsSequentialString(_obj);
Index: tools/generate-runtime-tests.py
diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py index 66020cbe126a89c8238afbccc6330508fa2d2c4f..f9b7b4a7c36387ec59a38bd9a8ae862267aacdcb 100755
--- a/tools/generate-runtime-tests.py
+++ b/tools/generate-runtime-tests.py
@@ -47,11 +47,11 @@ EXPAND_MACROS = [
# 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 = 359
-EXPECTED_FUZZABLE_COUNT = 326
+EXPECTED_FUNCTION_COUNT = 360
+EXPECTED_FUZZABLE_COUNT = 327
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 5
-EXPECTED_BUILTINS_COUNT = 823
+EXPECTED_BUILTINS_COUNT = 824


 # 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