Harden more runtime functions
R=dslomov@chromium.org Review URL: https://codereview.chromium.org/255333004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21090 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
528fd3c6a7
commit
2008b820dc
@ -10213,20 +10213,25 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSFunction::RemovePrototype() {
|
bool JSFunction::RemovePrototype() {
|
||||||
Context* native_context = context()->native_context();
|
Context* native_context = context()->native_context();
|
||||||
Map* no_prototype_map = shared()->strict_mode() == SLOPPY
|
Map* no_prototype_map = shared()->strict_mode() == SLOPPY
|
||||||
? native_context->sloppy_function_without_prototype_map()
|
? native_context->sloppy_function_without_prototype_map()
|
||||||
: native_context->strict_function_without_prototype_map();
|
: native_context->strict_function_without_prototype_map();
|
||||||
|
|
||||||
if (map() == no_prototype_map) return;
|
if (map() == no_prototype_map) return true;
|
||||||
|
|
||||||
ASSERT(map() == (shared()->strict_mode() == SLOPPY
|
#ifdef DEBUG
|
||||||
|
if (map() != (shared()->strict_mode() == SLOPPY
|
||||||
? native_context->sloppy_function_map()
|
? native_context->sloppy_function_map()
|
||||||
: native_context->strict_function_map()));
|
: native_context->strict_function_map())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
set_map(no_prototype_map);
|
set_map(no_prototype_map);
|
||||||
set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
|
set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7596,7 +7596,7 @@ class JSFunction: public JSObject {
|
|||||||
|
|
||||||
// After prototype is removed, it will not be created when accessed, and
|
// After prototype is removed, it will not be created when accessed, and
|
||||||
// [[Construct]] from this function will not be allowed.
|
// [[Construct]] from this function will not be allowed.
|
||||||
void RemovePrototype();
|
bool RemovePrototype();
|
||||||
inline bool should_have_prototype();
|
inline bool should_have_prototype();
|
||||||
|
|
||||||
// Accessor for this function's initial map's [[class]]
|
// Accessor for this function's initial map's [[class]]
|
||||||
|
@ -957,6 +957,10 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
|
|||||||
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
|
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
|
||||||
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
|
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
|
||||||
|
|
||||||
|
RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
|
||||||
|
arrayId <= Runtime::ARRAY_ID_LAST);
|
||||||
|
RUNTIME_ASSERT(maybe_buffer->IsNull() || maybe_buffer->IsJSArrayBuffer());
|
||||||
|
|
||||||
ASSERT(holder->GetInternalFieldCount() ==
|
ASSERT(holder->GetInternalFieldCount() ==
|
||||||
v8::ArrayBufferView::kInternalFieldCount);
|
v8::ArrayBufferView::kInternalFieldCount);
|
||||||
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
|
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
|
||||||
@ -998,8 +1002,8 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
|
|||||||
|
|
||||||
size_t array_buffer_byte_length =
|
size_t array_buffer_byte_length =
|
||||||
NumberToSize(isolate, buffer->byte_length());
|
NumberToSize(isolate, buffer->byte_length());
|
||||||
CHECK(byte_offset <= array_buffer_byte_length);
|
RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
|
||||||
CHECK(array_buffer_byte_length - byte_offset >= byte_length);
|
RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
|
||||||
|
|
||||||
holder->set_buffer(*buffer);
|
holder->set_buffer(*buffer);
|
||||||
holder->set_weak_next(buffer->weak_first_view());
|
holder->set_weak_next(buffer->weak_first_view());
|
||||||
@ -1038,6 +1042,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
|
|||||||
CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
|
CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
|
||||||
CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
|
CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
|
||||||
|
|
||||||
|
RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
|
||||||
|
arrayId <= Runtime::ARRAY_ID_LAST);
|
||||||
|
|
||||||
ASSERT(holder->GetInternalFieldCount() ==
|
ASSERT(holder->GetInternalFieldCount() ==
|
||||||
v8::ArrayBufferView::kInternalFieldCount);
|
v8::ArrayBufferView::kInternalFieldCount);
|
||||||
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
|
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
|
||||||
@ -1186,7 +1193,8 @@ RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
|
|||||||
|
|
||||||
Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
|
Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
|
||||||
Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
|
Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
|
||||||
size_t offset = NumberToSize(isolate, *offset_obj);
|
size_t offset = 0;
|
||||||
|
RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
|
||||||
size_t target_length = NumberToSize(isolate, target->length());
|
size_t target_length = NumberToSize(isolate, target->length());
|
||||||
size_t source_length = NumberToSize(isolate, source->length());
|
size_t source_length = NumberToSize(isolate, source->length());
|
||||||
size_t target_byte_length = NumberToSize(isolate, target->byte_length());
|
size_t target_byte_length = NumberToSize(isolate, target->byte_length());
|
||||||
@ -1680,7 +1688,7 @@ RUNTIME_FUNCTION(Runtime_MapCreateIterator) {
|
|||||||
ASSERT(args.length() == 2);
|
ASSERT(args.length() == 2);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
|
||||||
CONVERT_SMI_ARG_CHECKED(kind, 1)
|
CONVERT_SMI_ARG_CHECKED(kind, 1)
|
||||||
ASSERT(kind == JSMapIterator::kKindKeys
|
RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
|
||||||
|| kind == JSMapIterator::kKindValues
|
|| kind == JSMapIterator::kKindValues
|
||||||
|| kind == JSMapIterator::kKindEntries);
|
|| kind == JSMapIterator::kKindEntries);
|
||||||
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
|
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
|
||||||
@ -2207,6 +2215,8 @@ RUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
|
|||||||
CONVERT_SMI_ARG_CHECKED(access_control, 5);
|
CONVERT_SMI_ARG_CHECKED(access_control, 5);
|
||||||
RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
|
RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
|
||||||
RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
|
RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
|
||||||
|
RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
|
||||||
|
static_cast<PropertyAttributes>(attribute)));
|
||||||
JSObject::DefineAccessor(object,
|
JSObject::DefineAccessor(object,
|
||||||
name,
|
name,
|
||||||
InstantiateAccessorComponent(isolate, getter),
|
InstantiateAccessorComponent(isolate, getter),
|
||||||
@ -2660,6 +2670,8 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
|
|||||||
ASSERT(args.length() == 2);
|
ASSERT(args.length() == 2);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
||||||
CONVERT_SMI_ARG_CHECKED(properties, 1);
|
CONVERT_SMI_ARG_CHECKED(properties, 1);
|
||||||
|
// Conservative upper limit to prevent fuzz tests from going OOM.
|
||||||
|
RUNTIME_ASSERT(properties <= 100000);
|
||||||
if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
|
if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
|
||||||
JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
|
JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
|
||||||
}
|
}
|
||||||
@ -2941,7 +2953,7 @@ RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
|
|||||||
ASSERT(args.length() == 1);
|
ASSERT(args.length() == 1);
|
||||||
|
|
||||||
CONVERT_ARG_CHECKED(JSFunction, f, 0);
|
CONVERT_ARG_CHECKED(JSFunction, f, 0);
|
||||||
f->RemovePrototype();
|
RUNTIME_ASSERT(f->RemovePrototype());
|
||||||
|
|
||||||
return isolate->heap()->undefined_value();
|
return isolate->heap()->undefined_value();
|
||||||
}
|
}
|
||||||
@ -4632,6 +4644,8 @@ RUNTIME_FUNCTION(Runtime_StringMatch) {
|
|||||||
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
|
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
|
CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
|
||||||
|
|
||||||
|
RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
|
||||||
|
|
||||||
RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
|
RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
|
||||||
if (global_cache.HasException()) return isolate->heap()->exception();
|
if (global_cache.HasException()) return isolate->heap()->exception();
|
||||||
|
|
||||||
@ -4896,7 +4910,8 @@ RUNTIME_FUNCTION(Runtime_NumberToFixed) {
|
|||||||
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
|
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
|
||||||
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
|
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
|
||||||
int f = FastD2IChecked(f_number);
|
int f = FastD2IChecked(f_number);
|
||||||
RUNTIME_ASSERT(f >= 0);
|
// See DoubleToFixedCString for these constants:
|
||||||
|
RUNTIME_ASSERT(f >= 0 && f <= 20);
|
||||||
char* str = DoubleToFixedCString(value, f);
|
char* str = DoubleToFixedCString(value, f);
|
||||||
Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
|
Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
|
||||||
DeleteArray(str);
|
DeleteArray(str);
|
||||||
@ -7321,6 +7336,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int separator_length = separator->length();
|
int separator_length = separator->length();
|
||||||
|
RUNTIME_ASSERT(separator_length > 0);
|
||||||
int max_nof_separators =
|
int max_nof_separators =
|
||||||
(String::kMaxLength + separator_length - 1) / separator_length;
|
(String::kMaxLength + separator_length - 1) / separator_length;
|
||||||
if (max_nof_separators < (array_length - 1)) {
|
if (max_nof_separators < (array_length - 1)) {
|
||||||
@ -7422,26 +7438,30 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
|
|||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
ASSERT(args.length() == 3);
|
ASSERT(args.length() == 3);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
|
||||||
RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
|
|
||||||
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
|
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
|
CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
|
||||||
// elements_array is fast-mode JSarray of alternating positions
|
// elements_array is fast-mode JSarray of alternating positions
|
||||||
// (increasing order) and strings.
|
// (increasing order) and strings.
|
||||||
|
RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
|
||||||
// array_length is length of original array (used to add separators);
|
// array_length is length of original array (used to add separators);
|
||||||
// separator is string to put between elements. Assumed to be non-empty.
|
// separator is string to put between elements. Assumed to be non-empty.
|
||||||
|
RUNTIME_ASSERT(array_length > 0);
|
||||||
|
|
||||||
// Find total length of join result.
|
// Find total length of join result.
|
||||||
int string_length = 0;
|
int string_length = 0;
|
||||||
bool is_ascii = separator->IsOneByteRepresentation();
|
bool is_ascii = separator->IsOneByteRepresentation();
|
||||||
bool overflow = false;
|
bool overflow = false;
|
||||||
CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
|
CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
|
||||||
|
RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
|
||||||
RUNTIME_ASSERT((elements_length & 1) == 0); // Even length.
|
RUNTIME_ASSERT((elements_length & 1) == 0); // Even length.
|
||||||
|
|
||||||
{ DisallowHeapAllocation no_gc;
|
|
||||||
FixedArray* elements = FixedArray::cast(elements_array->elements());
|
FixedArray* elements = FixedArray::cast(elements_array->elements());
|
||||||
for (int i = 0; i < elements_length; i += 2) {
|
for (int i = 0; i < elements_length; i += 2) {
|
||||||
RUNTIME_ASSERT(elements->get(i)->IsNumber());
|
RUNTIME_ASSERT(elements->get(i)->IsNumber());
|
||||||
RUNTIME_ASSERT(elements->get(i + 1)->IsString());
|
RUNTIME_ASSERT(elements->get(i + 1)->IsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
{ DisallowHeapAllocation no_gc;
|
||||||
|
for (int i = 0; i < elements_length; i += 2) {
|
||||||
String* string = String::cast(elements->get(i + 1));
|
String* string = String::cast(elements->get(i + 1));
|
||||||
int length = string->length();
|
int length = string->length();
|
||||||
if (is_ascii && !string->IsOneByteRepresentation()) {
|
if (is_ascii && !string->IsOneByteRepresentation()) {
|
||||||
@ -7965,7 +7985,9 @@ RUNTIME_FUNCTION(Runtime_DateMakeDay) {
|
|||||||
CONVERT_SMI_ARG_CHECKED(year, 0);
|
CONVERT_SMI_ARG_CHECKED(year, 0);
|
||||||
CONVERT_SMI_ARG_CHECKED(month, 1);
|
CONVERT_SMI_ARG_CHECKED(month, 1);
|
||||||
|
|
||||||
return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
|
int days = isolate->date_cache()->DaysFromYearMonth(year, month);
|
||||||
|
RUNTIME_ASSERT(Smi::IsValid(days));
|
||||||
|
return Smi::FromInt(days);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -8943,7 +8965,10 @@ RUNTIME_FUNCTION(Runtime_Apply) {
|
|||||||
CONVERT_SMI_ARG_CHECKED(offset, 3);
|
CONVERT_SMI_ARG_CHECKED(offset, 3);
|
||||||
CONVERT_SMI_ARG_CHECKED(argc, 4);
|
CONVERT_SMI_ARG_CHECKED(argc, 4);
|
||||||
RUNTIME_ASSERT(offset >= 0);
|
RUNTIME_ASSERT(offset >= 0);
|
||||||
RUNTIME_ASSERT(argc >= 0);
|
// Loose upper bound to allow fuzzing. We'll most likely run out of
|
||||||
|
// stack space before hitting this limit.
|
||||||
|
static int kMaxArgc = 1000000;
|
||||||
|
RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
|
||||||
|
|
||||||
// If there are too many arguments, allocate argv via malloc.
|
// If there are too many arguments, allocate argv via malloc.
|
||||||
const int argv_small_size = 10;
|
const int argv_small_size = 10;
|
||||||
@ -13522,6 +13547,15 @@ RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
|
|||||||
ASSERT(args.length() == 2);
|
ASSERT(args.length() == 2);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
|
||||||
CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
|
CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
|
||||||
|
RUNTIME_ASSERT(shared_array->length()->IsSmi());
|
||||||
|
int array_length = Smi::cast(shared_array->length())->value();
|
||||||
|
for (int i = 0; i < array_length; i++) {
|
||||||
|
Handle<Object> element =
|
||||||
|
Object::GetElement(isolate, shared_array, i).ToHandleChecked();
|
||||||
|
RUNTIME_ASSERT(
|
||||||
|
element->IsJSValue() &&
|
||||||
|
Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
|
||||||
|
}
|
||||||
|
|
||||||
return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
|
return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
|
||||||
}
|
}
|
||||||
@ -13791,6 +13825,9 @@ RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
|
|||||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
|
||||||
|
|
||||||
uint32_t length = static_cast<uint32_t>(input->length()->Number());
|
uint32_t length = static_cast<uint32_t>(input->length()->Number());
|
||||||
|
// Set some limit to prevent fuzz tests from going OOM.
|
||||||
|
// Can be bumped when callers' requirements change.
|
||||||
|
RUNTIME_ASSERT(length < 100);
|
||||||
Handle<FixedArray> output = factory->NewFixedArray(length);
|
Handle<FixedArray> output = factory->NewFixedArray(length);
|
||||||
Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
|
Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
|
||||||
Handle<Name> base = factory->NewStringFromStaticAscii("base");
|
Handle<Name> base = factory->NewStringFromStaticAscii("base");
|
||||||
@ -14238,6 +14275,8 @@ RUNTIME_FUNCTION(Runtime_StringNormalize) {
|
|||||||
|
|
||||||
CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
|
CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
|
||||||
CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
|
CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
|
||||||
|
RUNTIME_ASSERT(form_id >= 0 &&
|
||||||
|
static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
|
||||||
|
|
||||||
v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
|
v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
|
||||||
const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
|
const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
|
||||||
|
@ -865,7 +865,10 @@ class Runtime : public AllStatic {
|
|||||||
ARRAY_ID_INT32 = 6,
|
ARRAY_ID_INT32 = 6,
|
||||||
ARRAY_ID_FLOAT32 = 7,
|
ARRAY_ID_FLOAT32 = 7,
|
||||||
ARRAY_ID_FLOAT64 = 8,
|
ARRAY_ID_FLOAT64 = 8,
|
||||||
ARRAY_ID_UINT8_CLAMPED = 9
|
ARRAY_ID_UINT8_CLAMPED = 9,
|
||||||
|
|
||||||
|
ARRAY_ID_FIRST = ARRAY_ID_UINT8,
|
||||||
|
ARRAY_ID_LAST = ARRAY_ID_UINT8_CLAMPED
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ArrayIdToTypeAndSize(int array_id,
|
static void ArrayIdToTypeAndSize(int array_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user