#include "src/allocation-site-scopes.h"
#include "src/api.h"
#include "src/arguments.h"
+#include "src/bailout-reason.h"
+#include "src/base/cpu.h"
+#include "src/base/platform/platform.h"
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/compilation-cache.h"
#include "src/compiler.h"
#include "src/conversions.h"
-#include "src/cpu.h"
#include "src/cpu-profiler.h"
+#include "src/date.h"
#include "src/dateparser-inl.h"
#include "src/debug.h"
#include "src/deoptimizer.h"
-#include "src/date.h"
#include "src/execution.h"
#include "src/full-codegen.h"
#include "src/global-handles.h"
#include "src/isolate-inl.h"
-#include "src/jsregexp.h"
-#include "src/jsregexp-inl.h"
#include "src/json-parser.h"
#include "src/json-stringifier.h"
+#include "src/jsregexp-inl.h"
+#include "src/jsregexp.h"
#include "src/liveedit.h"
#include "src/misc-intrinsics.h"
#include "src/parser.h"
-#include "src/platform.h"
-#include "src/runtime-profiler.h"
+#include "src/prototype.h"
#include "src/runtime.h"
+#include "src/runtime-profiler.h"
#include "src/scopeinfo.h"
#include "src/smart-pointers.h"
#include "src/string-search.h"
-#include "src/stub-cache.h"
#include "src/uri.h"
+#include "src/utils.h"
#include "src/v8threads.h"
#include "src/vm-state-inl.h"
+#include "third_party/fdlibm/fdlibm.h"
#ifdef V8_I18N_SUPPORT
#include "src/i18n.h"
StrictMode name = static_cast<StrictMode>(args.smi_at(index));
+// Assert that the given argument is a number within the Int32 range
+// and convert it to int32_t. If the argument is not an Int32 call
+// IllegalOperation and return.
+#define CONVERT_INT32_ARG_CHECKED(name, index) \
+ RUNTIME_ASSERT(args[index]->IsNumber()); \
+ int32_t name = 0; \
+ RUNTIME_ASSERT(args[index]->ToInt32(&name));
+
+
static Handle<Map> ComputeObjectLiteralMap(
Handle<Context> context,
Handle<FixedArray> constant_properties,
} else {
// Bail out as a non-internalized-string non-index key makes caching
// impossible.
- // ASSERT to make sure that the if condition after the loop is false.
- ASSERT(number_of_string_keys != number_of_properties);
+ // DCHECK to make sure that the if condition after the loop is false.
+ DCHECK(number_of_string_keys != number_of_properties);
break;
}
}
keys->set(index++, key);
}
}
- ASSERT(index == number_of_string_keys);
+ DCHECK(index == number_of_string_keys);
}
*is_result_from_cache = true;
return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
}
*is_result_from_cache = false;
- return Map::Create(handle(context->object_function()), number_of_properties);
+ return Map::Create(isolate, number_of_properties);
}
JSObject::NormalizeProperties(
boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
}
- Object::ValueType value_type = should_normalize
- ? Object::FORCE_TAGGED : Object::OPTIMAL_REPRESENTATION;
-
// TODO(verwaest): Support tracking representations in the boilerplate.
for (int index = 0; index < length; index +=2) {
Handle<Object> key(constant_properties->get(index+0), isolate);
}
MaybeHandle<Object> maybe_result;
uint32_t element_index = 0;
- StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
if (key->IsInternalizedString()) {
if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
// Array index as string (uint32).
- maybe_result = JSObject::SetOwnElement(
- boilerplate, element_index, value, SLOPPY);
+ if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
+ maybe_result =
+ JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
} else {
Handle<String> name(String::cast(*key));
- ASSERT(!name->AsArrayIndex(&element_index));
+ DCHECK(!name->AsArrayIndex(&element_index));
maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
- boilerplate, name, value, NONE,
- value_type, mode);
+ boilerplate, name, value, NONE);
}
} else if (key->ToArrayIndex(&element_index)) {
// Array index (uint32).
- maybe_result = JSObject::SetOwnElement(
- boilerplate, element_index, value, SLOPPY);
+ if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
+ maybe_result =
+ JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
} else {
// Non-uint32 number.
- ASSERT(key->IsNumber());
+ DCHECK(key->IsNumber());
double num = key->Number();
char arr[100];
- Vector<char> buffer(arr, ARRAY_SIZE(arr));
+ Vector<char> buffer(arr, arraysize(arr));
const char* str = DoubleToCString(num, buffer);
Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
- maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
- boilerplate, name, value, NONE,
- value_type, mode);
+ maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name,
+ value, NONE);
}
// If setting the property on the boilerplate throws an
// exception, the exception is converted to an empty handle in
// computed properties have been assigned so that we can generate
// constant function properties.
if (should_transform && !has_function_literal) {
- JSObject::TransformToFastProperties(
+ JSObject::MigrateSlowToFast(
boilerplate, boilerplate->map()->unused_property_fields());
}
}
-static const int kSmiLiteralMinimumLength = 1024;
-
-
MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
FixedArrayBase::cast(elements->get(1)));
{ DisallowHeapAllocation no_gc;
- ASSERT(IsFastElementsKind(constant_elements_kind));
+ DCHECK(IsFastElementsKind(constant_elements_kind));
Context* native_context = isolate->context()->native_context();
Object* maps_array = native_context->js_array_maps();
- ASSERT(!maps_array->IsUndefined());
+ DCHECK(!maps_array->IsUndefined());
Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
object->set_map(Map::cast(map));
}
Handle<FixedArrayBase> copied_elements_values;
if (IsFastDoubleElementsKind(constant_elements_kind)) {
- ASSERT(FLAG_smi_only_arrays);
copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
Handle<FixedDoubleArray>::cast(constant_elements_values));
} else {
- ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
+ DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
const bool is_cow =
(constant_elements_values->map() ==
isolate->heap()->fixed_cow_array_map());
Handle<FixedArray> fixed_array_values =
Handle<FixedArray>::cast(copied_elements_values);
for (int i = 0; i < fixed_array_values->length(); i++) {
- ASSERT(!fixed_array_values->get(i)->IsFixedArray());
+ DCHECK(!fixed_array_values->get(i)->IsFixedArray());
}
#endif
} else {
object->set_elements(*copied_elements_values);
object->set_length(Smi::FromInt(copied_elements_values->length()));
- // Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
- // on or the object is larger than the threshold.
- if (!FLAG_smi_only_arrays &&
- constant_elements_values->length() < kSmiLiteralMinimumLength) {
- ElementsKind elements_kind = object->GetElementsKind();
- if (!IsFastObjectElementsKind(elements_kind)) {
- if (IsFastHoleyElementsKind(elements_kind)) {
- TransitionElements(object, FAST_HOLEY_ELEMENTS, isolate).Check();
- } else {
- TransitionElements(object, FAST_ELEMENTS, isolate).Check();
- }
- }
- }
-
JSObject::ValidateElements(object);
return object;
}
}
-RUNTIME_FUNCTION(RuntimeHidden_CreateObjectLiteral) {
+RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
Handle<Object> literal_site(literals->get(literals_index), isolate);
Handle<AllocationSite> site;
if (*literal_site == isolate->heap()->undefined_value()) {
- ASSERT(*elements != isolate->heap()->empty_fixed_array());
+ DCHECK(*elements != isolate->heap()->empty_fixed_array());
Handle<Object> boilerplate;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, boilerplate,
AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
usage_context.EnterNewScope();
JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
- ? JSObject::kNoHints
- : JSObject::kObjectIsShallowArray;
+ ? JSObject::kNoHints
+ : JSObject::kObjectIsShallow;
MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
hints);
usage_context.ExitScope(site, boilerplate);
}
-RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteral) {
+RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
}
-RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteralStubBailout) {
+RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
RUNTIME_FUNCTION(Runtime_CreateSymbol) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
Handle<Symbol> symbol = isolate->factory()->NewSymbol();
RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
}
-RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
+RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+ RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
+ Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol();
+ if (name->IsString()) symbol->set_name(*name);
+ return *symbol;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateOwnSymbol) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
Handle<JSObject> registry = isolate->GetSymbolRegistry();
Handle<String> part = isolate->factory()->private_intern_string();
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, symbol, Object::GetPropertyOrElement(privates, name));
if (!symbol->IsSymbol()) {
- ASSERT(symbol->IsUndefined());
+ DCHECK(symbol->IsUndefined());
symbol = isolate->factory()->NewPrivateSymbol();
Handle<Symbol>::cast(symbol)->set_name(*name);
- JSObject::SetProperty(Handle<JSObject>::cast(privates),
- name, symbol, NONE, STRICT).Assert();
+ Handle<Symbol>::cast(symbol)->set_is_own(true);
+ JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol,
+ STRICT).Assert();
}
return *symbol;
}
RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
return *Object::ToObject(isolate, symbol).ToHandleChecked();
}
RUNTIME_FUNCTION(Runtime_SymbolDescription) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Symbol, symbol, 0);
return symbol->name();
}
RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
return *isolate->GetSymbolRegistry();
}
RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Symbol, symbol, 0);
return isolate->heap()->ToBoolean(symbol->is_private());
}
RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
RUNTIME_FUNCTION(Runtime_IsJSProxy) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSProxy());
}
RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
}
RUNTIME_FUNCTION(Runtime_GetHandler) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
return proxy->handler();
}
RUNTIME_FUNCTION(Runtime_GetCallTrap) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
return proxy->call_trap();
}
RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
return proxy->construct_trap();
}
RUNTIME_FUNCTION(Runtime_Fix) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
JSProxy::Fix(proxy);
return isolate->heap()->undefined_value();
void Runtime::FreeArrayBuffer(Isolate* isolate,
JSArrayBuffer* phantom_array_buffer) {
if (phantom_array_buffer->should_be_freed()) {
- ASSERT(phantom_array_buffer->is_external());
+ DCHECK(phantom_array_buffer->is_external());
free(phantom_array_buffer->backing_store());
}
if (phantom_array_buffer->is_external()) return;
bool is_external,
void* data,
size_t allocated_length) {
- ASSERT(array_buffer->GetInternalFieldCount() ==
+ DCHECK(array_buffer->GetInternalFieldCount() ==
v8::ArrayBuffer::kInternalFieldCount);
for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
array_buffer->SetInternalField(i, Smi::FromInt(0));
RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
if (!holder->byte_length()->IsUndefined()) {
}
size_t allocated_length = 0;
if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
if (!Runtime::SetupArrayBufferAllocatingData(isolate,
holder, allocated_length)) {
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
return *holder;
}
RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
return holder->byte_length();
}
RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, object, 0);
return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
}
RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
if (array_buffer->backing_store() == NULL) {
CHECK(Smi::FromInt(0) == array_buffer->byte_length());
return isolate->heap()->undefined_value();
}
- ASSERT(!array_buffer->is_external());
+ DCHECK(!array_buffer->is_external());
void* backing_store = array_buffer->backing_store();
size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
array_buffer->set_is_external(true);
RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 5);
+ DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
CONVERT_SMI_ARG_CHECKED(arrayId, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
size_t length = byte_length / element_size;
if (length > static_cast<unsigned>(Smi::kMaxValue)) {
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_typed_array_length",
- HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewRangeError("invalid_typed_array_length",
+ HandleVector<Object>(NULL, 0)));
}
// All checks are done, now we can modify objects.
- ASSERT(holder->GetInternalFieldCount() ==
+ DCHECK(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
holder->SetInternalField(i, Smi::FromInt(0));
Handle<Map> map =
JSObject::GetElementsTransitionMap(holder, external_elements_kind);
JSObject::SetMapAndElements(holder, map, elements);
- ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
+ DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
} else {
holder->set_buffer(Smi::FromInt(0));
holder->set_weak_next(isolate->heap()->undefined_value());
// Returns true if backing store was initialized or false otherwise.
RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
CONVERT_SMI_ARG_CHECKED(arrayId, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
(length > (kMaxInt / element_size))) {
- return isolate->Throw(*isolate->factory()->
- NewRangeError("invalid_typed_array_length",
- HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewRangeError("invalid_typed_array_length",
+ HandleVector<Object>(NULL, 0)));
}
size_t byte_length = length * element_size;
- ASSERT(holder->GetInternalFieldCount() ==
+ DCHECK(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
holder->SetInternalField(i, Smi::FromInt(0));
if (!Runtime::SetupArrayBufferAllocatingData(
isolate, buffer, byte_length, false)) {
- return isolate->Throw(*isolate->factory()->
- NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
holder->set_buffer(*buffer);
#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \
HandleScope scope(isolate); \
- ASSERT(args.length() == 1); \
+ DCHECK(args.length() == 1); \
CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
return holder->accessor(); \
}
RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
return *holder->GetBuffer();
}
RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
- if (!args[0]->IsJSTypedArray())
- return isolate->Throw(*isolate->factory()->NewTypeError(
- "not_typed_array", HandleVector<Object>(NULL, 0)));
+ DCHECK(args.length() == 3);
+ if (!args[0]->IsJSTypedArray()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
+ }
if (!args[1]->IsJSTypedArray())
return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
size_t source_length = NumberToSize(isolate, source->length());
size_t target_byte_length = NumberToSize(isolate, target->byte_length());
size_t source_byte_length = NumberToSize(isolate, source->byte_length());
- if (offset > target_length ||
- offset + source_length > target_length ||
- offset + source_length < offset) // overflow
- return isolate->Throw(*isolate->factory()->NewRangeError(
- "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
+ if (offset > target_length || offset + source_length > target_length ||
+ offset + source_length < offset) { // overflow
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewRangeError("typed_array_set_source_too_large",
+ HandleVector<Object>(NULL, 0)));
+ }
size_t target_offset = NumberToSize(isolate, target->byte_offset());
size_t source_offset = NumberToSize(isolate, source->byte_offset());
(target_base <= source_base &&
target_base + target_byte_length > source_base)) {
// We do not support overlapping ArrayBuffers
- ASSERT(
+ DCHECK(
target->GetBuffer()->backing_store() ==
source->GetBuffer()->backing_store());
return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
- ASSERT(args.length() == 0);
- ASSERT_OBJECT_SIZE(
+ DCHECK(args.length() == 0);
+ DCHECK_OBJECT_SIZE(
FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
}
RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
- ASSERT(holder->GetInternalFieldCount() ==
+ DCHECK(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
holder->SetInternalField(i, Smi::FromInt(0));
Value value;
size_t buffer_offset = data_view_byte_offset + byte_offset;
- ASSERT(
+ DCHECK(
NumberToSize(isolate, buffer->byte_length())
>= buffer_offset + sizeof(T));
uint8_t* source =
Value value;
value.data = data;
size_t buffer_offset = data_view_byte_offset + byte_offset;
- ASSERT(
+ DCHECK(
NumberToSize(isolate, buffer->byte_length())
>= buffer_offset + sizeof(T));
uint8_t* target =
}
-#define DATA_VIEW_GETTER(TypeName, Type, Converter) \
- RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
- HandleScope scope(isolate); \
- ASSERT(args.length() == 3); \
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
- CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
- CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \
- Type result; \
- if (DataViewGetValue( \
- isolate, holder, offset, is_little_endian, &result)) { \
- return *isolate->factory()->Converter(result); \
- } else { \
- return isolate->Throw(*isolate->factory()->NewRangeError( \
- "invalid_data_view_accessor_offset", \
- HandleVector<Object>(NULL, 0))); \
- } \
+#define DATA_VIEW_GETTER(TypeName, Type, Converter) \
+ RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 3); \
+ CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
+ CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \
+ Type result; \
+ if (DataViewGetValue(isolate, holder, offset, is_little_endian, \
+ &result)) { \
+ return *isolate->factory()->Converter(result); \
+ } else { \
+ THROW_NEW_ERROR_RETURN_FAILURE( \
+ isolate, NewRangeError("invalid_data_view_accessor_offset", \
+ HandleVector<Object>(NULL, 0))); \
+ } \
}
DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
}
-#define DATA_VIEW_SETTER(TypeName, Type) \
- RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
- HandleScope scope(isolate); \
- ASSERT(args.length() == 4); \
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
- CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
- CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \
- CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \
- Type v = DataViewConvertValue<Type>(value->Number()); \
- if (DataViewSetValue( \
- isolate, holder, offset, is_little_endian, v)) { \
- return isolate->heap()->undefined_value(); \
- } else { \
- return isolate->Throw(*isolate->factory()->NewRangeError( \
- "invalid_data_view_accessor_offset", \
- HandleVector<Object>(NULL, 0))); \
- } \
+#define DATA_VIEW_SETTER(TypeName, Type) \
+ RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 4); \
+ CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \
+ CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \
+ Type v = DataViewConvertValue<Type>(value->Number()); \
+ if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
+ return isolate->heap()->undefined_value(); \
+ } else { \
+ THROW_NEW_ERROR_RETURN_FAILURE( \
+ isolate, NewRangeError("invalid_data_view_accessor_offset", \
+ HandleVector<Object>(NULL, 0))); \
+ } \
}
DATA_VIEW_SETTER(Uint8, uint8_t)
RUNTIME_FUNCTION(Runtime_SetInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
holder->set_table(*table);
RUNTIME_FUNCTION(Runtime_SetAdd) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
table = OrderedHashSet::Add(table, key);
holder->set_table(*table);
- return isolate->heap()->undefined_value();
+ return *holder;
}
RUNTIME_FUNCTION(Runtime_SetHas) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
RUNTIME_FUNCTION(Runtime_SetDelete) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
RUNTIME_FUNCTION(Runtime_SetClear) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
table = OrderedHashSet::Clear(table);
RUNTIME_FUNCTION(Runtime_SetGetSize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
return Smi::FromInt(table->NumberOfElements());
RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
CONVERT_SMI_ARG_CHECKED(kind, 2)
RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
- return *JSSetIterator::Next(holder);
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
+ CONVERT_ARG_CHECKED(JSArray, value_array, 1);
+ return holder->Next(value_array);
}
RUNTIME_FUNCTION(Runtime_MapInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
holder->set_table(*table);
RUNTIME_FUNCTION(Runtime_MapGet) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
RUNTIME_FUNCTION(Runtime_MapHas) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
RUNTIME_FUNCTION(Runtime_MapDelete) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
RUNTIME_FUNCTION(Runtime_MapClear) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
table = OrderedHashMap::Clear(table);
RUNTIME_FUNCTION(Runtime_MapSet) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
holder->set_table(*new_table);
- return isolate->heap()->undefined_value();
+ return *holder;
}
RUNTIME_FUNCTION(Runtime_MapGetSize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
return Smi::FromInt(table->NumberOfElements());
RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
CONVERT_SMI_ARG_CHECKED(kind, 2)
}
-RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
+RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
- return *JSMapIterator::Next(holder);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<FixedArray> entries =
+ isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
+ {
+ DisallowHeapAllocation no_gc;
+ int number_of_non_hole_elements = 0;
+ for (int i = 0; i < table->Capacity(); i++) {
+ Handle<Object> key(table->KeyAt(i), isolate);
+ if (table->IsKey(*key)) {
+ entries->set(number_of_non_hole_elements++, *key);
+ Object* value = table->Lookup(key);
+ entries->set(number_of_non_hole_elements++, value);
+ }
+ }
+ DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
+ }
+ return *isolate->factory()->NewJSArrayWithElements(entries);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
+ CONVERT_ARG_CHECKED(JSArray, value_array, 1);
+ return holder->Next(value_array);
}
static Handle<JSWeakCollection> WeakCollectionInitialize(
Isolate* isolate,
Handle<JSWeakCollection> weak_collection) {
- ASSERT(weak_collection->map()->inobject_properties() == 0);
+ DCHECK(weak_collection->map()->inobject_properties() == 0);
Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
weak_collection->set_table(*table);
return weak_collection;
RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
return *WeakCollectionInitialize(isolate, weak_collection);
}
RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
RUNTIME_ASSERT(table->IsKey(*key));
Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
weak_collection->set_table(*new_table);
- return isolate->heap()->undefined_value();
+ return *weak_collection;
}
-RUNTIME_FUNCTION(Runtime_ClassOf) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(Object, obj, 0);
- if (!obj->IsJSObject()) return isolate->heap()->null_value();
- return JSObject::cast(obj)->class_name();
+RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<FixedArray> values =
+ isolate->factory()->NewFixedArray(table->NumberOfElements());
+ {
+ DisallowHeapAllocation no_gc;
+ int number_of_non_hole_elements = 0;
+ for (int i = 0; i < table->Capacity(); i++) {
+ Handle<Object> key(table->KeyAt(i), isolate);
+ if (table->IsKey(*key)) {
+ values->set(number_of_non_hole_elements++, *key);
+ }
+ }
+ DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
+ }
+ return *isolate->factory()->NewJSArrayWithElements(values);
}
RUNTIME_FUNCTION(Runtime_GetPrototype) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
// We don't expect access checks to be needed on JSProxy objects.
- ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+ DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+ PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
do {
- if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
- isolate->factory()->proto_string(),
- v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
- v8::ACCESS_GET);
+ if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+ isolate->factory()->proto_string(), v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+ v8::ACCESS_GET);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
- obj = Object::GetPrototype(isolate, obj);
- } while (obj->IsJSObject() &&
- JSObject::cast(*obj)->map()->is_hidden_prototype());
- return *obj;
+ iter.AdvanceIgnoringProxies();
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+ return *PrototypeIterator::GetCurrent(iter);
+ }
+ } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
+ return *PrototypeIterator::GetCurrent(iter);
}
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
Isolate* isolate, Handle<Object> receiver) {
- Handle<Object> current = Object::GetPrototype(isolate, receiver);
- while (current->IsJSObject() &&
- JSObject::cast(*current)->map()->is_hidden_prototype()) {
- current = Object::GetPrototype(isolate, current);
+ PrototypeIterator iter(isolate, receiver);
+ while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+ return PrototypeIterator::GetCurrent(iter);
+ }
+ iter.Advance();
}
- return current;
+ return PrototypeIterator::GetCurrent(iter);
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+ DCHECK(!obj->IsAccessCheckNeeded());
+ DCHECK(!obj->map()->is_observed());
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::SetPrototype(obj, prototype, false));
+ return *result;
}
RUNTIME_FUNCTION(Runtime_SetPrototype) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
if (obj->IsAccessCheckNeeded() &&
RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
HandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
// See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
+ PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
while (true) {
- Handle<Object> prototype = Object::GetPrototype(isolate, V);
- if (prototype->IsNull()) return isolate->heap()->false_value();
- if (*O == *prototype) return isolate->heap()->true_value();
- V = prototype;
- }
-}
-
-
-static bool CheckAccessException(Object* callback,
- v8::AccessType access_type) {
- DisallowHeapAllocation no_gc;
- ASSERT(!callback->IsForeign());
- if (callback->IsAccessorInfo()) {
- AccessorInfo* info = AccessorInfo::cast(callback);
- return
- (access_type == v8::ACCESS_HAS &&
- (info->all_can_read() || info->all_can_write())) ||
- (access_type == v8::ACCESS_GET && info->all_can_read()) ||
- (access_type == v8::ACCESS_SET && info->all_can_write());
- }
- if (callback->IsAccessorPair()) {
- AccessorPair* info = AccessorPair::cast(callback);
- return
- (access_type == v8::ACCESS_HAS &&
- (info->all_can_read() || info->all_can_write())) ||
- (access_type == v8::ACCESS_GET && info->all_can_read()) ||
- (access_type == v8::ACCESS_SET && info->all_can_write());
- }
- return false;
-}
-
-
-template<class Key>
-static bool CheckGenericAccess(
- Handle<JSObject> receiver,
- Handle<JSObject> holder,
- Key key,
- v8::AccessType access_type,
- bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
- Isolate* isolate = receiver->GetIsolate();
- for (Handle<JSObject> current = receiver;
- true;
- current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
- if (current->IsAccessCheckNeeded() &&
- !(isolate->*mayAccess)(current, key, access_type)) {
- return false;
- }
- if (current.is_identical_to(holder)) break;
- }
- return true;
-}
-
-
-enum AccessCheckResult {
- ACCESS_FORBIDDEN,
- ACCESS_ALLOWED,
- ACCESS_ABSENT
-};
-
-
-static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
- Handle<Name> name,
- v8::AccessType access_type) {
- uint32_t index;
- if (name->AsArrayIndex(&index)) {
- // TODO(1095): we should traverse hidden prototype hierachy as well.
- if (CheckGenericAccess(
- obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
- return ACCESS_ALLOWED;
- }
-
- obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
- return ACCESS_FORBIDDEN;
- }
-
- Isolate* isolate = obj->GetIsolate();
- LookupResult lookup(isolate);
- obj->LookupOwn(name, &lookup, true);
-
- if (!lookup.IsProperty()) return ACCESS_ABSENT;
- Handle<JSObject> holder(lookup.holder(), isolate);
- if (CheckGenericAccess<Handle<Object> >(
- obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
- return ACCESS_ALLOWED;
- }
-
- // Access check callback denied the access, but some properties
- // can have a special permissions which override callbacks descision
- // (currently see v8::AccessControl).
- // API callbacks can have per callback access exceptions.
- switch (lookup.type()) {
- case CALLBACKS:
- if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
- return ACCESS_ALLOWED;
- }
- break;
- case INTERCEPTOR:
- // If the object has an interceptor, try real named properties.
- // Overwrite the result to fetch the correct property later.
- holder->LookupRealNamedProperty(name, &lookup);
- if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
- if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
- return ACCESS_ALLOWED;
- }
- }
- break;
- default:
- break;
+ iter.AdvanceIgnoringProxies();
+ if (iter.IsAtEnd()) return isolate->heap()->false_value();
+ if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
}
-
- isolate->ReportFailedAccessCheck(obj, access_type);
- return ACCESS_FORBIDDEN;
}
Handle<Name> name) {
Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
- // Due to some WebKit tests, we want to make sure that we do not log
- // more than one access failure here.
- AccessCheckResult access_check_result =
- CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- switch (access_check_result) {
- case ACCESS_FORBIDDEN: return factory->false_value();
- case ACCESS_ALLOWED: break;
- case ACCESS_ABSENT: return factory->undefined_value();
- }
-
- PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name);
- if (attrs == ABSENT) {
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return factory->undefined_value();
- }
- ASSERT(!isolate->has_scheduled_exception());
- Handle<AccessorPair> accessors;
- bool has_accessors =
- JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors);
- Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
- elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
- elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
- elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
- if (!has_accessors) {
- elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
- // Runtime::GetObjectProperty does access check.
- Handle<Object> value;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
- Object);
- elms->set(VALUE_INDEX, *value);
+ PropertyAttributes attrs;
+ uint32_t index = 0;
+ Handle<Object> value;
+ MaybeHandle<AccessorPair> maybe_accessors;
+ // TODO(verwaest): Unify once indexed properties can be handled by the
+ // LookupIterator.
+ if (name->AsArrayIndex(&index)) {
+ // Get attributes.
+ Maybe<PropertyAttributes> maybe =
+ JSReceiver::GetOwnElementAttribute(obj, index);
+ if (!maybe.has_value) return MaybeHandle<Object>();
+ attrs = maybe.value;
+ if (attrs == ABSENT) return factory->undefined_value();
+
+ // Get AccessorPair if present.
+ maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
+
+ // Get value if not an AccessorPair.
+ if (maybe_accessors.is_null()) {
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
+ Runtime::GetElementOrCharAt(isolate, obj, index), Object);
+ }
} else {
- // Access checks are performed for both accessors separately.
- // When they fail, the respective field is not set in the descriptor.
- Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
- Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
+ // Get attributes.
+ LookupIterator it(obj, name, LookupIterator::HIDDEN);
+ Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
+ if (!maybe.has_value) return MaybeHandle<Object>();
+ attrs = maybe.value;
+ if (attrs == ABSENT) return factory->undefined_value();
- if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) {
- ASSERT(!isolate->has_scheduled_exception());
- elms->set(GETTER_INDEX, *getter);
- } else {
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ // Get AccessorPair if present.
+ if (it.state() == LookupIterator::ACCESSOR &&
+ it.GetAccessors()->IsAccessorPair()) {
+ maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
}
- if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
- ASSERT(!isolate->has_scheduled_exception());
- elms->set(SETTER_INDEX, *setter);
- } else {
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ // Get value if not an AccessorPair.
+ if (maybe_accessors.is_null()) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value, Object::GetProperty(&it), Object);
}
}
+ DCHECK(!isolate->has_pending_exception());
+ Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
+ elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
+ elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
+ elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
+
+ Handle<AccessorPair> accessors;
+ if (maybe_accessors.ToHandle(&accessors)) {
+ Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
+ Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
+ elms->set(GETTER_INDEX, *getter);
+ elms->set(SETTER_INDEX, *setter);
+ } else {
+ elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
+ elms->set(VALUE_INDEX, *value);
+ }
- return isolate->factory()->NewJSArrayWithElements(elms);
+ return factory->NewJSArrayWithElements(elms);
}
// [true, GetFunction, SetFunction, Enumerable, Configurable]
RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
Handle<Object> result;
RUNTIME_FUNCTION(Runtime_PreventExtensions) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
}
+RUNTIME_FUNCTION(Runtime_ToMethod) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+ Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
+ Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
+ JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
+ home_object, DONT_ENUM).Assert();
+ return *clone;
+}
+
+
+RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
+ DCHECK(args.length() == 0);
+ return isolate->heap()->home_object_symbol();
+}
+
+
+RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
+
+ if (home_object->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+ }
+
+ PrototypeIterator iter(isolate, home_object);
+ Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+ if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+
+ LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
+ return *result;
+}
+
+
RUNTIME_FUNCTION(Runtime_IsExtensible) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, obj, 0);
if (obj->IsJSGlobalProxy()) {
- Object* proto = obj->GetPrototype();
- if (proto->IsNull()) return isolate->heap()->false_value();
- ASSERT(proto->IsJSGlobalObject());
- obj = JSObject::cast(proto);
+ PrototypeIterator iter(isolate, obj);
+ if (iter.IsAtEnd()) return isolate->heap()->false_value();
+ DCHECK(iter.GetCurrent()->IsJSGlobalObject());
+ obj = JSObject::cast(iter.GetCurrent());
}
return isolate->heap()->ToBoolean(obj->map()->is_extensible());
}
RUNTIME_FUNCTION(Runtime_RegExpCompile) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
return *isolate->factory()->CreateApiFunction(data, prototype);
RUNTIME_FUNCTION(Runtime_IsTemplate) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
return isolate->heap()->ToBoolean(result);
RUNTIME_FUNCTION(Runtime_GetTemplateField) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(HeapObject, templ, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
int offset = index * kPointerSize + HeapObject::kHeaderSize;
RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
Handle<Map> old_map(object->map());
bool needs_access_checks = old_map->is_access_check_needed();
// Copy map so it won't interfere constructor's initial map.
Handle<Map> new_map = Map::Copy(old_map);
new_map->set_is_access_check_needed(false);
- if (object->IsJSObject()) {
- JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
- } else {
- object->set_map(*new_map);
- }
+ JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
}
return isolate->heap()->ToBoolean(needs_access_checks);
}
RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Handle<Map> old_map(object->map());
- if (!old_map->is_access_check_needed()) {
- // Copy map so it won't interfere constructor's initial map.
- Handle<Map> new_map = Map::Copy(old_map);
- new_map->set_is_access_check_needed(true);
- if (object->IsJSObject()) {
- JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
- } else {
- object->set_map(*new_map);
- }
- }
+ RUNTIME_ASSERT(!old_map->is_access_check_needed());
+ // Copy map so it won't interfere constructor's initial map.
+ Handle<Map> new_map = Map::Copy(old_map);
+ new_map->set_is_access_check_needed(true);
+ JSObject::MigrateToMap(object, new_map);
return isolate->heap()->undefined_value();
}
-// Transform getter or setter into something DefineAccessor can handle.
-static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
- Handle<Object> component) {
- if (component->IsUndefined()) return isolate->factory()->null_value();
- Handle<FunctionTemplateInfo> info =
- Handle<FunctionTemplateInfo>::cast(component);
- return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
+static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
+ HandleScope scope(isolate);
+ Handle<Object> args[1] = { name };
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError("var_redeclaration", HandleVector(args, 1)));
}
-RUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 6);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
- CONVERT_SMI_ARG_CHECKED(attribute, 4);
- CONVERT_SMI_ARG_CHECKED(access_control, 5);
- RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
- RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
- RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
- static_cast<PropertyAttributes>(attribute)));
- JSObject::DefineAccessor(object,
- name,
- InstantiateAccessorComponent(isolate, getter),
- InstantiateAccessorComponent(isolate, setter),
- static_cast<PropertyAttributes>(attribute),
- static_cast<v8::AccessControl>(access_control));
- return isolate->heap()->undefined_value();
-}
+// May throw a RedeclarationError.
+static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
+ Handle<String> name, Handle<Object> value,
+ PropertyAttributes attr, bool is_var,
+ bool is_const, bool is_function) {
+ // Do the lookup own properties only, see ES5 erratum.
+ LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+ Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+ if (!maybe.has_value) return isolate->heap()->exception();
+
+ if (it.IsFound()) {
+ PropertyAttributes old_attributes = maybe.value;
+ // The name was declared before; check for conflicting re-declarations.
+ if (is_const) return ThrowRedeclarationError(isolate, name);
+
+ // Skip var re-declarations.
+ if (is_var) return isolate->heap()->undefined_value();
+
+ DCHECK(is_function);
+ if ((old_attributes & DONT_DELETE) != 0) {
+ // Only allow reconfiguring globals to functions in user code (no
+ // natives, which are marked as read-only).
+ DCHECK((attr & READ_ONLY) == 0);
+
+ // Check whether we can reconfigure the existing property into a
+ // function.
+ PropertyDetails old_details = it.property_details();
+ // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
+ // which are actually data properties, not accessor properties.
+ if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
+ old_details.type() == CALLBACKS) {
+ return ThrowRedeclarationError(isolate, name);
+ }
+ // If the existing property is not configurable, keep its attributes. Do
+ attr = old_attributes;
+ }
+ }
+ // Define or redefine own property.
+ RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+ global, name, value, attr));
-static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
- HandleScope scope(isolate);
- Handle<Object> args[1] = { name };
- Handle<Object> error = isolate->factory()->NewTypeError(
- "var_redeclaration", HandleVector(args, 1));
- return isolate->Throw(*error);
+ return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(RuntimeHidden_DeclareGlobals) {
+RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
- Handle<GlobalObject> global = Handle<GlobalObject>(
- isolate->context()->global_object());
+ DCHECK(args.length() == 3);
+ Handle<GlobalObject> global(isolate->global_object());
CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
for (int i = 0; i < length; i += 2) {
HandleScope scope(isolate);
Handle<String> name(String::cast(pairs->get(i)));
- Handle<Object> value(pairs->get(i + 1), isolate);
+ Handle<Object> initial_value(pairs->get(i + 1), isolate);
// We have to declare a global const property. To capture we only
// assign to it when evaluating the assignment for "const x =
// <expr>" the initial value is the hole.
- bool is_var = value->IsUndefined();
- bool is_const = value->IsTheHole();
- bool is_function = value->IsSharedFunctionInfo();
- ASSERT(is_var + is_const + is_function == 1);
-
- if (is_var || is_const) {
- // Lookup the property in the global object, and don't set the
- // value of the variable if the property is already there.
- // Do the lookup own properties only, see ES5 erratum.
- LookupResult lookup(isolate);
- global->LookupOwn(name, &lookup, true);
- if (lookup.IsFound()) {
- // We found an existing property. Unless it was an interceptor
- // that claims the property is absent, skip this declaration.
- if (!lookup.IsInterceptor()) continue;
- if (JSReceiver::GetPropertyAttributes(global, name) != ABSENT) continue;
- // Fall-through and introduce the absent property by using
- // SetProperty.
- }
- } else if (is_function) {
+ bool is_var = initial_value->IsUndefined();
+ bool is_const = initial_value->IsTheHole();
+ bool is_function = initial_value->IsSharedFunctionInfo();
+ DCHECK(is_var + is_const + is_function == 1);
+
+ Handle<Object> value;
+ if (is_function) {
// Copy the function and update its context. Use it as value.
Handle<SharedFunctionInfo> shared =
- Handle<SharedFunctionInfo>::cast(value);
+ Handle<SharedFunctionInfo>::cast(initial_value);
Handle<JSFunction> function =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(
- shared, context, TENURED);
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+ TENURED);
value = function;
+ } else {
+ value = isolate->factory()->undefined_value();
}
- LookupResult lookup(isolate);
- global->LookupOwn(name, &lookup, true);
-
// Compute the property attributes. According to ECMA-262,
// the property must be non-configurable except in eval.
- int attr = NONE;
- bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
- if (!is_eval) {
- attr |= DONT_DELETE;
- }
bool is_native = DeclareGlobalsNativeFlag::decode(flags);
- if (is_const || (is_native && is_function)) {
- attr |= READ_ONLY;
- }
+ bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
+ int attr = NONE;
+ if (is_const) attr |= READ_ONLY;
+ if (is_function && is_native) attr |= READ_ONLY;
+ if (!is_const && !is_eval) attr |= DONT_DELETE;
- StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
+ Object* result = DeclareGlobals(isolate, global, name, value,
+ static_cast<PropertyAttributes>(attr),
+ is_var, is_const, is_function);
+ if (isolate->has_pending_exception()) return result;
+ }
- if (!lookup.IsFound() || is_function) {
- // If the own property exists, check that we can reconfigure it
- // as required for function declarations.
- if (lookup.IsFound() && lookup.IsDontDelete()) {
- if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
- lookup.IsPropertyCallbacks()) {
- return ThrowRedeclarationError(isolate, name);
- }
- // If the existing property is not configurable, keep its attributes.
- attr = lookup.GetAttributes();
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
+ HandleScope scope(isolate);
+ // args[0] == name
+ // args[1] == language_mode
+ // args[2] == value (optional)
+
+ // Determine if we need to assign to the variable if it already
+ // exists (based on the number of arguments).
+ RUNTIME_ASSERT(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+ CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+
+ Handle<GlobalObject> global(isolate->context()->global_object());
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, Object::SetProperty(global, name, value, strict_mode));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
+ HandleScope handle_scope(isolate);
+ // All constants are declared with an initial value. The name
+ // of the constant is the first argument and the initial value
+ // is the second.
+ RUNTIME_ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+
+ Handle<GlobalObject> global = isolate->global_object();
+
+ // Lookup the property as own on the global object.
+ LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+ Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+ DCHECK(maybe.has_value);
+ PropertyAttributes old_attributes = maybe.value;
+
+ PropertyAttributes attr =
+ static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+ // Set the value if the property is either missing, or the property attributes
+ // allow setting the value without invoking an accessor.
+ if (it.IsFound()) {
+ // Ignore if we can't reconfigure the value.
+ if ((old_attributes & DONT_DELETE) != 0) {
+ if ((old_attributes & READ_ONLY) != 0 ||
+ it.state() == LookupIterator::ACCESSOR) {
+ return *value;
}
- // Define or redefine own property.
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- global, name, value, static_cast<PropertyAttributes>(attr)));
- } else {
- // Do a [[Put]] on the existing (own) property.
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSObject::SetProperty(
- global, name, value, static_cast<PropertyAttributes>(attr),
- strict_mode));
+ attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
}
}
- ASSERT(!isolate->has_pending_exception());
- return isolate->heap()->undefined_value();
+ RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+ global, name, value, attr));
+
+ return *value;
}
-RUNTIME_FUNCTION(RuntimeHidden_DeclareContextSlot) {
+RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
- // Declarations are always made in a function or native context. In the
- // case of eval code, the context passed is the context of the caller,
+ // Declarations are always made in a function, native, or global context. In
+ // the case of eval code, the context passed is the context of the caller,
// which may be some nested context and not the declaration context.
CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
Handle<Context> context(context_arg->declaration_context());
CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
- CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
- PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
- RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
+ CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
+ PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
+ RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
+ // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
+ bool is_var = *initial_value == NULL;
+ bool is_const = initial_value->IsTheHole();
+ bool is_function = initial_value->IsJSFunction();
+ DCHECK(is_var + is_const + is_function == 1);
+
int index;
PropertyAttributes attributes;
ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes, &binding_flags);
+ Handle<JSObject> object;
+ Handle<Object> value =
+ is_function ? initial_value
+ : Handle<Object>::cast(isolate->factory()->undefined_value());
+
+ // TODO(verwaest): This case should probably not be covered by this function,
+ // but by DeclareGlobals instead.
+ if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
+ (context_arg->has_extension() &&
+ context_arg->extension()->IsJSGlobalObject())) {
+ return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
+ value, attr, is_var, is_const, is_function);
+ }
+
if (attributes != ABSENT) {
// The name was declared before; check for conflicting re-declarations.
- // Note: this is actually inconsistent with what happens for globals (where
- // we silently ignore such declarations).
- if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
- // Functions are not read-only.
- ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
+ if (is_const || (attributes & READ_ONLY) != 0) {
return ThrowRedeclarationError(isolate, name);
}
- // Initialize it if necessary.
- if (*initial_value != NULL) {
- if (index >= 0) {
- ASSERT(holder.is_identical_to(context));
- if (((attributes & READ_ONLY) == 0) ||
- context->get(index)->IsTheHole()) {
- context->set(index, *initial_value);
- }
- } else {
- // Slow case: The property is in the context extension object of a
- // function context or the global object of a native context.
- Handle<JSObject> object = Handle<JSObject>::cast(holder);
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
- }
- }
-
- } else {
- // The property is not in the function context. It needs to be
- // "declared" in the function context's extension context or as a
- // property of the the global object.
- Handle<JSObject> object;
- if (context->has_extension()) {
- object = Handle<JSObject>(JSObject::cast(context->extension()));
- } else {
- // Context extension objects are allocated lazily.
- ASSERT(context->IsFunctionContext());
- object = isolate->factory()->NewJSObject(
- isolate->context_extension_function());
- context->set_extension(*object);
- }
- ASSERT(*object != NULL);
-
- // Declare the property by setting it to the initial value if provided,
- // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
- // constant declarations).
- ASSERT(!JSReceiver::HasOwnProperty(object, name));
- Handle<Object> value(isolate->heap()->undefined_value(), isolate);
- if (*initial_value != NULL) value = initial_value;
- // Declaring a const context slot is a conflicting declaration if
- // there is a callback with that name in a prototype. It is
- // allowed to introduce const variables in
- // JSContextExtensionObjects. They are treated specially in
- // SetProperty and no setters are invoked for those since they are
- // not real JSObjects.
- if (initial_value->IsTheHole() &&
- !object->IsJSContextExtensionObject()) {
- LookupResult lookup(isolate);
- object->Lookup(name, &lookup);
- if (lookup.IsPropertyCallbacks()) {
- return ThrowRedeclarationError(isolate, name);
- }
- }
- if (object->IsJSGlobalObject()) {
- // Define own property on the global object.
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, mode));
- } else {
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
- }
- }
-
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
- HandleScope scope(isolate);
- // args[0] == name
- // args[1] == language_mode
- // args[2] == value (optional)
-
- // Determine if we need to assign to the variable if it already
- // exists (based on the number of arguments).
- RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
- bool assign = args.length() == 3;
+ // Skip var re-declarations.
+ if (is_var) return isolate->heap()->undefined_value();
- CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
-
- // According to ECMA-262, section 12.2, page 62, the property must
- // not be deletable.
- PropertyAttributes attributes = DONT_DELETE;
-
- // Lookup the property as own on the global object. If it isn't
- // there, there is a property with this name in the prototype chain.
- // We follow Safari and Firefox behavior and only set the property
- // if there is an explicit initialization value that we have
- // to assign to the property.
- // Note that objects can have hidden prototypes, so we need to traverse
- // the whole chain of hidden prototypes to do an 'own' lookup.
- LookupResult lookup(isolate);
- isolate->context()->global_object()->LookupOwn(name, &lookup, true);
- if (lookup.IsInterceptor()) {
- Handle<JSObject> holder(lookup.holder());
- PropertyAttributes intercepted =
- JSReceiver::GetPropertyAttributes(holder, name);
- if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
- // Found an interceptor that's not read only.
- if (assign) {
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::SetPropertyForResult(
- holder, &lookup, name, value, attributes, strict_mode));
- return *result;
- } else {
- return isolate->heap()->undefined_value();
- }
+ DCHECK(is_function);
+ if (index >= 0) {
+ DCHECK(holder.is_identical_to(context));
+ context->set(index, *initial_value);
+ return isolate->heap()->undefined_value();
}
- }
-
- if (assign) {
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
- Handle<GlobalObject> global(isolate->context()->global_object());
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
- return *result;
- }
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(RuntimeHidden_InitializeConstGlobal) {
- SealHandleScope shs(isolate);
- // All constants are declared with an initial value. The name
- // of the constant is the first argument and the initial value
- // is the second.
- RUNTIME_ASSERT(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-
- // Get the current global object from top.
- GlobalObject* global = isolate->context()->global_object();
-
- // According to ECMA-262, section 12.2, page 62, the property must
- // not be deletable. Since it's a const, it must be READ_ONLY too.
- PropertyAttributes attributes =
- static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
-
- // Lookup the property as own on the global object. If it isn't
- // there, we add the property and take special precautions to always
- // add it even in case of callbacks in the prototype chain (this rules
- // out using SetProperty). We use SetOwnPropertyIgnoreAttributes instead
- LookupResult lookup(isolate);
- global->LookupOwn(name, &lookup);
- if (!lookup.IsFound()) {
- HandleScope handle_scope(isolate);
- Handle<GlobalObject> global(isolate->context()->global_object());
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(global, name, value,
- attributes));
- return *value;
- }
- if (!lookup.IsReadOnly()) {
- // Restore global object from context (in case of GC) and continue
- // with setting the value.
- HandleScope handle_scope(isolate);
- Handle<GlobalObject> global(isolate->context()->global_object());
-
- // BUG 1213575: Handle the case where we have to set a read-only
- // property through an interceptor and only do it if it's
- // uninitialized, e.g. the hole. Nirk...
- // Passing sloppy mode because the property is writable.
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
- return *value;
- }
+ object = Handle<JSObject>::cast(holder);
- // Set the value, but only if we're assigning the initial value to a
- // constant. For now, we determine this by checking if the
- // current value is the hole.
- // Strict mode handling not needed (const is disallowed in strict mode).
- if (lookup.IsField()) {
- FixedArray* properties = global->properties();
- int index = lookup.GetFieldIndex().outobject_array_index();
- if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
- properties->set(index, *value);
- }
- } else if (lookup.IsNormal()) {
- if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
- !lookup.IsReadOnly()) {
- HandleScope scope(isolate);
- JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
- }
+ } else if (context->has_extension()) {
+ object = handle(JSObject::cast(context->extension()));
+ DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
} else {
- // Ignore re-initialization of constants that have already been
- // assigned a constant value.
- ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
+ DCHECK(context->IsFunctionContext());
+ object =
+ isolate->factory()->NewJSObject(isolate->context_extension_function());
+ context->set_extension(*object);
}
- // Use the set value as the result of the operation.
- return *value;
+ RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+ object, name, value, attr));
+
+ return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(RuntimeHidden_InitializeConstContextSlot) {
+RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
- ASSERT(!value->IsTheHole());
+ DCHECK(!value->IsTheHole());
// Initializations are always done in a function or native context.
CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
Handle<Context> context(context_arg->declaration_context());
int index;
PropertyAttributes attributes;
- ContextLookupFlags flags = FOLLOW_CHAINS;
+ ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
BindingFlags binding_flags;
Handle<Object> holder =
context->Lookup(name, flags, &index, &attributes, &binding_flags);
if (index >= 0) {
- ASSERT(holder->IsContext());
- // Property was found in a context. Perform the assignment if we
- // found some non-constant or an uninitialized constant.
+ DCHECK(holder->IsContext());
+ // Property was found in a context. Perform the assignment if the constant
+ // was uninitialized.
Handle<Context> context = Handle<Context>::cast(holder);
- if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
- context->set(index, *value);
- }
+ DCHECK((attributes & READ_ONLY) != 0);
+ if (context->get(index)->IsTheHole()) context->set(index, *value);
return *value;
}
- // The property could not be found, we introduce it as a property of the
- // global object.
- if (attributes == ABSENT) {
- Handle<JSObject> global = Handle<JSObject>(
- isolate->context()->global_object());
- // Strict mode not needed (const disallowed in strict mode).
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
- return *value;
- }
+ PropertyAttributes attr =
+ static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
- // The property was present in some function's context extension object,
- // as a property on the subject of a with, or as a property of the global
- // object.
- //
- // In most situations, eval-introduced consts should still be present in
- // the context extension object. However, because declaration and
- // initialization are separate, the property might have been deleted
- // before we reach the initialization point.
- //
- // Example:
- //
- // function f() { eval("delete x; const x;"); }
- //
- // In that case, the initialization behaves like a normal assignment.
- Handle<JSObject> object = Handle<JSObject>::cast(holder);
+ // Strict mode handling not needed (legacy const is disallowed in strict
+ // mode).
- if (*object == context->extension()) {
- // This is the property that was introduced by the const declaration.
- // Set it if it hasn't been set before. NOTE: We cannot use
- // GetProperty() to get the current value as it 'unholes' the value.
- LookupResult lookup(isolate);
- object->LookupOwnRealNamedProperty(name, &lookup);
- ASSERT(lookup.IsFound()); // the property was declared
- ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
-
- if (lookup.IsField()) {
- FixedArray* properties = object->properties();
- FieldIndex index = lookup.GetFieldIndex();
- ASSERT(!index.is_inobject());
- if (properties->get(index.outobject_array_index())->IsTheHole()) {
- properties->set(index.outobject_array_index(), *value);
- }
- } else if (lookup.IsNormal()) {
- if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
- JSObject::SetNormalizedProperty(object, &lookup, value);
- }
- } else {
- // We should not reach here. Any real, named property should be
- // either a field or a dictionary slot.
- UNREACHABLE();
- }
+ // The declared const was configurable, and may have been deleted in the
+ // meanwhile. If so, re-introduce the variable in the context extension.
+ DCHECK(context_arg->has_extension());
+ if (attributes == ABSENT) {
+ holder = handle(context_arg->extension(), isolate);
} else {
- // The property was found on some other object. Set it if it is not a
- // read-only property.
- if ((attributes & READ_ONLY) == 0) {
- // Strict mode not needed (const disallowed in strict mode).
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
+ // For JSContextExtensionObjects, the initializer can be run multiple times
+ // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
+ // first assignment should go through. For JSGlobalObjects, additionally any
+ // code can run in between that modifies the declared property.
+ DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
+
+ LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+ Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ PropertyAttributes old_attributes = maybe.value;
+
+ // Ignore if we can't reconfigure the value.
+ if ((old_attributes & DONT_DELETE) != 0) {
+ if ((old_attributes & READ_ONLY) != 0 ||
+ it.state() == LookupIterator::ACCESSOR) {
+ return *value;
+ }
+ attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
}
}
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+ Handle<JSObject>::cast(holder), name, value, attr));
+
return *value;
}
RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(properties, 1);
// Conservative upper limit to prevent fuzz tests from going OOM.
}
-RUNTIME_FUNCTION(RuntimeHidden_RegExpExec) {
+RUNTIME_FUNCTION(Runtime_RegExpExecRT) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
+ CONVERT_INT32_ARG_CHECKED(index, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
// Due to the way the JS calls are constructed this must be less than the
// length of a string, i.e. it is always a Smi. We check anyway for security.
- CONVERT_SMI_ARG_CHECKED(index, 2);
- CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
RUNTIME_ASSERT(index >= 0);
RUNTIME_ASSERT(index <= subject->length());
isolate->counters()->regexp_entry_runtime()->Increment();
}
-RUNTIME_FUNCTION(RuntimeHidden_RegExpConstructResult) {
+RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_SMI_ARG_CHECKED(size, 0);
RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
HandleScope scope(isolate);
- ASSERT(args.length() == 5);
+ DCHECK(args.length() == 6);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
// If source is the empty string we set it to "(?:)" instead as
CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
+ CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5);
+ if (!sticky->IsTrue()) sticky = isolate->factory()->false_value();
+
Map* map = regexp->map();
Object* constructor = map->constructor();
- if (constructor->IsJSFunction() &&
+ if (!FLAG_harmony_regexps &&
+ constructor->IsJSFunction() &&
JSFunction::cast(constructor)->initial_map() == map) {
// If we still have the original map, set in-object properties directly.
regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
return *regexp;
}
- // Map has changed, so use generic, but slower, method.
+ // Map has changed, so use generic, but slower, method. We also end here if
+ // the --harmony-regexp flag is set, because the initial map does not have
+ // space for the 'sticky' flag, since it is from the snapshot, but must work
+ // both with and without --harmony-regexp. When sticky comes out from under
+ // the flag, we will be able to use the fast initial map.
PropertyAttributes final =
static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
PropertyAttributes writable =
regexp, factory->ignore_case_string(), ignoreCase, final).Check();
JSObject::SetOwnPropertyIgnoreAttributes(
regexp, factory->multiline_string(), multiline, final).Check();
+ if (FLAG_harmony_regexps) {
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ regexp, factory->sticky_string(), sticky, final).Check();
+ }
JSObject::SetOwnPropertyIgnoreAttributes(
regexp, factory->last_index_string(), zero, writable).Check();
return *regexp;
RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
Object* length = prototype->length();
RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
Handle<JSFunction> optimized =
isolate->factory()->NewFunctionWithoutPrototype(key, code);
optimized->shared()->DontAdaptArguments();
- JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT).Assert();
+ JSObject::AddProperty(holder, key, optimized, NONE);
}
RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
Handle<JSObject> holder =
isolate->factory()->NewJSObject(isolate->object_function());
RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
if (!callable->IsJSFunction()) {
// Returns undefined for strict or native functions, or
// the associated global receiver for "normal" functions.
- Context* native_context =
- function->context()->global_object()->native_context();
- return native_context->global_object()->global_receiver();
+ return function->global_proxy();
}
-RUNTIME_FUNCTION(RuntimeHidden_MaterializeRegExpLiteral) {
+RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
RUNTIME_FUNCTION(Runtime_FunctionGetName) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return f->shared()->name();
RUNTIME_FUNCTION(Runtime_FunctionSetName) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
CONVERT_ARG_CHECKED(String, name, 1);
RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(
f->shared()->name_should_print_as_anonymous());
RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
f->shared()->set_name_should_print_as_anonymous(true);
return isolate->heap()->undefined_value();
RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(f->shared()->is_generator());
}
+RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
+ return isolate->heap()->ToBoolean(f->shared()->is_arrow());
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
+ return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
+}
+
+
RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
RUNTIME_ASSERT(f->RemovePrototype());
RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, fun, 0);
Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
Handle<SharedFunctionInfo> shared(f->shared());
RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, fun, 0);
int pos = fun->shared()->start_position();
RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(Code, code, 0);
CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(JSFunction, fun, 0);
CONVERT_ARG_CHECKED(String, name, 1);
RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(JSFunction, fun, 0);
CONVERT_SMI_ARG_CHECKED(length, 1);
RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(f->IsBuiltin());
RUNTIME_FUNCTION(Runtime_SetCode) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
// Mark both, the source and the target, as un-flushable because the
// shared unoptimized code makes them impossible to enqueue in a list.
- ASSERT(target_shared->code()->gc_metadata() == NULL);
- ASSERT(source_shared->code()->gc_metadata() == NULL);
+ DCHECK(target_shared->code()->gc_metadata() == NULL);
+ DCHECK(source_shared->code()->gc_metadata() == NULL);
target_shared->set_dont_flush(true);
source_shared->set_dont_flush(true);
// Set the code of the target function.
target->ReplaceCode(source_shared->code());
- ASSERT(target->next_function_link()->IsUndefined());
+ DCHECK(target->next_function_link()->IsUndefined());
// Make sure we get a fresh copy of the literal vector to avoid cross
// context contamination.
}
-RUNTIME_FUNCTION(RuntimeHidden_CreateJSGeneratorObject) {
+RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
}
-RUNTIME_FUNCTION(RuntimeHidden_SuspendJSGeneratorObject) {
+RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
JavaScriptFrameIterator stack_iterator(isolate);
JavaScriptFrame* frame = stack_iterator.frame();
RUNTIME_ASSERT(frame->function()->shared()->is_generator());
- ASSERT_EQ(frame->function(), generator_object->function());
+ DCHECK_EQ(frame->function(), generator_object->function());
// The caller should have saved the context and continuation already.
- ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
- ASSERT_LT(0, generator_object->continuation());
+ DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
+ DCHECK_LT(0, generator_object->continuation());
// We expect there to be at least two values on the operand stack: the return
// value of the yield expression, and the argument to this runtime call.
// Neither of those should be saved.
int operands_count = frame->ComputeOperandsCount();
- ASSERT_GE(operands_count, 2);
+ DCHECK_GE(operands_count, 2);
operands_count -= 2;
if (operands_count == 0) {
// Although it's semantically harmless to call this function with an
// operands_count of zero, it is also unnecessary.
- ASSERT_EQ(generator_object->operand_stack(),
+ DCHECK_EQ(generator_object->operand_stack(),
isolate->heap()->empty_fixed_array());
- ASSERT_EQ(generator_object->stack_handler_index(), -1);
+ DCHECK_EQ(generator_object->stack_handler_index(), -1);
// If there are no operands on the stack, there shouldn't be a handler
// active either.
- ASSERT(!frame->HasHandler());
+ DCHECK(!frame->HasHandler());
} else {
int stack_handler_index = -1;
Handle<FixedArray> operand_stack =
// inlined into GeneratorNext and GeneratorThrow. EmitGeneratorResumeResume is
// called in any case, as it needs to reconstruct the stack frame and make space
// for arguments and operands.
-RUNTIME_FUNCTION(RuntimeHidden_ResumeJSGeneratorObject) {
+RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
CONVERT_ARG_CHECKED(Object, value, 1);
CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
JavaScriptFrameIterator stack_iterator(isolate);
JavaScriptFrame* frame = stack_iterator.frame();
- ASSERT_EQ(frame->function(), generator_object->function());
- ASSERT(frame->function()->is_compiled());
+ DCHECK_EQ(frame->function(), generator_object->function());
+ DCHECK(frame->function()->is_compiled());
STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
Address pc = generator_object->function()->code()->instruction_start();
int offset = generator_object->continuation();
- ASSERT(offset > 0);
+ DCHECK(offset > 0);
frame->set_pc(pc + offset);
if (FLAG_enable_ool_constant_pool) {
frame->set_constant_pool(
}
-RUNTIME_FUNCTION(RuntimeHidden_ThrowGeneratorStateError) {
+RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
int continuation = generator->continuation();
const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
"generator_finished" : "generator_running";
Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
- Handle<Object> error = isolate->factory()->NewError(message, argv);
- return isolate->Throw(*error);
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
}
RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
// %ObjectFreeze is a fast path and these cases are handled elsewhere.
}
-RUNTIME_FUNCTION(RuntimeHidden_StringCharCodeAt) {
+RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
RUNTIME_FUNCTION(Runtime_CharFromCode) {
HandleScope handlescope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
if (args[0]->IsNumber()) {
CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
code &= 0xffff;
has_non_smi_elements_(false) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
- ASSERT(initial_capacity > 0);
+ DCHECK(initial_capacity > 0);
}
explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
has_non_smi_elements_(false) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
- ASSERT(backing_store->length() > 0);
+ DCHECK(backing_store->length() > 0);
}
bool HasCapacity(int elements) {
}
void Add(Object* value) {
- ASSERT(!value->IsSmi());
- ASSERT(length_ < capacity());
+ DCHECK(!value->IsSmi());
+ DCHECK(length_ < capacity());
array_->set(length_, value);
length_++;
has_non_smi_elements_ = true;
}
void Add(Smi* value) {
- ASSERT(value->IsSmi());
- ASSERT(length_ < capacity());
+ DCHECK(value->IsSmi());
+ DCHECK(length_ < capacity());
array_->set(length_, value);
length_++;
}
class ReplacementStringBuilder {
public:
- ReplacementStringBuilder(Heap* heap,
- Handle<String> subject,
+ ReplacementStringBuilder(Heap* heap, Handle<String> subject,
int estimated_part_count)
: heap_(heap),
array_builder_(heap->isolate(), estimated_part_count),
subject_(subject),
character_count_(0),
- is_ascii_(subject->IsOneByteRepresentation()) {
+ is_one_byte_(subject->IsOneByteRepresentation()) {
// Require a non-zero initial size. Ensures that doubling the size to
// extend the array will work.
- ASSERT(estimated_part_count > 0);
+ DCHECK(estimated_part_count > 0);
}
static inline void AddSubjectSlice(FixedArrayBuilder* builder,
int from,
int to) {
- ASSERT(from >= 0);
+ DCHECK(from >= 0);
int length = to - from;
- ASSERT(length > 0);
+ DCHECK(length > 0);
if (StringBuilderSubstringLength::is_valid(length) &&
StringBuilderSubstringPosition::is_valid(from)) {
int encoded_slice = StringBuilderSubstringLength::encode(length) |
void AddString(Handle<String> string) {
int length = string->length();
- ASSERT(length > 0);
+ DCHECK(length > 0);
AddElement(*string);
if (!string->IsOneByteRepresentation()) {
- is_ascii_ = false;
+ is_one_byte_ = false;
}
IncrementCharacterCount(length);
}
}
Handle<String> joined_string;
- if (is_ascii_) {
+ if (is_one_byte_) {
Handle<SeqOneByteString> seq;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, seq,
array_builder_.length());
joined_string = Handle<String>::cast(seq);
} else {
- // Non-ASCII.
+ // Two-byte.
Handle<SeqTwoByteString> seq;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, seq,
private:
void AddElement(Object* element) {
- ASSERT(element->IsSmi() || element->IsString());
- ASSERT(array_builder_.capacity() > array_builder_.length());
+ DCHECK(element->IsSmi() || element->IsString());
+ DCHECK(array_builder_.capacity() > array_builder_.length());
array_builder_.Add(element);
}
FixedArrayBuilder array_builder_;
Handle<String> subject_;
int character_count_;
- bool is_ascii_;
+ bool is_one_byte_;
};
return ReplacementPart(REPLACEMENT_STRING, 0);
}
static inline ReplacementPart ReplacementSubString(int from, int to) {
- ASSERT(from >= 0);
- ASSERT(to > from);
+ DCHECK(from >= 0);
+ DCHECK(to > from);
return ReplacementPart(-from, to);
}
ReplacementPart(int tag, int data)
: tag(tag), data(data) {
// Must be non-positive or a PartType value.
- ASSERT(tag < NUMBER_OF_PART_TYPES);
+ DCHECK(tag < NUMBER_OF_PART_TYPES);
}
// Either a value of PartType or a non-positive number that is
// the negation of an index into the replacement string.
if (i > last) {
parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
}
- ASSERT(capture_ref <= capture_count);
+ DCHECK(capture_ref <= capture_count);
parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
last = next_index + 1;
}
{
DisallowHeapAllocation no_gc;
String::FlatContent content = replacement->GetFlatContent();
- ASSERT(content.IsFlat());
+ DCHECK(content.IsFlat());
bool simple = false;
- if (content.IsAscii()) {
+ if (content.IsOneByte()) {
simple = ParseReplacementPattern(&parts_,
content.ToOneByteVector(),
capture_count,
subject_length,
zone());
} else {
- ASSERT(content.IsTwoByte());
+ DCHECK(content.IsTwoByte());
simple = ParseReplacementPattern(&parts_,
content.ToUC16Vector(),
capture_count,
int match_from,
int match_to,
int32_t* match) {
- ASSERT_LT(0, parts_.length());
+ DCHECK_LT(0, parts_.length());
for (int i = 0, n = parts_.length(); i < n; i++) {
ReplacementPart part = parts_[i];
switch (part.tag) {
}
-void FindAsciiStringIndices(Vector<const uint8_t> subject,
- char pattern,
- ZoneList<int>* indices,
- unsigned int limit,
- Zone* zone) {
- ASSERT(limit > 0);
+void FindOneByteStringIndices(Vector<const uint8_t> subject, char pattern,
+ ZoneList<int>* indices, unsigned int limit,
+ Zone* zone) {
+ DCHECK(limit > 0);
// Collect indices of pattern in subject using memchr.
// Stop after finding at most limit values.
const uint8_t* subject_start = subject.start();
ZoneList<int>* indices,
unsigned int limit,
Zone* zone) {
- ASSERT(limit > 0);
+ DCHECK(limit > 0);
const uc16* subject_start = subject.start();
const uc16* subject_end = subject_start + subject.length();
for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
ZoneList<int>* indices,
unsigned int limit,
Zone* zone) {
- ASSERT(limit > 0);
+ DCHECK(limit > 0);
// Collect indices of pattern in subject.
// Stop after finding at most limit values.
int pattern_length = pattern.length();
DisallowHeapAllocation no_gc;
String::FlatContent subject_content = subject->GetFlatContent();
String::FlatContent pattern_content = pattern->GetFlatContent();
- ASSERT(subject_content.IsFlat());
- ASSERT(pattern_content.IsFlat());
- if (subject_content.IsAscii()) {
+ DCHECK(subject_content.IsFlat());
+ DCHECK(pattern_content.IsFlat());
+ if (subject_content.IsOneByte()) {
Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
- if (pattern_content.IsAscii()) {
+ if (pattern_content.IsOneByte()) {
Vector<const uint8_t> pattern_vector =
pattern_content.ToOneByteVector();
if (pattern_vector.length() == 1) {
- FindAsciiStringIndices(subject_vector,
- pattern_vector[0],
- indices,
- limit,
- zone);
+ FindOneByteStringIndices(subject_vector, pattern_vector[0], indices,
+ limit, zone);
} else {
FindStringIndices(isolate,
subject_vector,
}
} else {
Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
- if (pattern_content.IsAscii()) {
+ if (pattern_content.IsOneByte()) {
Vector<const uint8_t> pattern_vector =
pattern_content.ToOneByteVector();
if (pattern_vector.length() == 1) {
Handle<JSRegExp> pattern_regexp,
Handle<String> replacement,
Handle<JSArray> last_match_info) {
- ASSERT(subject->IsFlat());
- ASSERT(replacement->IsFlat());
+ DCHECK(subject->IsFlat());
+ DCHECK(replacement->IsFlat());
ZoneScope zone_scope(isolate->runtime_zone());
ZoneList<int> indices(8, zone_scope.zone());
- ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
+ DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
String* pattern =
String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
int subject_len = subject->length();
int result_pos = 0;
MaybeHandle<SeqString> maybe_res;
- if (ResultSeqString::kHasAsciiEncoding) {
+ if (ResultSeqString::kHasOneByteEncoding) {
maybe_res = isolate->factory()->NewRawOneByteString(result_len);
} else {
maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
Handle<JSRegExp> regexp,
Handle<String> replacement,
Handle<JSArray> last_match_info) {
- ASSERT(subject->IsFlat());
- ASSERT(replacement->IsFlat());
+ DCHECK(subject->IsFlat());
+ DCHECK(replacement->IsFlat());
int capture_count = regexp->CaptureCount();
int subject_length = subject->length();
Handle<String> subject,
Handle<JSRegExp> regexp,
Handle<JSArray> last_match_info) {
- ASSERT(subject->IsFlat());
+ DCHECK(subject->IsFlat());
// Shortcut for simple non-regexp global replacements
if (regexp->TypeTag() == JSRegExp::ATOM) {
if (new_length == 0) return isolate->heap()->empty_string();
Handle<ResultSeqString> answer;
- if (ResultSeqString::kHasAsciiEncoding) {
+ if (ResultSeqString::kHasOneByteEncoding) {
answer = Handle<ResultSeqString>::cast(
isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
} else {
RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
Handle<String> sub,
Handle<String> pat,
int start_index) {
- ASSERT(0 <= start_index);
- ASSERT(start_index <= sub->length());
+ DCHECK(0 <= start_index);
+ DCHECK(start_index <= sub->length());
int pattern_length = pat->length();
if (pattern_length == 0) return start_index;
pat = String::Flatten(pat);
DisallowHeapAllocation no_gc; // ensure vectors stay valid
- // Extract flattened substrings of cons strings before determining asciiness.
+ // Extract flattened substrings of cons strings before getting encoding.
String::FlatContent seq_sub = sub->GetFlatContent();
String::FlatContent seq_pat = pat->GetFlatContent();
// dispatch on type of strings
- if (seq_pat.IsAscii()) {
+ if (seq_pat.IsOneByte()) {
Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
- if (seq_sub.IsAscii()) {
+ if (seq_sub.IsOneByte()) {
return SearchString(isolate,
seq_sub.ToOneByteVector(),
pat_vector,
start_index);
}
Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
- if (seq_sub.IsAscii()) {
+ if (seq_sub.IsOneByte()) {
return SearchString(isolate,
seq_sub.ToOneByteVector(),
pat_vector,
RUNTIME_FUNCTION(Runtime_StringIndexOf) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
Vector<const pchar> pattern,
int idx) {
int pattern_length = pattern.length();
- ASSERT(pattern_length >= 1);
- ASSERT(idx + pattern_length <= subject.length());
+ DCHECK(pattern_length >= 1);
+ DCHECK(idx + pattern_length <= subject.length());
if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
for (int i = 0; i < pattern_length; i++) {
RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
String::FlatContent sub_content = sub->GetFlatContent();
String::FlatContent pat_content = pat->GetFlatContent();
- if (pat_content.IsAscii()) {
+ if (pat_content.IsOneByte()) {
Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
- if (sub_content.IsAscii()) {
+ if (sub_content.IsOneByte()) {
position = StringMatchBackwards(sub_content.ToOneByteVector(),
pat_vector,
start_index);
}
} else {
Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
- if (sub_content.IsAscii()) {
+ if (sub_content.IsOneByte()) {
position = StringMatchBackwards(sub_content.ToOneByteVector(),
pat_vector,
start_index);
RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
}
-RUNTIME_FUNCTION(RuntimeHidden_SubString) {
+RUNTIME_FUNCTION(Runtime_SubString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
int start, end;
}
+RUNTIME_FUNCTION(Runtime_InternalizeString) {
+ HandleScope handles(isolate);
+ RUNTIME_ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
+ return *isolate->factory()->InternalizeString(string);
+}
+
+
RUNTIME_FUNCTION(Runtime_StringMatch) {
HandleScope handles(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
Handle<JSRegExp> regexp,
Handle<JSArray> last_match_array,
Handle<JSArray> result_array) {
- ASSERT(subject->IsFlat());
- ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
+ DCHECK(subject->IsFlat());
+ DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
int capture_count = regexp->CaptureCount();
int subject_length = subject->length();
if (global_cache.HasException()) return isolate->heap()->exception();
// Ensured in Runtime_RegExpExecMultiple.
- ASSERT(result_array->HasFastObjectElements());
+ DCHECK(result_array->HasFastObjectElements());
Handle<FixedArray> result_elements(
FixedArray::cast(result_array->elements()));
if (result_elements->length() < 16) {
int start = current_match[i * 2];
if (start >= 0) {
int end = current_match[i * 2 + 1];
- ASSERT(start <= end);
+ DCHECK(start <= end);
Handle<String> substring =
isolate->factory()->NewSubString(subject, start, end);
elements->set(i, *substring);
} else {
- ASSERT(current_match[i * 2 + 1] < 0);
+ DCHECK(current_match[i * 2 + 1] < 0);
elements->set(i, isolate->heap()->undefined_value());
}
}
// set any other last match array info.
RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
HandleScope handles(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(radix, 1);
RUNTIME_ASSERT(2 <= radix && radix <= 36);
RUNTIME_FUNCTION(Runtime_NumberToFixed) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
RUNTIME_FUNCTION(Runtime_NumberToExponential) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
RUNTIME_FUNCTION(Runtime_IsValidSmi) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
return isolate->heap()->ToBoolean(Smi::IsValid(number));
Handle<Object> result;
if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- Handle<Object> proto(object->GetPrototype(isolate), isolate);
- return Object::GetElement(isolate, proto, index);
+ PrototypeIterator iter(isolate, object);
+ return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
+ index);
} else {
return Object::GetElement(isolate, object, index);
}
MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
Handle<JSReceiver> object,
Handle<Object> key) {
+ Maybe<bool> maybe;
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
- return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
- }
+ maybe = JSReceiver::HasElement(object, index);
+ } else {
+ // Convert the key to a name - possibly by calling back into JavaScript.
+ Handle<Name> name;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
- // Convert the key to a name - possibly by calling back into JavaScript.
- Handle<Name> name;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
+ maybe = JSReceiver::HasProperty(object, name);
+ }
- return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
+ if (!maybe.has_value) return MaybeHandle<Object>();
+ return isolate->factory()->ToBoolean(maybe.value);
}
Handle<Object> key) {
if (object->IsUndefined() || object->IsNull()) {
Handle<Object> args[2] = { key, object };
- return isolate->Throw<Object>(
- isolate->factory()->NewTypeError("non_object_property_load",
- HandleVector(args, 2)));
+ THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load",
+ HandleVector(args, 2)),
+ Object);
}
// Check if the given key is an array index.
RUNTIME_FUNCTION(Runtime_GetProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
int index = keyed_lookup_cache->Lookup(receiver_map, key);
if (index != -1) {
// Doubles are not cached, so raw read the value.
- Object* value = receiver->RawFastPropertyAt(
+ return receiver->RawFastPropertyAt(
FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
- return value->IsTheHole()
- ? isolate->heap()->undefined_value()
- : value;
}
// Lookup cache miss. Perform lookup and update the cache if
// appropriate.
- LookupResult result(isolate);
- receiver->LookupOwn(key, &result);
- if (result.IsField()) {
- FieldIndex field_index = result.GetFieldIndex();
+ LookupIterator it(receiver, key, LookupIterator::OWN);
+ if (it.state() == LookupIterator::DATA &&
+ it.property_details().type() == FIELD) {
+ FieldIndex field_index = it.GetFieldIndex();
// Do not track double fields in the keyed lookup cache. Reading
// double values requires boxing.
- if (!result.representation().IsDouble()) {
+ if (!it.representation().IsDouble()) {
keyed_lookup_cache->Update(receiver_map, key,
field_index.GetKeyedLookupCacheIndex());
}
AllowHeapAllocation allow_allocation;
- return *JSObject::FastPropertyAt(receiver, result.representation(),
+ return *JSObject::FastPropertyAt(receiver, it.representation(),
field_index);
}
} else {
if (!receiver->IsGlobalObject()) return value;
value = PropertyCell::cast(value)->value();
if (!value->IsTheHole()) return value;
- // If value is the hole do the general lookup.
+ // If value is the hole (meaning, absent) do the general lookup.
}
}
- } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) {
+ } else if (key_obj->IsSmi()) {
// JSObject without a name key. If the key is a Smi, check for a
// definite out-of-bounds access to elements, which is a strong indicator
// that subsequent accesses will also call the runtime. Proactively
isolate, TransitionElements(js_object, elements_kind, isolate));
}
} else {
- ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
+ DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
!IsFastElementsKind(elements_kind));
}
}
}
+// Transform getter or setter into something DefineAccessor can handle.
+static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
+ Handle<Object> component) {
+ if (component->IsUndefined()) return isolate->factory()->undefined_value();
+ Handle<FunctionTemplateInfo> info =
+ Handle<FunctionTemplateInfo>::cast(component);
+ return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 5);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
+ CONVERT_SMI_ARG_CHECKED(attribute, 4);
+ RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
+ RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
+ RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
+ static_cast<PropertyAttributes>(attribute)));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::DefineAccessor(
+ object, name, InstantiateAccessorComponent(isolate, getter),
+ InstantiateAccessorComponent(isolate, setter),
+ static_cast<PropertyAttributes>(attribute)));
+ return isolate->heap()->undefined_value();
+}
+
+
// Implements part of 8.12.9 DefineOwnProperty.
// There are 3 cases that lead here:
// Step 4b - define a new accessor property.
// Steps 9c & 12 - replace an existing data property with an accessor property.
// Step 12 - update an existing accessor property with an accessor or generic
// descriptor.
-RUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) {
+RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
HandleScope scope(isolate);
- ASSERT(args.length() == 5);
+ DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
RUNTIME_ASSERT(!obj->IsNull());
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
bool fast = obj->HasFastProperties();
- // DefineAccessor checks access rights.
- JSObject::DefineAccessor(obj, name, getter, setter, attr);
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- if (fast) JSObject::TransformToFastProperties(obj, 0);
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
+ if (fast) JSObject::MigrateSlowToFast(obj, 0);
return isolate->heap()->undefined_value();
}
// Steps 9b & 12 - replace an existing accessor property with a data property.
// Step 12 - update an existing data property with a data or generic
// descriptor.
-RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
+RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
- // Check access rights if needed.
- if (js_object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
- return isolate->heap()->undefined_value();
+ LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
+ if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
+ if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
+ return isolate->heap()->undefined_value();
+ }
+ it.Next();
}
- LookupResult lookup(isolate);
- js_object->LookupOwnRealNamedProperty(name, &lookup);
-
// Take special care when attributes are different and there is already
- // a property. For simplicity we normalize the property which enables us
- // to not worry about changing the instance_descriptor and creating a new
- // map. The current version of SetObjectProperty does not handle attributes
- // correctly in the case where a property is a field and is reset with
- // new attributes.
- if (lookup.IsFound() &&
- (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
- // New attributes - normalize to avoid writing to instance descriptor
- if (js_object->IsJSGlobalProxy()) {
- // Since the result is a property, the prototype will exist so
- // we don't have to check for null.
- js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
- }
-
- if (attr != lookup.GetAttributes() ||
- (lookup.IsPropertyCallbacks() &&
- !lookup.GetCallbackObject()->IsAccessorInfo())) {
- JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
- }
-
+ // a property.
+ if (it.state() == LookupIterator::ACCESSOR) {
// Use IgnoreAttributes version since a readonly property may be
// overridden and SetProperty does not allow this.
Handle<Object> result;
isolate, result,
JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, obj_value, attr,
- Object::OPTIMAL_REPRESENTATION,
- ALLOW_AS_CONSTANT,
- JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
- JSReceiver::MAY_BE_STORE_FROM_KEYED,
JSObject::DONT_FORCE_FIELD));
return *result;
}
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- Runtime::ForceSetObjectProperty(
- js_object, name, obj_value, attr,
- JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
+ Runtime::DefineObjectProperty(js_object, name, obj_value, attr));
return *result;
}
// Return property without being observable by accessors or interceptors.
RUNTIME_FUNCTION(Runtime_GetDataProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
return *JSObject::GetDataProperty(object, key);
Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
- PropertyAttributes attr,
StrictMode strict_mode) {
- SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
-
if (object->IsUndefined() || object->IsNull()) {
Handle<Object> args[2] = { key, object };
- Handle<Object> error =
- isolate->factory()->NewTypeError("non_object_property_store",
- HandleVector(args, 2));
- return isolate->Throw<Object>(error);
+ THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store",
+ HandleVector(args, 2)),
+ Object);
}
if (object->IsJSProxy()) {
isolate, name_object, Execution::ToString(isolate, key), Object);
}
Handle<Name> name = Handle<Name>::cast(name_object);
- return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
- attr,
- strict_mode);
+ return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
+ strict_mode);
}
- // If the object isn't a JavaScript object, we ignore the store.
- if (!object->IsJSObject()) return value;
-
- Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
+ // TODO(verwaest): Support non-JSObject receivers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+
// In Firefox/SpiderMonkey, Safari and Opera you can access the characters
// of a string using [] notation. We need to support this too in
// JavaScript.
JSObject::ValidateElements(js_object);
if (js_object->HasExternalArrayElements() ||
js_object->HasFixedTypedArrayElements()) {
- if (!value->IsNumber() && !value->IsUndefined()) {
+ if (!value->IsNumber() && !value->IsFloat32x4() &&
+ !value->IsFloat64x2() && !value->IsInt32x4() &&
+ !value->IsUndefined()) {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, Execution::ToNumber(isolate, value), Object);
}
}
MaybeHandle<Object> result = JSObject::SetElement(
- js_object, index, value, attr, strict_mode, true, set_mode);
+ js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
JSObject::ValidateElements(js_object);
return result.is_null() ? result : value;
if (key->IsName()) {
Handle<Name> name = Handle<Name>::cast(key);
if (name->AsArrayIndex(&index)) {
+ // TODO(verwaest): Support non-JSObject receivers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> js_object = Handle<JSObject>::cast(object);
if (js_object->HasExternalArrayElements()) {
- if (!value->IsNumber() && !value->IsUndefined()) {
+ if (!value->IsNumber() && !value->IsFloat32x4() &&
+ !value->IsFloat64x2() && !value->IsInt32x4() &&
+ !value->IsUndefined()) {
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, Execution::ToNumber(isolate, value), Object);
}
}
- return JSObject::SetElement(js_object, index, value, attr,
- strict_mode, true, set_mode);
+ return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
+ true, SET_PROPERTY);
} else {
if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
- return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
+ return Object::SetProperty(object, name, value, strict_mode);
}
}
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- return JSObject::SetElement(js_object, index, value, attr,
- strict_mode, true, set_mode);
- } else {
- return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
+ // TODO(verwaest): Support non-JSObject receivers.
+ if (!object->IsJSObject()) return value;
+ Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+ return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
+ true, SET_PROPERTY);
}
+ return Object::SetProperty(object, name, value, strict_mode);
}
-MaybeHandle<Object> Runtime::ForceSetObjectProperty(
- Handle<JSObject> js_object,
- Handle<Object> key,
- Handle<Object> value,
- PropertyAttributes attr,
- JSReceiver::StoreFromKeyed store_from_keyed) {
+MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
+ Handle<Object> key,
+ Handle<Object> value,
+ PropertyAttributes attr) {
Isolate* isolate = js_object->GetIsolate();
// Check if the given key is an array index.
uint32_t index;
SLOPPY, false, DEFINE_PROPERTY);
} else {
if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
- return JSObject::SetOwnPropertyIgnoreAttributes(
- js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
- ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
- store_from_keyed);
+ return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
+ attr);
}
}
return JSObject::SetElement(js_object, index, value, attr,
SLOPPY, false, DEFINE_PROPERTY);
} else {
- return JSObject::SetOwnPropertyIgnoreAttributes(
- js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
- ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
- store_from_keyed);
+ return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
+ attr);
}
}
}
-RUNTIME_FUNCTION(Runtime_SetProperty) {
+RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
HandleScope scope(isolate);
- RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
+ RUNTIME_ASSERT(args.length() == 4);
- CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+ CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+ RUNTIME_ASSERT(
+ (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+ // Compute attributes.
+ PropertyAttributes attributes =
+ static_cast<PropertyAttributes>(unchecked_attributes);
+
+#ifdef DEBUG
+ uint32_t index = 0;
+ DCHECK(!key->ToArrayIndex(&index));
+ LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
+ Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ RUNTIME_ASSERT(!it.IsFound());
+#endif
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
+ HandleScope scope(isolate);
+ RUNTIME_ASSERT(args.length() == 4);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
PropertyAttributes attributes =
static_cast<PropertyAttributes>(unchecked_attributes);
- StrictMode strict_mode = SLOPPY;
- if (args.length() == 5) {
- CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 4);
- strict_mode = strict_mode_arg;
+#ifdef DEBUG
+ bool duplicate;
+ if (key->IsName()) {
+ LookupIterator it(object, Handle<Name>::cast(key),
+ LookupIterator::OWN_SKIP_INTERCEPTOR);
+ Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+ DCHECK(maybe.has_value);
+ duplicate = it.IsFound();
+ } else {
+ uint32_t index = 0;
+ RUNTIME_ASSERT(key->ToArrayIndex(&index));
+ Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ duplicate = maybe.value;
+ }
+ if (duplicate) {
+ Handle<Object> args[1] = { key };
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewTypeError("duplicate_template_property", HandleVector(args, 1)));
}
+#endif
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::DefineObjectProperty(object, key, value, attributes));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetProperty) {
+ HandleScope scope(isolate);
+ RUNTIME_ASSERT(args.length() == 4);
+
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+ CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
+ StrictMode strict_mode = strict_mode_arg;
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- Runtime::SetObjectProperty(
- isolate, object, key, value, attributes, strict_mode));
+ Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
+ return *result;
+}
+
+
+// Adds an element to an array.
+// This is used to create an indexed data property into an array.
+RUNTIME_FUNCTION(Runtime_AddElement) {
+ HandleScope scope(isolate);
+ RUNTIME_ASSERT(args.length() == 4);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+ CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+ RUNTIME_ASSERT(
+ (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+ // Compute attributes.
+ PropertyAttributes attributes =
+ static_cast<PropertyAttributes>(unchecked_attributes);
+
+ uint32_t index = 0;
+ key->ToArrayIndex(&index);
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::SetElement(object, index, value, attributes,
+ SLOPPY, false, DEFINE_PROPERTY));
return *result;
}
}
Handle<JSArray> boilerplate_object(boilerplate);
ElementsKind elements_kind = object->GetElementsKind();
- ASSERT(IsFastElementsKind(elements_kind));
+ DCHECK(IsFastElementsKind(elements_kind));
// Smis should never trigger transitions.
- ASSERT(!value->IsSmi());
+ DCHECK(!value->IsSmi());
if (value->IsNumber()) {
- ASSERT(IsFastSmiElementsKind(elements_kind));
+ DCHECK(IsFastSmiElementsKind(elements_kind));
ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
? FAST_HOLEY_DOUBLE_ELEMENTS
: FAST_DOUBLE_ELEMENTS;
JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
}
JSObject::TransitionElementsKind(object, transitioned_kind);
- ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
+ DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
HeapNumber* number = HeapNumber::cast(*value);
double_array->set(store_index, number->Number());
// Check whether debugger and is about to step into the callback that is passed
// to a built-in function such as Array.forEach.
RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
return isolate->heap()->false_value();
}
// Set one shot breakpoints for the callback function that is passed to a
// built-in function such as Array.forEach to enable stepping into the callback.
RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
Debug* debug = isolate->debug();
if (!debug->IsStepping()) return isolate->heap()->undefined_value();
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
+
HandleScope scope(isolate);
- // When leaving the callback, step out has been activated, but not performed
- // if we do not leave the builtin. To be able to step into the callback
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
+ Handle<JSFunction> fun;
+ if (object->IsJSFunction()) {
+ fun = Handle<JSFunction>::cast(object);
+ } else {
+ fun = Handle<JSFunction>(
+ Handle<JSGeneratorObject>::cast(object)->function(), isolate);
+ }
+ // When leaving the function, step out has been activated, but not performed
+ // if we do not leave the builtin. To be able to step into the function
// again, we need to clear the step out at this point.
debug->ClearStepOut();
- debug->FloodWithOneShot(callback);
+ debug->FloodWithOneShot(fun);
return isolate->heap()->undefined_value();
}
-// The argument is a closure that is kept until the epilogue is called.
-// On exception, the closure is called, which returns the promise if the
-// exception is considered uncaught, or undefined otherwise.
-RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
- ASSERT(args.length() == 1);
+RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
+ DCHECK(args.length() == 1);
HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
- isolate->debug()->PromiseHandlePrologue(promise_getter);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+ isolate->PushPromise(promise);
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
- ASSERT(args.length() == 0);
+RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
+ DCHECK(args.length() == 0);
SealHandleScope shs(isolate);
- isolate->debug()->PromiseHandleEpilogue();
+ isolate->PopPromise();
return isolate->heap()->undefined_value();
}
-// Set an own property, even if it is READ_ONLY. If the property does not
-// exist, it will be added with attributes NONE.
-RUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
+RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
+ DCHECK(args.length() == 1);
HandleScope scope(isolate);
- RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
- // Compute attributes.
- PropertyAttributes attributes = NONE;
- if (args.length() == 4) {
- CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
- // Only attribute bits should be set.
- RUNTIME_ASSERT(
- (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
- attributes = static_cast<PropertyAttributes>(unchecked_value);
- }
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::SetOwnPropertyIgnoreAttributes(
- object, name, value, attributes));
- return *result;
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+ isolate->debug()->OnPromiseEvent(data);
+ return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(Runtime_DeleteProperty) {
+RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
+ DCHECK(args.length() == 2);
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
- CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
- JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
- ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
- Handle<Object> result;
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+ isolate->debug()->OnPromiseReject(promise, value);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
+ DCHECK(args.length() == 1);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+ isolate->debug()->OnAsyncTaskEvent(data);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeleteProperty) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+ CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
+ JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
+ ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
+ Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
JSReceiver::DeleteProperty(object, key, delete_mode));
static Object* HasOwnPropertyImplementation(Isolate* isolate,
Handle<JSObject> object,
Handle<Name> key) {
- if (JSReceiver::HasOwnProperty(object, key)) {
- return isolate->heap()->true_value();
- }
+ Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ if (maybe.value) return isolate->heap()->true_value();
// Handle hidden prototypes. If there's a hidden prototype above this thing
// then we have to check it for properties, because they are supposed to
// look like they are on this object.
- Handle<Object> proto(object->GetPrototype(), isolate);
- if (proto->IsJSObject() &&
- Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
- return HasOwnPropertyImplementation(isolate,
- Handle<JSObject>::cast(proto),
- key);
+ PrototypeIterator iter(isolate, object);
+ if (!iter.IsAtEnd() &&
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
+ ->map()
+ ->is_hidden_prototype()) {
+ // TODO(verwaest): The recursion is not necessary for keys that are array
+ // indices. Removing this.
+ return HasOwnPropertyImplementation(
+ isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+ key);
}
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->false_value();
RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
// Fast case: either the key is a real named property or it is not
// an array index and there are no interceptors or hidden
// prototypes.
- if (JSObject::HasRealNamedProperty(js_obj, key)) {
- ASSERT(!isolate->has_scheduled_exception());
+ Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ DCHECK(!isolate->has_pending_exception());
+ if (maybe.value) {
return isolate->heap()->true_value();
- } else {
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
Map* map = js_obj->map();
if (!key_is_array_index &&
RUNTIME_FUNCTION(Runtime_HasProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
- bool result = JSReceiver::HasProperty(receiver, key);
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- if (isolate->has_pending_exception()) return isolate->heap()->exception();
- return isolate->heap()->ToBoolean(result);
+ Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(maybe.value);
}
RUNTIME_FUNCTION(Runtime_HasElement) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
- bool result = JSReceiver::HasElement(receiver, index);
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return isolate->heap()->ToBoolean(result);
+ Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(maybe.value);
}
RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
- PropertyAttributes att = JSReceiver::GetOwnPropertyAttributes(object, key);
- if (att == ABSENT || (att & DONT_ENUM) != 0) {
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return isolate->heap()->false_value();
- }
- ASSERT(!isolate->has_scheduled_exception());
- return isolate->heap()->true_value();
+ Maybe<PropertyAttributes> maybe =
+ JSReceiver::GetOwnPropertyAttributes(object, key);
+ if (!maybe.has_value) return isolate->heap()->exception();
+ if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
+ return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
}
RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Handle<JSArray> result;
// the check for deletions during a for-in.
RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
// is prototype for.
static int OwnPrototypeChainLength(JSObject* obj) {
int count = 1;
- Object* proto = obj->GetPrototype();
- while (proto->IsJSObject() &&
- JSObject::cast(proto)->map()->is_hidden_prototype()) {
+ for (PrototypeIterator iter(obj->GetIsolate(), obj);
+ !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
count++;
- proto = JSObject::cast(proto)->GetPrototype();
}
return count;
}
// args[1]: PropertyAttributes as int
RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
if (!args[0]->IsJSObject()) {
return isolate->heap()->undefined_value();
}
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
- obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
+ PrototypeIterator iter(isolate, obj);
+ obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
}
// Find the number of objects making up this.
// Find the number of own properties for each of the objects.
ScopedVector<int> own_property_count(length);
int total_property_count = 0;
- Handle<JSObject> jsproto = obj;
- for (int i = 0; i < length; i++) {
- // Only collect names if access is permitted.
- if (jsproto->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(
- jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return *isolate->factory()->NewJSArray(0);
- }
- int n;
- n = jsproto->NumberOfOwnProperties(filter);
- own_property_count[i] = n;
- total_property_count += n;
- if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ {
+ PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+ for (int i = 0; i < length; i++) {
+ DCHECK(!iter.IsAtEnd());
+ Handle<JSObject> jsproto =
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+ // Only collect names if access is permitted.
+ if (jsproto->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(jsproto,
+ isolate->factory()->undefined_value(),
+ v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+ return *isolate->factory()->NewJSArray(0);
+ }
+ int n;
+ n = jsproto->NumberOfOwnProperties(filter);
+ own_property_count[i] = n;
+ total_property_count += n;
+ iter.Advance();
}
}
isolate->factory()->NewFixedArray(total_property_count);
// Get the property names.
- jsproto = obj;
int next_copy_index = 0;
int hidden_strings = 0;
- for (int i = 0; i < length; i++) {
- jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
- if (i > 0) {
- // Names from hidden prototypes may already have been added
- // for inherited function template instances. Count the duplicates
- // and stub them out; the final copy pass at the end ignores holes.
- for (int j = next_copy_index;
- j < next_copy_index + own_property_count[i];
- j++) {
- Object* name_from_hidden_proto = names->get(j);
- for (int k = 0; k < next_copy_index; k++) {
- if (names->get(k) != isolate->heap()->hidden_string()) {
- Object* name = names->get(k);
- if (name_from_hidden_proto == name) {
- names->set(j, isolate->heap()->hidden_string());
- hidden_strings++;
- break;
+ {
+ PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+ for (int i = 0; i < length; i++) {
+ DCHECK(!iter.IsAtEnd());
+ Handle<JSObject> jsproto =
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+ jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
+ if (i > 0) {
+ // Names from hidden prototypes may already have been added
+ // for inherited function template instances. Count the duplicates
+ // and stub them out; the final copy pass at the end ignores holes.
+ for (int j = next_copy_index;
+ j < next_copy_index + own_property_count[i]; j++) {
+ Object* name_from_hidden_proto = names->get(j);
+ for (int k = 0; k < next_copy_index; k++) {
+ if (names->get(k) != isolate->heap()->hidden_string()) {
+ Object* name = names->get(k);
+ if (name_from_hidden_proto == name) {
+ names->set(j, isolate->heap()->hidden_string());
+ hidden_strings++;
+ break;
+ }
}
}
}
}
- }
- next_copy_index += own_property_count[i];
+ next_copy_index += own_property_count[i];
- // Hidden properties only show up if the filter does not skip strings.
- if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
- hidden_strings++;
- }
- if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ // Hidden properties only show up if the filter does not skip strings.
+ if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
+ hidden_strings++;
+ }
+ iter.Advance();
}
}
}
names->set(dest_pos++, name);
}
- ASSERT_EQ(0, hidden_strings);
+ DCHECK_EQ(0, hidden_strings);
}
return *isolate->factory()->NewJSArrayWithElements(names);
// args[0]: object
RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
if (!args[0]->IsJSObject()) {
return isolate->heap()->undefined_value();
}
// args[0]: object
RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
if (!args[0]->IsJSObject()) {
return Smi::FromInt(0);
}
// args[0]: object
RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
if (obj->HasNamedInterceptor()) {
// args[0]: object
RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
if (obj->HasIndexedInterceptor()) {
RUNTIME_FUNCTION(Runtime_OwnKeys) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
Handle<JSObject> object(raw_object);
return *isolate->factory()->NewJSArray(0);
}
- Handle<Object> proto(object->GetPrototype(), isolate);
+ PrototypeIterator iter(isolate, object);
// If proxy is detached we simply return an empty array.
- if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
- object = Handle<JSObject>::cast(proto);
+ if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
+ object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
}
Handle<FixedArray> contents;
if (entry->IsString()) {
copy->set(i, entry);
} else {
- ASSERT(entry->IsNumber());
+ DCHECK(entry->IsNumber());
HandleScope scope(isolate);
Handle<Object> entry_handle(entry, isolate);
Handle<Object> entry_str =
RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
// Compute the frame holding the arguments.
HandleScope scope(isolate);
if (raw_key->IsSymbol()) {
+ Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
+ if (symbol->Equals(isolate->native_context()->iterator_symbol())) {
+ return isolate->native_context()->array_values_iterator();
+ }
// Lookup in the initial Object.prototype object.
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
if (String::Equals(isolate->factory()->callee_string(), key)) {
JSFunction* function = frame->function();
if (function->shared()->strict_mode() == STRICT) {
- return isolate->Throw(*isolate->factory()->NewTypeError(
- "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError("strict_arguments_callee",
+ HandleVector<Object>(NULL, 0)));
}
return function;
}
RUNTIME_FUNCTION(Runtime_ToFastProperties) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
if (object->IsJSObject() && !object->IsGlobalObject()) {
- JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0);
+ JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0);
}
return *object;
}
RUNTIME_FUNCTION(Runtime_ToBool) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, object, 0);
return isolate->heap()->ToBoolean(object->BooleanValue());
// Possible optimizations: put the type string into the oddballs.
RUNTIME_FUNCTION(Runtime_Typeof) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, obj, 0);
if (obj->IsNumber()) return isolate->heap()->number_string();
HeapObject* heap_obj = HeapObject::cast(obj);
return isolate->heap()->boolean_string();
}
if (heap_obj->IsNull()) {
- return FLAG_harmony_typeof
- ? isolate->heap()->null_string()
- : isolate->heap()->object_string();
+ return isolate->heap()->object_string();
}
- ASSERT(heap_obj->IsUndefined());
+ DCHECK(heap_obj->IsUndefined());
return isolate->heap()->undefined_string();
case SYMBOL_TYPE:
return isolate->heap()->symbol_string();
}
+RUNTIME_FUNCTION(Runtime_Booleanize) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_CHECKED(Object, value_raw, 0);
+ CONVERT_SMI_ARG_CHECKED(token_raw, 1);
+ intptr_t value = reinterpret_cast<intptr_t>(value_raw);
+ Token::Value token = static_cast<Token::Value>(token_raw);
+ switch (token) {
+ case Token::EQ:
+ case Token::EQ_STRICT:
+ return isolate->heap()->ToBoolean(value == 0);
+ case Token::NE:
+ case Token::NE_STRICT:
+ return isolate->heap()->ToBoolean(value != 0);
+ case Token::LT:
+ return isolate->heap()->ToBoolean(value < 0);
+ case Token::GT:
+ return isolate->heap()->ToBoolean(value > 0);
+ case Token::LTE:
+ return isolate->heap()->ToBoolean(value <= 0);
+ case Token::GTE:
+ return isolate->heap()->ToBoolean(value >= 0);
+ default:
+ // This should only happen during natives fuzzing.
+ return isolate->heap()->undefined_value();
+ }
+}
+
+
static bool AreDigits(const uint8_t*s, int from, int to) {
for (int i = from; i < to; i++) {
if (s[i] < '0' || s[i] > '9') return false;
static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
- ASSERT(to - from < 10); // Overflow is not possible.
- ASSERT(from < to);
+ DCHECK(to - from < 10); // Overflow is not possible.
+ DCHECK(from < to);
int d = s[from] - '0';
for (int i = from + 1; i < to; i++) {
RUNTIME_FUNCTION(Runtime_StringToNumber) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
subject = String::Flatten(subject);
uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
#ifdef DEBUG
subject->Hash(); // Force hash calculation.
- ASSERT_EQ(static_cast<int>(subject->hash_field()),
+ DCHECK_EQ(static_cast<int>(subject->hash_field()),
static_cast<int>(hash));
#endif
subject->set_hash_field(hash);
RUNTIME_FUNCTION(Runtime_NewString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
- CONVERT_SMI_ARG_CHECKED(length, 0);
+ DCHECK(args.length() == 2);
+ CONVERT_INT32_ARG_CHECKED(length, 0);
CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
if (length == 0) return isolate->heap()->empty_string();
Handle<String> result;
RUNTIME_FUNCTION(Runtime_TruncateString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
- CONVERT_SMI_ARG_CHECKED(new_length, 1);
+ CONVERT_INT32_ARG_CHECKED(new_length, 1);
RUNTIME_ASSERT(new_length >= 0);
return *SeqString::Truncate(string, new_length);
}
RUNTIME_FUNCTION(Runtime_URIEscape) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
Handle<String> string = String::Flatten(source);
- ASSERT(string->IsFlat());
+ DCHECK(string->IsFlat());
Handle<String> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
RUNTIME_FUNCTION(Runtime_URIUnescape) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
Handle<String> string = String::Flatten(source);
- ASSERT(string->IsFlat());
+ DCHECK(string->IsFlat());
Handle<String> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
BasicJsonStringifier stringifier(isolate);
Handle<Object> result;
RUNTIME_FUNCTION(Runtime_StringParseInt) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
String::FlatContent flat = subject->GetFlatContent();
// ECMA-262 section 15.1.2.3, empty string is NaN
- if (flat.IsAscii()) {
+ if (flat.IsOneByte()) {
value = StringToInt(
isolate->unicode_cache(), flat.ToOneByteVector(), radix);
} else {
RUNTIME_FUNCTION(Runtime_StringParseFloat) {
HandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
subject = String::Flatten(subject);
- double value = StringToDouble(
- isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
+ double value = StringToDouble(isolate->unicode_cache(), *subject,
+ ALLOW_TRAILING_JUNK, base::OS::nan_value());
return *isolate->factory()->NewNumber(value);
}
} else if (char_length == 1 &&
(ignore_overflow || !ToUpperOverflows(current))) {
// Common case: converting the letter resulted in one character.
- ASSERT(static_cast<uc32>(chars[0]) != current);
+ DCHECK(static_cast<uc32>(chars[0]) != current);
result->Set(i, chars[0]);
has_changed_character = true;
i++;
current_length += char_length;
if (current_length > String::kMaxLength) {
AllowHeapAllocation allocate_error_and_return;
- return isolate->ThrowInvalidStringLength();
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+ NewInvalidStringLengthError());
}
}
// Try again with the real length. Return signed if we need
static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
// Use strict inequalities since in edge cases the function could be
// further simplified.
- ASSERT(0 < m && m < n);
+ DCHECK(0 < m && m < n);
// Has high bit set in every w byte less than n.
uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
// Has high bit set in every w byte greater than m.
if (dst[i] == src[i]) continue;
expected_changed = true;
if (is_to_lower) {
- ASSERT('A' <= src[i] && src[i] <= 'Z');
- ASSERT(dst[i] == src[i] + ('a' - 'A'));
+ DCHECK('A' <= src[i] && src[i] <= 'Z');
+ DCHECK(dst[i] == src[i] + ('a' - 'A'));
} else {
- ASSERT('a' <= src[i] && src[i] <= 'z');
- ASSERT(dst[i] == src[i] - ('a' - 'A'));
+ DCHECK('a' <= src[i] && src[i] <= 'z');
+ DCHECK(dst[i] == src[i] - ('a' - 'A'));
}
}
return (expected_changed == changed);
DisallowHeapAllocation no_gc;
// We rely on the distance between upper and lower case letters
// being a known power of 2.
- ASSERT('a' - 'A' == (1 << 5));
+ DCHECK('a' - 'A' == (1 << 5));
// Boundaries for the range of input characters than require conversion.
static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
bool changed = false;
uintptr_t or_acc = 0;
const char* const limit = src + length;
-#ifdef V8_HOST_CAN_READ_UNALIGNED
- // Process the prefix of the input that requires no conversion one
- // (machine) word at a time.
- while (src <= limit - sizeof(uintptr_t)) {
- const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
- or_acc |= w;
- if (AsciiRangeMask(w, lo, hi) != 0) {
- changed = true;
- break;
+
+ // dst is newly allocated and always aligned.
+ DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t)));
+ // Only attempt processing one word at a time if src is also aligned.
+ if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) {
+ // Process the prefix of the input that requires no conversion one aligned
+ // (machine) word at a time.
+ while (src <= limit - sizeof(uintptr_t)) {
+ const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
+ or_acc |= w;
+ if (AsciiRangeMask(w, lo, hi) != 0) {
+ changed = true;
+ break;
+ }
+ *reinterpret_cast<uintptr_t*>(dst) = w;
+ src += sizeof(uintptr_t);
+ dst += sizeof(uintptr_t);
+ }
+ // Process the remainder of the input performing conversion when
+ // required one word at a time.
+ while (src <= limit - sizeof(uintptr_t)) {
+ const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
+ or_acc |= w;
+ uintptr_t m = AsciiRangeMask(w, lo, hi);
+ // The mask has high (7th) bit set in every byte that needs
+ // conversion and we know that the distance between cases is
+ // 1 << 5.
+ *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
+ src += sizeof(uintptr_t);
+ dst += sizeof(uintptr_t);
}
- *reinterpret_cast<uintptr_t*>(dst) = w;
- src += sizeof(uintptr_t);
- dst += sizeof(uintptr_t);
- }
- // Process the remainder of the input performing conversion when
- // required one word at a time.
- while (src <= limit - sizeof(uintptr_t)) {
- const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
- or_acc |= w;
- uintptr_t m = AsciiRangeMask(w, lo, hi);
- // The mask has high (7th) bit set in every byte that needs
- // conversion and we know that the distance between cases is
- // 1 << 5.
- *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
- src += sizeof(uintptr_t);
- dst += sizeof(uintptr_t);
}
-#endif
// Process the last few bytes of the input (or the whole input if
// unaligned access is not supported).
while (src < limit) {
++src;
++dst;
}
- if ((or_acc & kAsciiMask) != 0) {
- return false;
- }
- ASSERT(CheckFastAsciiConvert(
+ if ((or_acc & kAsciiMask) != 0) return false;
+
+ DCHECK(CheckFastAsciiConvert(
saved_dst, saved_src, length, changed, Converter::kIsToLower));
*changed_out = changed;
isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
DisallowHeapAllocation no_gc;
String::FlatContent flat_content = s->GetFlatContent();
- ASSERT(flat_content.IsFlat());
+ DCHECK(flat_content.IsFlat());
bool has_changed_character = false;
bool is_ascii = FastAsciiConvert<Converter>(
reinterpret_cast<char*>(result->GetChars()),
Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
if (answer->IsException() || answer->IsString()) return answer;
- ASSERT(answer->IsSmi());
+ DCHECK(answer->IsSmi());
length = Smi::cast(answer)->value();
if (s->IsOneByteRepresentation() && length > 0) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return ConvertCase(
s, isolate, isolate->runtime_state()->to_lower_mapping());
RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return ConvertCase(
s, isolate, isolate->runtime_state()->to_upper_mapping());
RUNTIME_FUNCTION(Runtime_StringTrim) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
RUNTIME_FUNCTION(Runtime_StringSplit) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
JSObject::EnsureCanContainHeapObjectElements(result);
result->set_length(Smi::FromInt(part_count));
- ASSERT(result->HasFastObjectElements());
+ DCHECK(result->HasFastObjectElements());
if (part_count == 1 && indices.at(0) == subject_length) {
FixedArray::cast(result->elements())->set(0, *subject);
}
-// Copies ASCII characters to the given fixed array looking up
+// Copies Latin1 characters to the given fixed array looking up
// one-char strings in the cache. Gives up on the first char that is
// not in the cache and fills the remainder with smi zeros. Returns
// the length of the successfully copied prefix.
-static int CopyCachedAsciiCharsToArray(Heap* heap,
- const uint8_t* chars,
- FixedArray* elements,
- int length) {
+static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars,
+ FixedArray* elements, int length) {
DisallowHeapAllocation no_gc;
- FixedArray* ascii_cache = heap->single_character_string_cache();
+ FixedArray* one_byte_cache = heap->single_character_string_cache();
Object* undefined = heap->undefined_value();
int i;
WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
for (i = 0; i < length; ++i) {
- Object* value = ascii_cache->get(chars[i]);
+ Object* value = one_byte_cache->get(chars[i]);
if (value == undefined) break;
elements->set(i, value, mode);
}
if (i < length) {
- ASSERT(Smi::FromInt(0) == 0);
+ DCHECK(Smi::FromInt(0) == 0);
memset(elements->data_start() + i, 0, kPointerSize * (length - i));
}
#ifdef DEBUG
for (int j = 0; j < length; ++j) {
Object* element = elements->get(j);
- ASSERT(element == Smi::FromInt(0) ||
+ DCHECK(element == Smi::FromInt(0) ||
(element->IsString() && String::cast(element)->LooksValid()));
}
#endif
// For example, "foo" => ["f", "o", "o"].
RUNTIME_FUNCTION(Runtime_StringToArray) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
DisallowHeapAllocation no_gc;
String::FlatContent content = s->GetFlatContent();
- if (content.IsAscii()) {
+ if (content.IsOneByte()) {
Vector<const uint8_t> chars = content.ToOneByteVector();
// Note, this will initialize all elements (not only the prefix)
// to prevent GC from seeing partially initialized array.
- position = CopyCachedAsciiCharsToArray(isolate->heap(),
- chars.start(),
- *elements,
- length);
+ position = CopyCachedOneByteCharsToArray(isolate->heap(), chars.start(),
+ *elements, length);
} else {
MemsetPointer(elements->data_start(),
isolate->heap()->undefined_value(),
#ifdef DEBUG
for (int i = 0; i < length; ++i) {
- ASSERT(String::cast(elements->get(i))->length() == 1);
+ DCHECK(String::cast(elements->get(i))->length() == 1);
}
#endif
RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
return *Object::ToObject(isolate, value).ToHandleChecked();
}
}
-RUNTIME_FUNCTION(RuntimeHidden_NumberToString) {
+RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
return *isolate->factory()->NumberToString(number);
}
-RUNTIME_FUNCTION(RuntimeHidden_NumberToStringSkipCache) {
+RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
return *isolate->factory()->NumberToString(number, false);
RUNTIME_FUNCTION(Runtime_NumberToInteger) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(number, 0);
return *isolate->factory()->NewNumber(DoubleToInteger(number));
RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(number, 0);
double double_value = DoubleToInteger(number);
RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
return *isolate->factory()->NewNumberFromUint(number);
RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(number, 0);
return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
// Converts a Number to a Smi, if possible. Returns NaN if the number is not
// a small integer.
-RUNTIME_FUNCTION(RuntimeHidden_NumberToSmi) {
+RUNTIME_FUNCTION(Runtime_NumberToSmi) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, obj, 0);
if (obj->IsSmi()) {
return obj;
}
-RUNTIME_FUNCTION(RuntimeHidden_AllocateHeapNumber) {
+RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
return *isolate->factory()->NewHeapNumber(0);
}
+RUNTIME_FUNCTION(Runtime_AllocateFloat32x4) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+
+ float32x4_value_t zero = {{0, 0, 0, 0}};
+ return *isolate->factory()->NewFloat32x4(zero);
+}
+
+
+RUNTIME_FUNCTION(Runtime_AllocateFloat64x2) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+
+ float64x2_value_t zero = {{0, 0}};
+ return *isolate->factory()->NewFloat64x2(zero);
+}
+
+
+RUNTIME_FUNCTION(Runtime_AllocateInt32x4) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+
+ int32x4_value_t zero = {{0, 0, 0, 0}};
+ return *isolate->factory()->NewInt32x4(zero);
+}
+
+
RUNTIME_FUNCTION(Runtime_NumberAdd) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
RUNTIME_FUNCTION(Runtime_NumberSub) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
RUNTIME_FUNCTION(Runtime_NumberMul) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
return *isolate->factory()->NewNumber(-x);
RUNTIME_FUNCTION(Runtime_NumberDiv) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
RUNTIME_FUNCTION(Runtime_NumberMod) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
RUNTIME_FUNCTION(Runtime_NumberImul) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
- CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
- CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return *isolate->factory()->NewNumberFromInt(x * y);
+ // We rely on implementation-defined behavior below, but at least not on
+ // undefined behavior.
+ CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
+ CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
+ int32_t product = static_cast<int32_t>(x * y);
+ return *isolate->factory()->NewNumberFromInt(product);
}
-RUNTIME_FUNCTION(RuntimeHidden_StringAdd) {
+RUNTIME_FUNCTION(Runtime_StringAdd) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
isolate->counters()->string_add_runtime()->Increment();
} else {
// Position and length encoded in two smis.
Object* obj = fixed_array->get(++i);
- ASSERT(obj->IsSmi());
+ DCHECK(obj->IsSmi());
pos = Smi::cast(obj)->value();
len = -encoded_slice;
}
pos = Smi::cast(next_smi)->value();
if (pos < 0) return -1;
}
- ASSERT(pos >= 0);
- ASSERT(len >= 0);
+ DCHECK(pos >= 0);
+ DCHECK(len >= 0);
if (pos > special_length || len > special_length - pos) return -1;
increment = len;
} else if (elt->IsString()) {
RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
- if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
- CONVERT_SMI_ARG_CHECKED(array_length, 1);
+ int32_t array_length;
+ if (!args[1]->ToInt32(&array_length)) {
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
+ }
CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
size_t actual_array_length = 0;
RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
// This assumption is used by the slice encoding in one or two smis.
- ASSERT(Smi::kMaxValue >= String::kMaxLength);
+ DCHECK(Smi::kMaxValue >= String::kMaxLength);
RUNTIME_ASSERT(array->HasFastElements());
JSObject::EnsureCanContainHeapObjectElements(array);
RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
- if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
- CONVERT_SMI_ARG_CHECKED(array_length, 1);
+ int32_t array_length;
+ if (!args[1]->ToInt32(&array_length)) {
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
+ }
CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
RUNTIME_ASSERT(array->HasFastObjectElements());
RUNTIME_ASSERT(array_length >= 0);
int max_nof_separators =
(String::kMaxLength + separator_length - 1) / separator_length;
if (max_nof_separators < (array_length - 1)) {
- return isolate->ThrowInvalidStringLength();
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
}
int length = (array_length - 1) * separator_length;
for (int i = 0; i < array_length; i++) {
sink += first_length;
for (int i = 1; i < array_length; i++) {
- ASSERT(sink + separator_length <= end);
+ DCHECK(sink + separator_length <= end);
String::WriteToFlat(separator_raw, sink, 0, separator_length);
sink += separator_length;
RUNTIME_ASSERT(fixed_array->get(i)->IsString());
String* element = String::cast(fixed_array->get(i));
int element_length = element->length();
- ASSERT(sink + element_length <= end);
+ DCHECK(sink + element_length <= end);
String::WriteToFlat(element, sink, 0, element_length);
sink += element_length;
}
- ASSERT(sink == end);
+ DCHECK(sink == end);
- // Use %_FastAsciiArrayJoin instead.
- ASSERT(!answer->IsOneByteRepresentation());
+ // Use %_FastOneByteArrayJoin instead.
+ DCHECK(!answer->IsOneByteRepresentation());
return *answer;
}
if (separator_length > 0) {
// Array length must be representable as a signed 32-bit number,
// otherwise the total string length would have been too large.
- ASSERT(array_length <= 0x7fffffff); // Is int32_t.
+ DCHECK(array_length <= 0x7fffffff); // Is int32_t.
int last_array_index = static_cast<int>(array_length - 1);
while (previous_separator_position < last_array_index) {
String::WriteToFlat<Char>(separator, &buffer[cursor],
previous_separator_position++;
}
}
- ASSERT(cursor <= buffer.length());
+ DCHECK(cursor <= buffer.length());
}
RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
// Find total length of join result.
int string_length = 0;
- bool is_ascii = separator->IsOneByteRepresentation();
+ bool is_one_byte = separator->IsOneByteRepresentation();
bool overflow = false;
CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
for (int i = 0; i < elements_length; i += 2) {
String* string = String::cast(elements->get(i + 1));
int length = string->length();
- if (is_ascii && !string->IsOneByteRepresentation()) {
- is_ascii = false;
+ if (is_one_byte && !string->IsOneByteRepresentation()) {
+ is_one_byte = false;
}
if (length > String::kMaxLength ||
String::kMaxLength - length < string_length) {
// Throw an exception if the resulting string is too large. See
// https://code.google.com/p/chromium/issues/detail?id=336820
// for details.
- return isolate->ThrowInvalidStringLength();
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
}
- if (is_ascii) {
+ if (is_one_byte) {
Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
string_length).ToHandleChecked();
JoinSparseArrayWithSeparator<uint8_t>(
RUNTIME_FUNCTION(Runtime_NumberOr) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_NumberAnd) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_NumberXor) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_NumberShl) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_NumberShr) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_NumberSar) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_NumberEquals) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
RUNTIME_FUNCTION(Runtime_StringEquals) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
// This is slightly convoluted because the value that signifies
// equality is 0 and inequality is 1 so we have to negate the result
// from String::Equals.
- ASSERT(not_equal == 0 || not_equal == 1);
+ DCHECK(not_equal == 0 || not_equal == 1);
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(NOT_EQUAL == 1);
return Smi::FromInt(not_equal);
RUNTIME_FUNCTION(Runtime_NumberCompare) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
// compared lexicographically.
RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(x_value, 0);
CONVERT_SMI_ARG_CHECKED(y_value, 1);
}
-RUNTIME_FUNCTION(RuntimeHidden_StringCompare) {
+RUNTIME_FUNCTION(Runtime_StringCompare) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
int r;
String::FlatContent x_content = x->GetFlatContent();
String::FlatContent y_content = y->GetFlatContent();
- if (x_content.IsAscii()) {
+ if (x_content.IsOneByte()) {
Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
- if (y_content.IsAscii()) {
+ if (y_content.IsOneByte()) {
Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
} else {
}
} else {
Vector<const uc16> x_chars = x_content.ToUC16Vector();
- if (y_content.IsAscii()) {
+ if (y_content.IsOneByte()) {
Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
} else {
#define RUNTIME_UNARY_MATH(Name, name) \
RUNTIME_FUNCTION(Runtime_Math##Name) { \
HandleScope scope(isolate); \
- ASSERT(args.length() == 1); \
+ DCHECK(args.length() == 1); \
isolate->counters()->math_##name()->Increment(); \
CONVERT_DOUBLE_ARG_CHECKED(x, 0); \
return *isolate->factory()->NewHeapNumber(std::name(x)); \
RUNTIME_FUNCTION(Runtime_DoubleHi) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
uint64_t integer = double_to_uint64(x);
integer = (integer >> 32) & 0xFFFFFFFFu;
RUNTIME_FUNCTION(Runtime_DoubleLo) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
return *isolate->factory()->NewNumber(
static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
RUNTIME_FUNCTION(Runtime_ConstructDouble) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
}
+RUNTIME_FUNCTION(Runtime_RemPiO2) {
+ HandleScope handle_scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+ Factory* factory = isolate->factory();
+ double y[2] = {0.0, 0.0};
+ int n = fdlibm::rempio2(x, y);
+ Handle<FixedArray> array = factory->NewFixedArray(3);
+ Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
+ Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
+ array->set(0, Smi::FromInt(n));
+ array->set(1, *y0);
+ array->set(2, *y1);
+ return *factory->NewJSArrayWithElements(array);
+}
+
+
static const double kPiDividedBy4 = 0.78539816339744830962;
RUNTIME_FUNCTION(Runtime_MathAtan2) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
isolate->counters()->math_atan2()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_FUNCTION(Runtime_MathExpRT) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
isolate->counters()->math_exp()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_FUNCTION(Runtime_MathFloorRT) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
isolate->counters()->math_floor()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return *isolate->factory()->NewNumber(std::floor(x));
+ return *isolate->factory()->NewNumber(Floor(x));
}
// Slow version of Math.pow. We check for fast paths for special cases.
// Used if VFP3 is not available.
-RUNTIME_FUNCTION(RuntimeHidden_MathPowSlow) {
+RUNTIME_FUNCTION(Runtime_MathPowSlow) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
isolate->counters()->math_pow()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
// Fast version of Math.pow if we know that y is not an integer and y is not
// -0.5 or 0.5. Used as slow case from full codegen.
-RUNTIME_FUNCTION(RuntimeHidden_MathPow) {
+RUNTIME_FUNCTION(Runtime_MathPowRT) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
isolate->counters()->math_pow()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_FUNCTION(Runtime_RoundNumber) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
isolate->counters()->math_round()->Increment();
if (!input->IsHeapNumber()) {
- ASSERT(input->IsSmi());
+ DCHECK(input->IsSmi());
return *input;
}
if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
// Do not call NumberFromDouble() to avoid extra checks.
- return *isolate->factory()->NewNumber(std::floor(value + 0.5));
+ return *isolate->factory()->NewNumber(Floor(value + 0.5));
}
RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
isolate->counters()->math_sqrt()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_FUNCTION(Runtime_MathFround) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- float xf = static_cast<float>(x);
+ float xf = DoubleToFloat32(x);
return *isolate->factory()->NewNumber(xf);
}
RUNTIME_FUNCTION(Runtime_DateMakeDay) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(year, 0);
CONVERT_SMI_ARG_CHECKED(month, 1);
RUNTIME_FUNCTION(Runtime_DateSetValue) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
CONVERT_DOUBLE_ARG_CHECKED(time, 1);
}
-RUNTIME_FUNCTION(RuntimeHidden_NewSloppyArguments) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 3);
-
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
- Object** parameters = reinterpret_cast<Object**>(args[1]);
- CONVERT_SMI_ARG_CHECKED(argument_count, 2);
-
+static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
+ Handle<JSFunction> callee,
+ Object** parameters,
+ int argument_count) {
Handle<JSObject> result =
isolate->factory()->NewArgumentsObject(callee, argument_count);
+
// Allocate the elements if needed.
int parameter_count = callee->shared()->formal_parameter_count();
if (argument_count > 0) {
break;
}
}
- ASSERT(context_index >= 0);
+ DCHECK(context_index >= 0);
arguments->set_the_hole(index);
parameter_map->set(index + 2, Smi::FromInt(
Context::MIN_CONTEXT_SLOTS + context_index));
}
}
}
- return *result;
+ return result;
}
-RUNTIME_FUNCTION(RuntimeHidden_NewStrictArguments) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
- Object** parameters = reinterpret_cast<Object**>(args[1]);
- CONVERT_SMI_ARG_CHECKED(length, 2);
-
+static Handle<JSObject> NewStrictArguments(Isolate* isolate,
+ Handle<JSFunction> callee,
+ Object** parameters,
+ int argument_count) {
Handle<JSObject> result =
- isolate->factory()->NewArgumentsObject(callee, length);
+ isolate->factory()->NewArgumentsObject(callee, argument_count);
- if (length > 0) {
+ if (argument_count > 0) {
Handle<FixedArray> array =
- isolate->factory()->NewUninitializedFixedArray(length);
+ isolate->factory()->NewUninitializedFixedArray(argument_count);
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
- for (int i = 0; i < length; i++) {
+ for (int i = 0; i < argument_count; i++) {
array->set(i, *--parameters, mode);
}
result->set_elements(*array);
}
- return *result;
+ return result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewArguments) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
+ JavaScriptFrameIterator it(isolate);
+
+ // Find the frame that holds the actual arguments passed to the function.
+ it.AdvanceToArgumentsFrame();
+ JavaScriptFrame* frame = it.frame();
+
+ // Determine parameter location on the stack and dispatch on language mode.
+ int argument_count = frame->GetArgumentsLength();
+ Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
+ return callee->shared()->strict_mode() == STRICT
+ ? *NewStrictArguments(isolate, callee, parameters, argument_count)
+ : *NewSloppyArguments(isolate, callee, parameters, argument_count);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
+ Object** parameters = reinterpret_cast<Object**>(args[1]);
+ CONVERT_SMI_ARG_CHECKED(argument_count, 2);
+ return *NewSloppyArguments(isolate, callee, parameters, argument_count);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
+ Object** parameters = reinterpret_cast<Object**>(args[1]);
+ CONVERT_SMI_ARG_CHECKED(argument_count, 2);
+ return *NewStrictArguments(isolate, callee, parameters, argument_count);
}
-RUNTIME_FUNCTION(RuntimeHidden_NewClosureFromStubFailure) {
+RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
Handle<Context> context(isolate->context());
PretenureFlag pretenure_flag = NOT_TENURED;
- return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
- shared, context, pretenure_flag);
+ return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+ pretenure_flag);
}
-RUNTIME_FUNCTION(RuntimeHidden_NewClosure) {
+RUNTIME_FUNCTION(Runtime_NewClosure) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(bound_function, length_string,
- new_length, attr));
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ bound_function, length_string, new_length, attr));
return *bound_function;
}
RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
HandleScope handles(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
if (callable->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
// First argument is a function to use as a constructor.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
RUNTIME_ASSERT(function->shared()->bound());
Handle<Object> bound_function(
JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
isolate);
- ASSERT(!bound_function->IsJSFunction() ||
+ DCHECK(!bound_function->IsJSFunction() ||
!Handle<JSFunction>::cast(bound_function)->shared()->bound());
int total_argc = 0;
isolate, bound_function,
Execution::TryGetConstructorDelegate(isolate, bound_function));
}
- ASSERT(bound_function->IsJSFunction());
+ DCHECK(bound_function->IsJSFunction());
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
// If the constructor isn't a proper function we throw a type error.
if (!constructor->IsJSFunction()) {
Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
- Handle<Object> type_error =
- isolate->factory()->NewTypeError("not_constructor", arguments);
- return isolate->Throw(*type_error);
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+ NewTypeError("not_constructor", arguments));
}
Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
// case generated code bailouts here, since function has no initial_map.
if (!function->should_have_prototype() && !function->shared()->bound()) {
Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
- Handle<Object> type_error =
- isolate->factory()->NewTypeError("not_constructor", arguments);
- return isolate->Throw(*type_error);
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+ NewTypeError("not_constructor", arguments));
}
Debug* debug = isolate->debug();
// instead of a new JSFunction object. This way, errors are
// reported the same way whether or not 'Function' is called
// using 'new'.
- return isolate->context()->global_object();
+ return isolate->global_proxy();
}
}
}
-RUNTIME_FUNCTION(RuntimeHidden_NewObject) {
+RUNTIME_FUNCTION(Runtime_NewObject) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
return Runtime_NewObjectHelper(isolate,
constructor,
}
-RUNTIME_FUNCTION(RuntimeHidden_NewObjectWithAllocationSite) {
+RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
Handle<AllocationSite> site;
}
-RUNTIME_FUNCTION(RuntimeHidden_FinalizeInstanceSize) {
+RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
function->CompleteInobjectSlackTracking();
}
-RUNTIME_FUNCTION(RuntimeHidden_CompileUnoptimized) {
+RUNTIME_FUNCTION(Runtime_CompileLazy) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
#ifdef DEBUG
if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
#endif
// Compile the target function.
- ASSERT(function->shared()->allows_lazy_compilation());
+ DCHECK(function->shared()->allows_lazy_compilation());
Handle<Code> code;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
- Compiler::GetUnoptimizedCode(function));
+ Compiler::GetLazyCode(function));
+ DCHECK(code->kind() == Code::FUNCTION ||
+ code->kind() == Code::OPTIMIZED_FUNCTION);
function->ReplaceCode(*code);
-
- // All done. Return the compiled code.
- ASSERT(function->is_compiled());
- ASSERT(function->code()->kind() == Code::FUNCTION ||
- (FLAG_always_opt &&
- function->code()->kind() == Code::OPTIMIZED_FUNCTION));
return *code;
}
-RUNTIME_FUNCTION(RuntimeHidden_CompileOptimized) {
+RUNTIME_FUNCTION(Runtime_CompileOptimized) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
Handle<Code> unoptimized(function->shared()->code());
- if (!function->shared()->is_compiled()) {
- // If the function is not compiled, do not optimize.
- // This can happen if the debugger is activated and
- // the function is returned to the not compiled state.
- // TODO(yangguo): reconsider this.
- function->ReplaceCode(function->shared()->code());
- } else if (!isolate->use_crankshaft() ||
- function->shared()->optimization_disabled() ||
- isolate->DebuggerHasBreakPoints()) {
+ if (!isolate->use_crankshaft() ||
+ function->shared()->optimization_disabled() ||
+ isolate->DebuggerHasBreakPoints()) {
// If the function is not optimizable or debugger is active continue
// using the code from the full compiler.
if (FLAG_trace_opt) {
isolate->DebuggerHasBreakPoints() ? "T" : "F");
}
function->ReplaceCode(*unoptimized);
+ return function->code();
+ }
+
+ Compiler::ConcurrencyMode mode =
+ concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
+ Handle<Code> code;
+ if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
+ function->ReplaceCode(*code);
} else {
- Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
- : Compiler::NOT_CONCURRENT;
- Handle<Code> code;
- if (Compiler::GetOptimizedCode(
- function, unoptimized, mode).ToHandle(&code)) {
- function->ReplaceCode(*code);
- } else {
- function->ReplaceCode(*unoptimized);
- }
+ function->ReplaceCode(function->shared()->code());
}
- ASSERT(function->code()->kind() == Code::FUNCTION ||
+ DCHECK(function->code()->kind() == Code::FUNCTION ||
function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
function->IsInOptimizationQueue());
return function->code();
};
-RUNTIME_FUNCTION(RuntimeHidden_NotifyStubFailure) {
+RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
- ASSERT(AllowHeapAllocation::IsAllowed());
+ DCHECK(AllowHeapAllocation::IsAllowed());
delete deoptimizer;
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(RuntimeHidden_NotifyDeoptimized) {
+RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_SMI_ARG_CHECKED(type_arg, 0);
Deoptimizer::BailoutType type =
static_cast<Deoptimizer::BailoutType>(type_arg);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
- ASSERT(AllowHeapAllocation::IsAllowed());
+ DCHECK(AllowHeapAllocation::IsAllowed());
Handle<JSFunction> function = deoptimizer->function();
Handle<Code> optimized_code = deoptimizer->compiled_code();
- ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
- ASSERT(type == deoptimizer->bailout_type());
+ DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
+ DCHECK(type == deoptimizer->bailout_type());
// Make sure to materialize objects before causing any allocation.
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
RUNTIME_ASSERT(frame->function()->IsJSFunction());
- ASSERT(frame->function() == *function);
+ DCHECK(frame->function() == *function);
// Avoid doing too much work when running with --always-opt and keep
// the optimized code around.
RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
if (!function->IsOptimized()) return isolate->heap()->undefined_value();
+ // TODO(turbofan): Deoptimization is not supported yet.
+ if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
+ return isolate->heap()->undefined_value();
+ }
+
Deoptimizer::DeoptimizeFunction(*function);
return isolate->heap()->undefined_value();
RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
function->shared()->ClearTypeFeedbackInfo();
Code* unoptimized = function->shared()->code();
RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
#if defined(USE_SIMULATOR)
return isolate->heap()->true_value();
#else
RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
return isolate->heap()->ToBoolean(
isolate->concurrent_recompilation_enabled());
}
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+ // The following two assertions are lifted from the DCHECKs inside
+ // JSFunction::MarkForOptimization().
+ RUNTIME_ASSERT(!function->shared()->is_generator());
+ RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
+ (function->code()->kind() == Code::FUNCTION &&
+ function->code()->optimizable()));
- if (!function->IsOptimizable() &&
- !function->IsMarkedForConcurrentOptimization() &&
- !function->IsInOptimizationQueue()) {
- return isolate->heap()->undefined_value();
- }
+ // If the function is optimized, just return.
+ if (function->IsOptimized()) return isolate->heap()->undefined_value();
function->MarkForOptimization();
if (args.length() == 2 &&
unoptimized->kind() == Code::FUNCTION) {
CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
- if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
+ if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
// Start patching from the currently patched loop nesting level.
- int current_level = unoptimized->allow_osr_at_loop_nesting_level();
- ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
- if (FLAG_use_osr) {
- for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
- unoptimized->set_allow_osr_at_loop_nesting_level(i);
- isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
- }
- }
- } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent")) &&
+ DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
+ isolate->runtime_profiler()->AttemptOnStackReplacement(
+ *function, Code::kMaxLoopNestingMarker);
+ } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
isolate->concurrent_recompilation_enabled()) {
function->MarkForConcurrentOptimization();
}
RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, function, 0);
function->shared()->set_optimization_disabled(true);
return isolate->heap()->undefined_value();
bool sync_with_compiler_thread = true;
if (args.length() == 2) {
CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
- if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
+ if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
sync_with_compiler_thread = false;
}
}
sync_with_compiler_thread) {
while (function->IsInOptimizationQueue()) {
isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
- OS::Sleep(50);
+ base::OS::Sleep(50);
}
}
if (FLAG_always_opt) {
if (FLAG_deopt_every_n_times) {
return Smi::FromInt(6); // 6 == "maybe deopted".
}
+ if (function->IsOptimized() && function->code()->is_turbofanned()) {
+ return Smi::FromInt(7); // 7 == "TurboFan compiler".
+ }
return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes".
: Smi::FromInt(2); // 2 == "no".
}
RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
isolate->optimizing_compiler_thread()->Unblock();
RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return Smi::FromInt(function->shared()->opt_count());
}
RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
Handle<Code> caller_code(function->shared()->code());
// We're not prepared to handle a function with arguments object.
- ASSERT(!function->shared()->uses_arguments());
+ DCHECK(!function->shared()->uses_arguments());
RUNTIME_ASSERT(FLAG_use_osr);
frame->pc() - caller_code->instruction_start());
#ifdef DEBUG
- ASSERT_EQ(frame->function(), *function);
- ASSERT_EQ(frame->LookupCode(), *caller_code);
- ASSERT(caller_code->contains(frame->pc()));
+ DCHECK_EQ(frame->function(), *function);
+ DCHECK_EQ(frame->LookupCode(), *caller_code);
+ DCHECK(caller_code->contains(frame->pc()));
#endif // DEBUG
BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
- ASSERT(!ast_id.IsNone());
+ DCHECK(!ast_id.IsNone());
Compiler::ConcurrencyMode mode =
isolate->concurrent_osr_enabled() &&
DeoptimizationInputData::cast(result->deoptimization_data());
if (data->OsrPcOffset()->value() >= 0) {
- ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
+ DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
if (FLAG_trace_osr) {
PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
ast_id.ToInt(), data->OsrPcOffset()->value());
RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2 || args.length() == 3);
+ DCHECK(args.length() == 2 || args.length() == 3);
#ifdef DEBUG
CONVERT_SMI_ARG_CHECKED(interval, 0);
CONVERT_SMI_ARG_CHECKED(timeout, 1);
RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_GetRootNaN) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
return isolate->heap()->nan_value();
}
RUNTIME_FUNCTION(Runtime_Call) {
HandleScope scope(isolate);
- ASSERT(args.length() >= 2);
+ DCHECK(args.length() >= 2);
int argc = args.length() - 2;
CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
Object* receiver = args[0];
RUNTIME_FUNCTION(Runtime_Apply) {
HandleScope scope(isolate);
- ASSERT(args.length() == 5);
+ DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
- CONVERT_SMI_ARG_CHECKED(offset, 3);
- CONVERT_SMI_ARG_CHECKED(argc, 4);
+ CONVERT_INT32_ARG_CHECKED(offset, 3);
+ CONVERT_INT32_ARG_CHECKED(argc, 4);
RUNTIME_ASSERT(offset >= 0);
// Loose upper bound to allow fuzzing. We'll most likely run out of
// stack space before hitting this limit.
RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
RUNTIME_ASSERT(!object->IsJSFunction());
return *Execution::GetFunctionDelegate(isolate, object);
RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
RUNTIME_ASSERT(!object->IsJSFunction());
return *Execution::GetConstructorDelegate(isolate, object);
}
-RUNTIME_FUNCTION(RuntimeHidden_NewGlobalContext) {
+RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
Handle<Context> result =
isolate->factory()->NewGlobalContext(function, scope_info);
- ASSERT(function->context() == isolate->context());
- ASSERT(function->context()->global_object() == result->global_object());
+ DCHECK(function->context() == isolate->context());
+ DCHECK(function->context()->global_object() == result->global_object());
result->global_object()->set_global_context(*result);
return *result;
}
-RUNTIME_FUNCTION(RuntimeHidden_NewFunctionContext) {
+RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+ DCHECK(function->context() == isolate->context());
int length = function->shared()->scope_info()->ContextLength();
return *isolate->factory()->NewFunctionContext(length, function);
}
-RUNTIME_FUNCTION(RuntimeHidden_PushWithContext) {
+RUNTIME_FUNCTION(Runtime_PushWithContext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
Handle<JSReceiver> extension_object;
if (args[0]->IsJSReceiver()) {
extension_object = args.at<JSReceiver>(0);
Object::ToObject(isolate, args.at<Object>(0));
if (!maybe_object.ToHandle(&extension_object)) {
Handle<Object> handle = args.at<Object>(0);
- Handle<Object> result =
- isolate->factory()->NewTypeError("with_expression",
- HandleVector(&handle, 1));
- return isolate->Throw(*result);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError("with_expression", HandleVector(&handle, 1)));
}
}
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
// gotten from the native context.
- function = handle(isolate->context()->native_context()->closure());
+ function = handle(isolate->native_context()->closure());
} else {
function = args.at<JSFunction>(1);
}
}
-RUNTIME_FUNCTION(RuntimeHidden_PushCatchContext) {
+RUNTIME_FUNCTION(Runtime_PushCatchContext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
Handle<JSFunction> function;
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
// gotten from the native context.
- function = handle(isolate->context()->native_context()->closure());
+ function = handle(isolate->native_context()->closure());
} else {
function = args.at<JSFunction>(2);
}
}
-RUNTIME_FUNCTION(RuntimeHidden_PushBlockContext) {
+RUNTIME_FUNCTION(Runtime_PushBlockContext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
Handle<JSFunction> function;
if (args[1]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
// gotten from the native context.
- function = handle(isolate->context()->native_context()->closure());
+ function = handle(isolate->native_context()->closure());
} else {
function = args.at<JSFunction>(1);
}
RUNTIME_FUNCTION(Runtime_IsJSModule) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSModule());
}
-RUNTIME_FUNCTION(RuntimeHidden_PushModuleContext) {
+RUNTIME_FUNCTION(Runtime_PushModuleContext) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(index, 0);
if (!args[1]->IsScopeInfo()) {
// Module already initialized. Find hosting context and retrieve context.
Context* host = Context::cast(isolate->context())->global_context();
Context* context = Context::cast(host->get(index));
- ASSERT(context->previous() == isolate->context());
+ DCHECK(context->previous() == isolate->context());
isolate->set_context(context);
return context;
}
}
-RUNTIME_FUNCTION(RuntimeHidden_DeclareModules) {
+RUNTIME_FUNCTION(Runtime_DeclareModules) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
Context* host_context = isolate->context();
Accessors::MakeModuleExport(name, index, attr);
Handle<Object> result =
JSObject::SetAccessor(module, info).ToHandleChecked();
- ASSERT(!result->IsUndefined());
+ DCHECK(!result->IsUndefined());
USE(result);
break;
}
case MODULE: {
Object* referenced_context = Context::cast(host_context)->get(index);
Handle<JSModule> value(Context::cast(referenced_context)->module());
- JSReceiver::SetProperty(module, name, value, FROZEN, STRICT).Assert();
+ JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
+ .Assert();
break;
}
case INTERNAL:
JSObject::PreventExtensions(module).Assert();
}
- ASSERT(!isolate->has_pending_exception());
+ DCHECK(!isolate->has_pending_exception());
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(RuntimeHidden_DeleteContextSlot) {
+RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
// In Win64 they are assigned to a hidden first argument.
return result;
}
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+// For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
+// are used in the full codegen and Crankshaft compiler. An alternative is
+// using uint64_t and modifying full codegen and Crankshaft compiler.
+struct ObjectPair {
+ Object* x;
+ uint32_t x_upper;
+ Object* y;
+ uint32_t y_upper;
+};
+
+
+static inline ObjectPair MakePair(Object* x, Object* y) {
+ ObjectPair result = {x, 0, y, 0};
+ // Pointers x and y returned in rax and rdx, in x32-abi.
+ return result;
+}
#else
typedef uint64_t ObjectPair;
static inline ObjectPair MakePair(Object* x, Object* y) {
static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
JSObject* holder) {
- ASSERT(!holder->IsGlobalObject());
+ DCHECK(!holder->IsGlobalObject());
Context* top = isolate->context();
// Get the context extension function.
JSFunction* context_extension_function =
}
-static ObjectPair LoadContextSlotHelper(Arguments args,
- Isolate* isolate,
- bool throw_error) {
+static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
+ bool throw_error) {
HandleScope scope(isolate);
- ASSERT_EQ(2, args.length());
+ DCHECK_EQ(2, args.length());
if (!args[0]->IsContext() || !args[1]->IsString()) {
return MakePair(isolate->ThrowIllegalOperation(), NULL);
// If the index is non-negative, the slot has been found in a context.
if (index >= 0) {
- ASSERT(holder->IsContext());
+ DCHECK(holder->IsContext());
// If the "property" we were looking for is a local variable, the
// receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
Handle<Object> receiver = isolate->factory()->undefined_value();
case MUTABLE_CHECK_INITIALIZED:
case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
if (value->IsTheHole()) {
- Handle<Object> reference_error =
+ Handle<Object> error;
+ MaybeHandle<Object> maybe_error =
isolate->factory()->NewReferenceError("not_defined",
HandleVector(&name, 1));
- return MakePair(isolate->Throw(*reference_error), NULL);
+ if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
+ return MakePair(isolate->heap()->exception(), NULL);
}
// FALLTHROUGH
case MUTABLE_IS_INITIALIZED:
case IMMUTABLE_IS_INITIALIZED:
case IMMUTABLE_IS_INITIALIZED_HARMONY:
- ASSERT(!value->IsTheHole());
+ DCHECK(!value->IsTheHole());
return MakePair(value, *receiver);
case IMMUTABLE_CHECK_INITIALIZED:
if (value->IsTheHole()) {
- ASSERT((attributes & READ_ONLY) != 0);
+ DCHECK((attributes & READ_ONLY) != 0);
value = isolate->heap()->undefined_value();
}
return MakePair(value, *receiver);
// property from it.
if (!holder.is_null()) {
Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
- ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
+#ifdef DEBUG
+ if (!object->IsJSProxy()) {
+ Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
+ DCHECK(maybe.has_value);
+ DCHECK(maybe.value);
+ }
+#endif
// GetProperty below can cause GC.
Handle<Object> receiver_handle(
object->IsGlobalObject()
if (throw_error) {
// The property doesn't exist - throw exception.
- Handle<Object> reference_error =
- isolate->factory()->NewReferenceError("not_defined",
- HandleVector(&name, 1));
- return MakePair(isolate->Throw(*reference_error), NULL);
+ Handle<Object> error;
+ MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError(
+ "not_defined", HandleVector(&name, 1));
+ if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
+ return MakePair(isolate->heap()->exception(), NULL);
} else {
// The property doesn't exist - return undefined.
return MakePair(isolate->heap()->undefined_value(),
}
-RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlot) {
- return LoadContextSlotHelper(args, isolate, true);
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) {
+ return LoadLookupSlotHelper(args, isolate, true);
}
-RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlotNoReferenceError) {
- return LoadContextSlotHelper(args, isolate, false);
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) {
+ return LoadLookupSlotHelper(args, isolate, false);
}
-RUNTIME_FUNCTION(RuntimeHidden_StoreContextSlot) {
+RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
&index,
&attributes,
&binding_flags);
+ // In case of JSProxy, an exception might have been thrown.
if (isolate->has_pending_exception()) return isolate->heap()->exception();
+ // The property was found in a context slot.
if (index >= 0) {
- // The property was found in a context slot.
- Handle<Context> context = Handle<Context>::cast(holder);
- if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
- context->get(index)->IsTheHole()) {
- Handle<Object> error =
- isolate->factory()->NewReferenceError("not_defined",
- HandleVector(&name, 1));
- return isolate->Throw(*error);
- }
- // Ignore if read_only variable.
if ((attributes & READ_ONLY) == 0) {
- // Context is a fixed array and set cannot fail.
- context->set(index, *value);
+ Handle<Context>::cast(holder)->set(index, *value);
} else if (strict_mode == STRICT) {
// Setting read only property in strict mode.
- Handle<Object> error =
- isolate->factory()->NewTypeError("strict_cannot_assign",
- HandleVector(&name, 1));
- return isolate->Throw(*error);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewTypeError("strict_cannot_assign", HandleVector(&name, 1)));
}
return *value;
}
// context extension object, a property of the subject of a with, or a
// property of the global object.
Handle<JSReceiver> object;
-
- if (!holder.is_null()) {
+ if (attributes != ABSENT) {
// The property exists on the holder.
object = Handle<JSReceiver>::cast(holder);
+ } else if (strict_mode == STRICT) {
+ // If absent in strict mode: throw.
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
} else {
- // The property was not found.
- ASSERT(attributes == ABSENT);
-
- if (strict_mode == STRICT) {
- // Throw in strict mode (assignment to undefined variable).
- Handle<Object> error =
- isolate->factory()->NewReferenceError(
- "not_defined", HandleVector(&name, 1));
- return isolate->Throw(*error);
- }
- // In sloppy mode, the property is added to the global object.
- attributes = NONE;
- object = Handle<JSReceiver>(isolate->context()->global_object());
+ // If absent in sloppy mode: add the property to the global object.
+ object = Handle<JSReceiver>(context->global_object());
}
- // Set the property if it's not read only or doesn't yet exist.
- if ((attributes & READ_ONLY) == 0 ||
- (JSReceiver::GetOwnPropertyAttributes(object, name) == ABSENT)) {
- RETURN_FAILURE_ON_EXCEPTION(
- isolate,
- JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
- } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
- // Setting read only property in strict mode.
- Handle<Object> error =
- isolate->factory()->NewTypeError(
- "strict_cannot_assign", HandleVector(&name, 1));
- return isolate->Throw(*error);
- }
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, Object::SetProperty(object, name, value, strict_mode));
+
return *value;
}
-RUNTIME_FUNCTION(RuntimeHidden_Throw) {
+RUNTIME_FUNCTION(Runtime_Throw) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
return isolate->Throw(args[0]);
}
-RUNTIME_FUNCTION(RuntimeHidden_ReThrow) {
+RUNTIME_FUNCTION(Runtime_ReThrow) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
return isolate->ReThrow(args[0]);
}
-RUNTIME_FUNCTION(RuntimeHidden_PromoteScheduledException) {
+RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
return isolate->PromoteScheduledException();
}
-RUNTIME_FUNCTION(RuntimeHidden_ThrowReferenceError) {
+RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
- Handle<Object> reference_error =
- isolate->factory()->NewReferenceError("not_defined",
- HandleVector(&name, 1));
- return isolate->Throw(*reference_error);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewReferenceError("non_method", HandleVector<Object>(NULL, 0)));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 0);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
}
-RUNTIME_FUNCTION(RuntimeHidden_ThrowNotDateError) {
+RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
- return isolate->Throw(*isolate->factory()->NewTypeError(
- "not_date_object", HandleVector<Object>(NULL, 0)));
+ DCHECK(args.length() == 0);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
}
-RUNTIME_FUNCTION(RuntimeHidden_StackGuard) {
+RUNTIME_FUNCTION(Runtime_StackGuard) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
// First check if this is a real stack overflow.
StackLimitCheck check(isolate);
}
-RUNTIME_FUNCTION(RuntimeHidden_TryInstallOptimizedCode) {
+RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
// First check if this is a real stack overflow.
}
-RUNTIME_FUNCTION(RuntimeHidden_Interrupt) {
+RUNTIME_FUNCTION(Runtime_Interrupt) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
return isolate->stack_guard()->HandleInterrupts();
}
RUNTIME_FUNCTION(Runtime_TraceEnter) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
PrintTransition(isolate, NULL);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_TraceExit) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, obj, 0);
PrintTransition(isolate, obj);
return obj; // return TOS
RUNTIME_FUNCTION(Runtime_DebugPrint) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
+ OFStream os(stdout);
#ifdef DEBUG
if (args[0]->IsString()) {
// If we have a string, assume it's a code "marker"
// and print some interesting cpu debugging info.
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
- PrintF("fp = %p, sp = %p, caller_sp = %p: ",
- frame->fp(), frame->sp(), frame->caller_sp());
+ os << "fp = " << frame->fp() << ", sp = " << frame->sp()
+ << ", caller_sp = " << frame->caller_sp() << ": ";
} else {
- PrintF("DebugPrint: ");
+ os << "DebugPrint: ";
}
- args[0]->Print();
+ args[0]->Print(os);
if (args[0]->IsHeapObject()) {
- PrintF("\n");
- HeapObject::cast(args[0])->map()->Print();
+ os << "\n";
+ HeapObject::cast(args[0])->map()->Print(os);
}
#else
// ShortPrint is available in release mode. Print is not.
- args[0]->ShortPrint();
+ os << Brief(args[0]);
#endif
- PrintF("\n");
- Flush();
+ os << endl;
return args[0]; // return TOS
}
RUNTIME_FUNCTION(Runtime_DebugTrace) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
isolate->PrintStack(stdout);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
// According to ECMA-262, section 15.9.1, page 117, the precision of
// the number in a Date object representing a particular instant in
// time is milliseconds. Therefore, we floor the result of getting
// the OS time.
- double millis = std::floor(OS::TimeCurrentMillis());
+ double millis;
+ if (FLAG_verify_predictable) {
+ millis = 1388534400000.0; // Jan 1 2014 00:00:00 GMT+0000
+ millis += Floor(isolate->heap()->synthetic_time());
+ } else {
+ millis = Floor(base::OS::TimeCurrentMillis());
+ }
return *isolate->factory()->NewNumber(millis);
}
RUNTIME_FUNCTION(Runtime_DateParseString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
bool result;
String::FlatContent str_content = str->GetFlatContent();
- if (str_content.IsAscii()) {
+ if (str_content.IsOneByte()) {
result = DateParser::Parse(str_content.ToOneByteVector(),
*output_array,
isolate->unicode_cache());
} else {
- ASSERT(str_content.IsTwoByte());
+ DCHECK(str_content.IsTwoByte());
result = DateParser::Parse(str_content.ToUC16Vector(),
*output_array,
isolate->unicode_cache());
RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
RUNTIME_FUNCTION(Runtime_DateToUTC) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
HandleScope hs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
Handle<FixedArray> date_cache_version =
isolate->factory()->NewFixedArray(1, TENURED);
}
-RUNTIME_FUNCTION(Runtime_GlobalReceiver) {
+RUNTIME_FUNCTION(Runtime_GlobalProxy) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, global, 0);
if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
- return JSGlobalObject::cast(global)->global_receiver();
+ return JSGlobalObject::cast(global)->global_proxy();
}
RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, global, 0);
if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
return isolate->heap()->ToBoolean(
RUNTIME_FUNCTION(Runtime_ParseJson) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
source = String::Flatten(source);
- // Optimized fast case where we only have ASCII characters.
+ // Optimized fast case where we only have Latin1 characters.
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
bool CodeGenerationFromStringsAllowed(Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->allow_code_gen_from_strings()->IsFalse());
+ DCHECK(context->allow_code_gen_from_strings()->IsFalse());
// Check with callback if set.
AllowCodeGenerationFromStringsCallback callback =
isolate->allow_code_gen_callback();
}
-// Walk up the stack expecting:
-// - Runtime_CompileString
-// - JSFunction callee (eval, Function constructor, etc)
-// - call() (maybe)
-// - apply() (maybe)
-// - bind() (maybe)
-// - JSFunction caller (maybe)
-//
-// return true if the caller has the same security token as the callee
-// or if an exit frame was hit, in which case allow it through, as it could
-// have come through the api.
-static bool TokensMatchForCompileString(Isolate* isolate) {
- MaybeHandle<JSFunction> callee;
- bool exit_handled = true;
- bool tokens_match = true;
- bool done = false;
- for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
- StackFrame* raw_frame = it.frame();
- if (!raw_frame->is_java_script()) {
- if (raw_frame->is_exit()) exit_handled = false;
- continue;
- }
- JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
- List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
- outer_frame->Summarize(&frames);
- for (int i = frames.length() - 1; i >= 0 && !done; --i) {
- FrameSummary& frame = frames[i];
- Handle<JSFunction> fun = frame.function();
- // Capture the callee function.
- if (callee.is_null()) {
- callee = fun;
- exit_handled = true;
- continue;
- }
- // Exit condition.
- Handle<Context> context(callee.ToHandleChecked()->context());
- if (!fun->context()->HasSameSecurityTokenAs(*context)) {
- tokens_match = false;
- done = true;
- continue;
- }
- // Skip bound functions in correct origin.
- if (fun->shared()->bound()) {
- exit_handled = true;
- continue;
- }
- done = true;
- }
- }
- return !exit_handled || tokens_match;
-}
-
-
RUNTIME_FUNCTION(Runtime_CompileString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
// Extract native context.
- Handle<Context> context(isolate->context()->native_context());
-
- // Filter cross security context calls.
- if (!TokensMatchForCompileString(isolate)) {
- return isolate->heap()->undefined_value();
- }
+ Handle<Context> context(isolate->native_context());
// Check if native context allows code generation from
// strings. Throw an exception if it doesn't.
!CodeGenerationFromStringsAllowed(isolate, context)) {
Handle<Object> error_message =
context->ErrorMessageForCodeGenerationFromStrings();
- return isolate->Throw(*isolate->factory()->NewEvalError(
- "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewEvalError("code_gen_from_strings",
+ HandleVector<Object>(&error_message, 1)));
}
// Compile source string in the native context.
ParseRestriction restriction = function_literal_only
? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
+ Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
Handle<JSFunction> fun;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, fun,
Compiler::GetFunctionFromEval(
- source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
+ source, outer_info,
+ context, SLOPPY, restriction, RelocInfo::kNoPosition));
return *fun;
}
static ObjectPair CompileGlobalEval(Isolate* isolate,
Handle<String> source,
+ Handle<SharedFunctionInfo> outer_info,
Handle<Object> receiver,
StrictMode strict_mode,
int scope_position) {
!CodeGenerationFromStringsAllowed(isolate, native_context)) {
Handle<Object> error_message =
native_context->ErrorMessageForCodeGenerationFromStrings();
- isolate->Throw(*isolate->factory()->NewEvalError(
- "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
+ Handle<Object> error;
+ MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
+ "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
+ if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
return MakePair(isolate->heap()->exception(), NULL);
}
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, compiled,
Compiler::GetFunctionFromEval(
- source, context, strict_mode, restriction, scope_position),
+ source, outer_info,
+ context, strict_mode, restriction, scope_position),
MakePair(isolate->heap()->exception(), NULL));
return MakePair(*compiled, *receiver);
}
-RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_ResolvePossiblyDirectEval) {
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
HandleScope scope(isolate);
- ASSERT(args.length() == 5);
+ DCHECK(args.length() == 6);
Handle<Object> callee = args.at<Object>(0);
return MakePair(*callee, isolate->heap()->undefined_value());
}
- ASSERT(args[3]->IsSmi());
- ASSERT(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
- StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
- ASSERT(args[4]->IsSmi());
+ DCHECK(args[4]->IsSmi());
+ DCHECK(args.smi_at(4) == SLOPPY || args.smi_at(4) == STRICT);
+ StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(4));
+ DCHECK(args[5]->IsSmi());
+ Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
+ isolate);
return CompileGlobalEval(isolate,
args.at<String>(1),
- args.at<Object>(2),
+ outer_info,
+ args.at<Object>(3),
strict_mode,
- args.smi_at(4));
+ args.smi_at(5));
}
-RUNTIME_FUNCTION(RuntimeHidden_AllocateInNewSpace) {
+RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_SMI_ARG_CHECKED(size, 0);
RUNTIME_ASSERT(IsAligned(size, kPointerSize));
RUNTIME_ASSERT(size > 0);
}
-RUNTIME_FUNCTION(RuntimeHidden_AllocateInTargetSpace) {
+RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(size, 0);
CONVERT_SMI_ARG_CHECKED(flags, 1);
RUNTIME_ASSERT(IsAligned(size, kPointerSize));
// false otherwise.
RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
SetDictionaryMode();
// Fall-through to dictionary mode.
}
- ASSERT(!fast_elements_);
+ DCHECK(!fast_elements_);
Handle<SeededNumberDictionary> dict(
SeededNumberDictionary::cast(*storage_));
Handle<SeededNumberDictionary> result =
// but the array blowing the limit didn't contain elements beyond the
// provided-for index range, go to dictionary mode now.
if (fast_elements_ &&
- index_offset_ >= static_cast<uint32_t>(
- FixedArrayBase::cast(*storage_)->length())) {
+ index_offset_ >
+ static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
SetDictionaryMode();
}
}
private:
// Convert storage to dictionary mode.
void SetDictionaryMode() {
- ASSERT(fast_elements_);
+ DCHECK(fast_elements_);
Handle<FixedArray> current_storage(*storage_);
Handle<SeededNumberDictionary> slow_storage(
SeededNumberDictionary::New(isolate_, current_storage->length()));
case FAST_HOLEY_ELEMENTS: {
// Fast elements can't have lengths that are not representable by
// a 32-bit signed integer.
- ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
+ DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
int fast_length = static_cast<int>(length);
Handle<FixedArray> elements(FixedArray::cast(array->elements()));
for (int i = 0; i < fast_length; i++) {
case FAST_HOLEY_DOUBLE_ELEMENTS: {
// Fast elements can't have lengths that are not representable by
// a 32-bit signed integer.
- ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
+ DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
int fast_length = static_cast<int>(length);
if (array->elements()->IsFixedArray()) {
- ASSERT(FixedArray::cast(array->elements())->length() == 0);
+ DCHECK(FixedArray::cast(array->elements())->length() == 0);
break;
}
Handle<FixedDoubleArray> elements(
ExternalArrayClass::cast(receiver->elements()));
uint32_t len = static_cast<uint32_t>(array->length());
- ASSERT(visitor != NULL);
+ DCHECK(visitor != NULL);
if (elements_are_ints) {
if (elements_are_guaranteed_smis) {
for (uint32_t j = 0; j < len; j++) {
}
+static void IterateExternalFloat32x4ArrayElements(Isolate* isolate,
+ Handle<JSObject> receiver,
+ ArrayConcatVisitor* visitor) {
+ Handle<ExternalFloat32x4Array> array(
+ ExternalFloat32x4Array::cast(receiver->elements()));
+ uint32_t len = static_cast<uint32_t>(array->length());
+
+ DCHECK(visitor != NULL);
+ for (uint32_t j = 0; j < len; j++) {
+ HandleScope loop_scope(isolate);
+ Handle<Object> e = isolate->factory()->NewFloat32x4(array->get_scalar(j));
+ visitor->visit(j, e);
+ }
+}
+
+
+static void IterateExternalFloat64x2ArrayElements(Isolate* isolate,
+ Handle<JSObject> receiver,
+ ArrayConcatVisitor* visitor) {
+ Handle<ExternalFloat64x2Array> array(
+ ExternalFloat64x2Array::cast(receiver->elements()));
+ uint32_t len = static_cast<uint32_t>(array->length());
+
+ DCHECK(visitor != NULL);
+ for (uint32_t j = 0; j < len; j++) {
+ HandleScope loop_scope(isolate);
+ Handle<Object> e = isolate->factory()->NewFloat64x2(array->get_scalar(j));
+ visitor->visit(j, e);
+ }
+}
+
+
+static void IterateExternalInt32x4ArrayElements(Isolate* isolate,
+ Handle<JSObject> receiver,
+ ArrayConcatVisitor* visitor) {
+ Handle<ExternalInt32x4Array> array(
+ ExternalInt32x4Array::cast(receiver->elements()));
+ uint32_t len = static_cast<uint32_t>(array->length());
+
+ DCHECK(visitor != NULL);
+ for (uint32_t j = 0; j < len; j++) {
+ HandleScope loop_scope(isolate);
+ Handle<Object> e = isolate->factory()->NewInt32x4(array->get_scalar(j));
+ visitor->visit(j, e);
+ }
+}
+
+
// Used for sorting indices in a List<uint32_t>.
static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
uint32_t a = *ap;
}
case FAST_HOLEY_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS: {
- // TODO(1810): Decide if it's worthwhile to implement this.
- UNREACHABLE();
+ if (object->elements()->IsFixedArray()) {
+ DCHECK(object->elements()->length() == 0);
+ break;
+ }
+ Handle<FixedDoubleArray> elements(
+ FixedDoubleArray::cast(object->elements()));
+ uint32_t length = static_cast<uint32_t>(elements->length());
+ if (range < length) length = range;
+ for (uint32_t i = 0; i < length; i++) {
+ if (!elements->is_the_hole(i)) {
+ indices->Add(i);
+ }
+ }
break;
}
case DICTIONARY_ELEMENTS: {
HandleScope loop_scope(isolate);
Handle<Object> k(dict->KeyAt(j), isolate);
if (dict->IsKey(*k)) {
- ASSERT(k->IsNumber());
+ DCHECK(k->IsNumber());
uint32_t index = static_cast<uint32_t>(k->Number());
if (index < range) {
indices->Add(index);
}
break;
}
- default: {
- int dense_elements_length;
- switch (kind) {
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
- case EXTERNAL_##TYPE##_ELEMENTS: { \
- dense_elements_length = \
- External##Type##Array::cast(object->elements())->length(); \
- break; \
- }
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ case EXTERNAL_##TYPE##_ELEMENTS:
- TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
-
- default:
- UNREACHABLE();
- dense_elements_length = 0;
- break;
- }
- uint32_t length = static_cast<uint32_t>(dense_elements_length);
+ {
+ uint32_t length = static_cast<uint32_t>(
+ FixedArrayBase::cast(object->elements())->length());
if (range <= length) {
length = range;
// We will add all indices, so we might as well clear it first
if (length == range) return; // All indices accounted for already.
break;
}
+ case SLOPPY_ARGUMENTS_ELEMENTS: {
+ MaybeHandle<Object> length_obj =
+ Object::GetProperty(object, isolate->factory()->length_string());
+ double length_num = length_obj.ToHandleChecked()->Number();
+ uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num));
+ ElementsAccessor* accessor = object->GetElementsAccessor();
+ for (uint32_t i = 0; i < length; i++) {
+ if (accessor->HasElement(object, object, i)) {
+ indices->Add(i);
+ }
+ }
+ break;
+ }
}
- Handle<Object> prototype(object->GetPrototype(), isolate);
- if (prototype->IsJSObject()) {
+ PrototypeIterator iter(isolate, object);
+ if (!iter.IsAtEnd()) {
// The prototype will usually have no inherited element indices,
// but we have to check.
- CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
+ CollectElementIndices(
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
+ indices);
}
}
// to check the prototype for missing elements.
Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
int fast_length = static_cast<int>(length);
- ASSERT(fast_length <= elements->length());
+ DCHECK(fast_length <= elements->length());
for (int j = 0; j < fast_length; j++) {
HandleScope loop_scope(isolate);
Handle<Object> element_value(elements->get(j), isolate);
if (!element_value->IsTheHole()) {
visitor->visit(j, element_value);
- } else if (JSReceiver::HasElement(receiver, j)) {
- // Call GetElement on receiver, not its prototype, or getters won't
- // have the correct receiver.
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, element_value,
- Object::GetElement(isolate, receiver, j),
- false);
- visitor->visit(j, element_value);
+ } else {
+ Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
+ if (!maybe.has_value) return false;
+ if (maybe.value) {
+ // Call GetElement on receiver, not its prototype, or getters won't
+ // have the correct receiver.
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, element_value,
+ Object::GetElement(isolate, receiver, j), false);
+ visitor->visit(j, element_value);
+ }
}
}
break;
// Run through the elements FixedArray and use HasElement and GetElement
// to check the prototype for missing elements.
if (receiver->elements()->IsFixedArray()) {
- ASSERT(receiver->elements()->length() == 0);
+ DCHECK(receiver->elements()->length() == 0);
break;
}
Handle<FixedDoubleArray> elements(
FixedDoubleArray::cast(receiver->elements()));
int fast_length = static_cast<int>(length);
- ASSERT(fast_length <= elements->length());
+ DCHECK(fast_length <= elements->length());
for (int j = 0; j < fast_length; j++) {
HandleScope loop_scope(isolate);
if (!elements->is_the_hole(j)) {
Handle<Object> element_value =
isolate->factory()->NewNumber(double_value);
visitor->visit(j, element_value);
- } else if (JSReceiver::HasElement(receiver, j)) {
- // Call GetElement on receiver, not its prototype, or getters won't
- // have the correct receiver.
- Handle<Object> element_value;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, element_value,
- Object::GetElement(isolate, receiver, j),
- false);
- visitor->visit(j, element_value);
+ } else {
+ Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
+ if (!maybe.has_value) return false;
+ if (maybe.value) {
+ // Call GetElement on receiver, not its prototype, or getters won't
+ // have the correct receiver.
+ Handle<Object> element_value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, element_value,
+ Object::GetElement(isolate, receiver, j), false);
+ visitor->visit(j, element_value);
+ }
}
}
break;
isolate, receiver, false, false, visitor);
break;
}
+ case EXTERNAL_FLOAT32x4_ELEMENTS: {
+ IterateExternalFloat32x4ArrayElements(isolate, receiver, visitor);
+ break;
+ }
+ case EXTERNAL_FLOAT64x2_ELEMENTS: {
+ IterateExternalFloat64x2ArrayElements(isolate, receiver, visitor);
+ break;
+ }
+ case EXTERNAL_INT32x4_ELEMENTS: {
+ IterateExternalInt32x4ArrayElements(isolate, receiver, visitor);
+ break;
+ }
case EXTERNAL_FLOAT64_ELEMENTS: {
IterateExternalArrayElements<ExternalFloat64Array, double>(
isolate, receiver, false, false, visitor);
*/
RUNTIME_FUNCTION(Runtime_ArrayConcat) {
HandleScope handle_scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
int argument_count = static_cast<int>(arguments->length()->Number());
Handle<FixedArrayBase> storage =
isolate->factory()->NewFixedDoubleArray(estimate_result_length);
int j = 0;
+ bool failure = false;
if (estimate_result_length > 0) {
Handle<FixedDoubleArray> double_storage =
Handle<FixedDoubleArray>::cast(storage);
- bool failure = false;
for (int i = 0; i < argument_count; i++) {
Handle<Object> obj(elements->get(i), isolate);
if (obj->IsSmi()) {
FixedDoubleArray::cast(array->elements());
for (uint32_t i = 0; i < length; i++) {
if (elements->is_the_hole(i)) {
+ // TODO(jkummerow/verwaest): We could be a bit more clever
+ // here: Check if there are no elements/getters on the
+ // prototype chain, and if so, allow creation of a holey
+ // result array.
+ // Same thing below (holey smi case).
failure = true;
break;
}
break;
}
case FAST_HOLEY_ELEMENTS:
- ASSERT_EQ(0, length);
+ case FAST_ELEMENTS:
+ DCHECK_EQ(0, length);
break;
default:
UNREACHABLE();
if (failure) break;
}
}
- Handle<JSArray> array = isolate->factory()->NewJSArray(0);
- Smi* length = Smi::FromInt(j);
- Handle<Map> map;
- map = JSObject::GetElementsTransitionMap(array, kind);
- array->set_map(*map);
- array->set_length(length);
- array->set_elements(*storage);
- return *array;
+ if (!failure) {
+ Handle<JSArray> array = isolate->factory()->NewJSArray(0);
+ Smi* length = Smi::FromInt(j);
+ Handle<Map> map;
+ map = JSObject::GetElementsTransitionMap(array, kind);
+ array->set_map(*map);
+ array->set_length(length);
+ array->set_elements(*storage);
+ return *array;
+ }
+ // In case of failure, fall through.
}
Handle<FixedArray> storage;
}
if (visitor.exceeds_array_limit()) {
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_length",
- HandleVector<Object>(NULL, 0)));
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0)));
}
return *visitor.ToArray();
}
// very slowly for very deeply nested ConsStrings. For debugging use only.
RUNTIME_FUNCTION(Runtime_GlobalPrint) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(String, string, 0);
ConsStringIteratorOp op;
// Returns -1 if hole removal is not supported by this method.
RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
return *JSObject::PrepareElementsForSort(object, limit);
// Move contents of argument 0 (an array) to argument 1 (an array)
RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
JSObject::ValidateElements(from);
// How many elements does this object/array have?
RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+ Handle<FixedArrayBase> elements(array->elements(), isolate);
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSArray, object, 0);
- HeapObject* elements = object->elements();
if (elements->IsDictionary()) {
- int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
+ int result =
+ Handle<SeededNumberDictionary>::cast(elements)->NumberOfElements();
return Smi::FromInt(result);
} else {
- return object->length();
+ DCHECK(array->length()->IsSmi());
+ // For packed elements, we know the exact number of elements
+ int length = elements->length();
+ ElementsKind kind = array->GetElementsKind();
+ if (IsFastPackedElementsKind(kind)) {
+ return Smi::FromInt(length);
+ }
+ // For holey elements, take samples from the buffer checking for holes
+ // to generate the estimate.
+ const int kNumberOfHoleCheckSamples = 97;
+ int increment = (length < kNumberOfHoleCheckSamples)
+ ? 1
+ : static_cast<int>(length / kNumberOfHoleCheckSamples);
+ ElementsAccessor* accessor = array->GetElementsAccessor();
+ int holes = 0;
+ for (int i = 0; i < length; i += increment) {
+ if (!accessor->HasElement(array, array, i, elements)) {
+ ++holes;
+ }
+ }
+ int estimate = static_cast<int>((kNumberOfHoleCheckSamples - holes) /
+ kNumberOfHoleCheckSamples * length);
+ return Smi::FromInt(estimate);
}
}
// Intervals can span over some keys that are not in the object.
RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
if (array->elements()->IsDictionary()) {
Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
- for (Handle<Object> p = array;
- !p->IsNull();
- p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
- if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
+ for (PrototypeIterator iter(isolate, array,
+ PrototypeIterator::START_AT_RECEIVER);
+ !iter.IsAtEnd(); iter.Advance()) {
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
+ JSObject::cast(*PrototypeIterator::GetCurrent(iter))
+ ->HasIndexedInterceptor()) {
// Bail out if we find a proxy or interceptor, likely not worth
// collecting keys in that case.
return *isolate->factory()->NewNumberFromUint(length);
}
- Handle<JSObject> current = Handle<JSObject>::cast(p);
+ Handle<JSObject> current =
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
Handle<FixedArray> current_keys =
isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
current->GetOwnElementKeys(*current_keys, NONE);
RUNTIME_FUNCTION(Runtime_LookupAccessor) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_SMI_ARG_CHECKED(flag, 2);
RUNTIME_FUNCTION(Runtime_DebugBreak) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
isolate->debug()->HandleDebugBreak();
return isolate->heap()->undefined_value();
}
// Helper functions for wrapping and unwrapping stack frame ids.
static Smi* WrapFrameId(StackFrame::Id id) {
- ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
+ DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
return Smi::FromInt(id >> 2);
}
// args[1]: object supplied during callback
RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
RUNTIME_ASSERT(args[0]->IsJSFunction() ||
args[0]->IsUndefined() ||
args[0]->IsNull());
RUNTIME_FUNCTION(Runtime_Break) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
isolate->stack_guard()->RequestDebugBreak();
return isolate->heap()->undefined_value();
}
-static Handle<Object> DebugLookupResultValue(Isolate* isolate,
- Handle<Object> receiver,
- Handle<Name> name,
- LookupResult* result,
- bool* has_caught = NULL) {
- Handle<Object> value = isolate->factory()->undefined_value();
- if (!result->IsFound()) return value;
- switch (result->type()) {
- case NORMAL:
- value = JSObject::GetNormalizedProperty(
- handle(result->holder(), isolate), result);
- break;
- case FIELD:
- value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
- result->representation(),
- result->GetFieldIndex());
- break;
- case CONSTANT:
- return handle(result->GetConstant(), isolate);
- case CALLBACKS: {
- Handle<Object> structure(result->GetCallbackObject(), isolate);
- ASSERT(!structure->IsForeign());
- if (structure->IsAccessorInfo()) {
- MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor(
- receiver, name, handle(result->holder(), isolate), structure);
- if (!obj.ToHandle(&value)) {
- value = handle(isolate->pending_exception(), isolate);
- isolate->clear_pending_exception();
+static Handle<Object> DebugGetProperty(LookupIterator* it,
+ bool* has_caught = NULL) {
+ for (; it->IsFound(); it->Next()) {
+ switch (it->state()) {
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
+ UNREACHABLE();
+ case LookupIterator::ACCESS_CHECK:
+ // Ignore access checks.
+ break;
+ case LookupIterator::INTERCEPTOR:
+ case LookupIterator::JSPROXY:
+ return it->isolate()->factory()->undefined_value();
+ case LookupIterator::ACCESSOR: {
+ Handle<Object> accessors = it->GetAccessors();
+ if (!accessors->IsAccessorInfo()) {
+ return it->isolate()->factory()->undefined_value();
+ }
+ MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
+ it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
+ accessors);
+ Handle<Object> result;
+ if (!maybe_result.ToHandle(&result)) {
+ result = handle(it->isolate()->pending_exception(), it->isolate());
+ it->isolate()->clear_pending_exception();
if (has_caught != NULL) *has_caught = true;
- return value;
}
+ return result;
}
- break;
+
+ case LookupIterator::DATA:
+ return it->GetDataValue();
}
- case INTERCEPTOR:
- case HANDLER:
- break;
- case NONEXISTENT:
- UNREACHABLE();
- break;
}
- ASSERT(!value->IsTheHole() || result->IsReadOnly());
- return value->IsTheHole()
- ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value;
+
+ return it->isolate()->factory()->undefined_value();
}
-// Get debugger related details for an object property.
-// args[0]: object holding property
-// args[1]: name of the property
-//
-// The array returned contains the following information:
+// Get debugger related details for an object property, in the following format:
// 0: Property value
// 1: Property details
// 2: Property value is exception
// 3: Getter function if defined
// 4: Setter function if defined
-// Items 2-4 are only filled if the property has either a getter or a setter
-// defined through __defineGetter__ and/or __defineSetter__.
+// Items 2-4 are only filled if the property has either a getter or a setter.
RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
}
- // Skip the global proxy as it has no properties and always delegates to the
- // real global object.
- if (obj->IsJSGlobalProxy()) {
- obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
- }
-
-
// Check if the name is trivially convertible to an index and get the element
// if so.
uint32_t index;
return *isolate->factory()->NewJSArrayWithElements(details);
}
- // Find the number of objects making up this.
- int length = OwnPrototypeChainLength(*obj);
-
- // Try own lookup on each of the objects.
- Handle<JSObject> jsproto = obj;
- for (int i = 0; i < length; i++) {
- LookupResult result(isolate);
- jsproto->LookupOwn(name, &result);
- if (result.IsFound()) {
- // LookupResult is not GC safe as it holds raw object pointers.
- // GC can happen later in this code so put the required fields into
- // local variables using handles when required for later use.
- Handle<Object> result_callback_obj;
- if (result.IsPropertyCallbacks()) {
- result_callback_obj = Handle<Object>(result.GetCallbackObject(),
- isolate);
- }
-
+ LookupIterator it(obj, name, LookupIterator::HIDDEN);
+ bool has_caught = false;
+ Handle<Object> value = DebugGetProperty(&it, &has_caught);
+ if (!it.IsFound()) return isolate->heap()->undefined_value();
- bool has_caught = false;
- Handle<Object> value = DebugLookupResultValue(
- isolate, obj, name, &result, &has_caught);
-
- // If the callback object is a fixed array then it contains JavaScript
- // getter and/or setter.
- bool has_js_accessors = result.IsPropertyCallbacks() &&
- result_callback_obj->IsAccessorPair();
- Handle<FixedArray> details =
- isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
- details->set(0, *value);
- details->set(1, result.GetPropertyDetails().AsSmi());
- if (has_js_accessors) {
- AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
- details->set(2, isolate->heap()->ToBoolean(has_caught));
- details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
- details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
- }
+ Handle<Object> maybe_pair;
+ if (it.state() == LookupIterator::ACCESSOR) {
+ maybe_pair = it.GetAccessors();
+ }
- return *isolate->factory()->NewJSArrayWithElements(details);
- }
- if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
- }
+ // If the callback object is a fixed array then it contains JavaScript
+ // getter and/or setter.
+ bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
+ Handle<FixedArray> details =
+ isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
+ details->set(0, *value);
+ // TODO(verwaest): Get rid of this random way of handling interceptors.
+ PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
+ ? PropertyDetails(NONE, NORMAL, 0)
+ : it.property_details();
+ details->set(1, d.AsSmi());
+ details->set(
+ 2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
+ if (has_js_accessors) {
+ AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
+ details->set(3, isolate->heap()->ToBoolean(has_caught));
+ details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
+ details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
}
- return isolate->heap()->undefined_value();
+ return *isolate->factory()->NewJSArrayWithElements(details);
}
RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- LookupResult result(isolate);
- obj->Lookup(name, &result);
- return *DebugLookupResultValue(isolate, obj, name, &result);
+ LookupIterator it(obj, name);
+ return *DebugGetProperty(&it);
}
// args[0]: smi with property details.
RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
return Smi::FromInt(static_cast<int>(details.type()));
}
// args[0]: smi with property details.
RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
return Smi::FromInt(static_cast<int>(details.attributes()));
}
// args[0]: smi with property details.
RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
// TODO(verwaest): Depends on the type of details.
return Smi::FromInt(details.dictionary_index());
// args[1]: property name
RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
RUNTIME_ASSERT(obj->HasNamedInterceptor());
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
Handle<Object> result;
- LookupIterator it(obj, name, obj);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, JSObject::GetProperty(&it));
+ isolate, result, JSObject::GetProperty(obj, name));
return *result;
}
// args[1]: index
RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
return isolate->heap()->true_value();
RUNTIME_FUNCTION(Runtime_GetFrameCount) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
}
for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
- n += it.frame()->GetInlineCount();
+ List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+ it.frame()->Summarize(&frames);
+ for (int i = frames.length() - 1; i >= 0; i--) {
+ // Omit functions from native scripts.
+ if (!frames[i].function()->IsFromNativeScript()) n++;
+ }
}
return Smi::FromInt(n);
}
? deoptimized_frame_->HasConstructStub()
: frame_->IsConstructor();
}
+ Object* GetContext() {
+ return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
+ }
// To inspect all the provided arguments the frame might need to be
// replaced with the arguments frame.
void SetArgumentsFrame(JavaScriptFrame* frame) {
- ASSERT(has_adapted_arguments_);
+ DCHECK(has_adapted_arguments_);
frame_ = frame;
is_optimized_ = frame_->is_optimized();
- ASSERT(!is_optimized_);
+ DCHECK(!is_optimized_);
}
private:
while (save != NULL && !save->IsBelowFrame(frame)) {
save = save->prev();
}
- ASSERT(save != NULL);
+ DCHECK(save != NULL);
return save;
}
+// Advances the iterator to the frame that matches the index and returns the
+// inlined frame index, or -1 if not found. Skips native JS functions.
+static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
+ int count = -1;
+ for (; !it->done(); it->Advance()) {
+ List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+ it->frame()->Summarize(&frames);
+ for (int i = frames.length() - 1; i >= 0; i--) {
+ // Omit functions from native scripts.
+ if (frames[i].function()->IsFromNativeScript()) continue;
+ if (++count == index) return i;
+ }
+ }
+ return -1;
+}
+
+
// Return an array with frame details
// args[0]: number: break id
// args[1]: number: frame index
// Return value if any
RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
return heap->undefined_value();
}
- int count = 0;
JavaScriptFrameIterator it(isolate, id);
- for (; !it.done(); it.Advance()) {
- if (index < count + it.frame()->GetInlineCount()) break;
- count += it.frame()->GetInlineCount();
- }
- if (it.done()) return heap->undefined_value();
-
- bool is_optimized = it.frame()->is_optimized();
+ // Inlined frame index in optimized frame, starting from outer function.
+ int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
+ if (inlined_jsframe_index == -1) return heap->undefined_value();
- int inlined_jsframe_index = 0; // Inlined frame index in optimized frame.
- if (is_optimized) {
- inlined_jsframe_index =
- it.frame()->GetInlineCount() - (index - count) - 1;
- }
FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
+ bool is_optimized = it.frame()->is_optimized();
// Traverse the saved contexts chain to find the active context for the
// selected frame.
Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
Handle<SharedFunctionInfo> shared(function->shared());
Handle<ScopeInfo> scope_info(shared->scope_info());
- ASSERT(*scope_info != ScopeInfo::Empty(isolate));
+ DCHECK(*scope_info != ScopeInfo::Empty(isolate));
// Get the locals names and values into a temporary array.
int local_count = scope_info->LocalCount();
if (local < local_count) {
// Get the context containing declarations.
Handle<Context> context(
- Context::cast(it.frame()->context())->declaration_context());
+ Context::cast(frame_inspector.GetContext())->declaration_context());
for (; i < scope_info->LocalCount(); ++i) {
if (scope_info->LocalIsSynthetic(i))
continue;
Handle<String> name(scope_info->LocalName(i));
VariableMode mode;
InitializationFlag init_flag;
+ MaybeAssignedFlag maybe_assigned_flag;
locals->set(local * 2, *name);
- int context_slot_index =
- ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
+ int context_slot_index = ScopeInfo::ContextSlotIndex(
+ scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
Object* value = context->get(context_slot_index);
locals->set(local * 2 + 1, value);
local++;
// native context.
it.Advance();
if (receiver->IsUndefined()) {
- Context* context = function->context();
- receiver = handle(context->global_object()->global_receiver());
+ receiver = handle(function->global_proxy());
} else {
- ASSERT(!receiver->IsNull());
Context* context = Context::cast(it.frame()->context());
Handle<Context> native_context(Context::cast(context->native_context()));
- receiver = Object::ToObject(
- isolate, receiver, native_context).ToHandleChecked();
+ if (!Object::ToObject(isolate, receiver, native_context)
+ .ToHandle(&receiver)) {
+ // This only happens if the receiver is forcibly set in %_CallFunction.
+ return heap->undefined_value();
+ }
}
}
details->set(kFrameDetailsReceiverIndex, *receiver);
- ASSERT_EQ(details_size, details_index);
+ DCHECK_EQ(details_size, details_index);
return *isolate->factory()->NewJSArrayWithElements(details);
}
static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
Handle<String> parameter_name) {
VariableMode mode;
- InitializationFlag flag;
- return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &flag) != -1;
+ InitializationFlag init_flag;
+ MaybeAssignedFlag maybe_assigned_flag;
+ return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
+ &maybe_assigned_flag) != -1;
}
? frame_inspector->GetParameter(i)
: isolate->heap()->undefined_value(),
isolate);
- ASSERT(!value->IsTheHole());
+ DCHECK(!value->IsTheHole());
RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
+ Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
JSObject);
}
RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
+ Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
JSObject);
}
Handle<String> name(scope_info->ParameterName(i));
if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
- ASSERT(!frame->GetParameter(i)->IsTheHole());
+ DCHECK(!frame->GetParameter(i)->IsTheHole());
HandleScope scope(isolate);
Handle<Object> value =
Object::GetPropertyOrElement(target, name).ToHandleChecked();
for (int i = 0; i < keys->length(); i++) {
// Names of variables introduced by eval are strings.
- ASSERT(keys->get(i)->IsString());
+ DCHECK(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(
- isolate, target, key, value, NONE, SLOPPY),
+ Runtime::SetObjectProperty(isolate, target, key, value, SLOPPY),
JSObject);
}
}
if (String::Equals(variable_name, next_name)) {
VariableMode mode;
InitializationFlag init_flag;
- int context_index =
- ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &init_flag);
+ MaybeAssignedFlag maybe_assigned_flag;
+ int context_index = ScopeInfo::ContextSlotIndex(
+ scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
context->set(context_index, *new_value);
return true;
}
!function_context->IsNativeContext()) {
Handle<JSObject> ext(JSObject::cast(function_context->extension()));
- if (JSReceiver::HasProperty(ext, variable_name)) {
+ Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
+ DCHECK(maybe.has_value);
+ if (maybe.value) {
// We don't expect this to do anything except replacing
// property value.
Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
- NONE, SLOPPY).Assert();
+ SLOPPY).Assert();
return true;
}
}
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->IsFunctionContext());
+ DCHECK(context->IsFunctionContext());
Handle<SharedFunctionInfo> shared(context->closure()->shared());
Handle<ScopeInfo> scope_info(shared->scope_info());
for (int i = 0; i < keys->length(); i++) {
HandleScope scope(isolate);
// Names of variables introduced by eval are strings.
- ASSERT(keys->get(i)->IsString());
+ DCHECK(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(
- isolate, closure_scope, key, value, NONE, SLOPPY),
+ Runtime::DefineObjectProperty(closure_scope, key, value, NONE),
JSObject);
}
}
Handle<Context> context,
Handle<String> variable_name,
Handle<Object> new_value) {
- ASSERT(context->IsFunctionContext());
+ DCHECK(context->IsFunctionContext());
Handle<SharedFunctionInfo> shared(context->closure()->shared());
Handle<ScopeInfo> scope_info(shared->scope_info());
// be variables introduced by eval.
if (context->has_extension()) {
Handle<JSObject> ext(JSObject::cast(context->extension()));
- if (JSReceiver::HasProperty(ext, variable_name)) {
+ Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
+ DCHECK(maybe.has_value);
+ if (maybe.value) {
// We don't expect this to do anything except replacing property value.
- Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
- NONE, SLOPPY).Assert();
+ Runtime::DefineObjectProperty(
+ ext, variable_name, new_value, NONE).Assert();
return true;
}
}
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->IsCatchContext());
+ DCHECK(context->IsCatchContext());
Handle<String> name(String::cast(context->extension()));
Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
isolate);
isolate->factory()->NewJSObject(isolate->object_function());
RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
- NONE, SLOPPY),
+ Runtime::DefineObjectProperty(catch_scope, name, thrown_object, NONE),
JSObject);
return catch_scope;
}
Handle<Context> context,
Handle<String> variable_name,
Handle<Object> new_value) {
- ASSERT(context->IsCatchContext());
+ DCHECK(context->IsCatchContext());
Handle<String> name(String::cast(context->extension()));
if (!String::Equals(name, variable_name)) {
return false;
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->IsBlockContext());
+ DCHECK(context->IsBlockContext());
Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
// Allocate and initialize a JSObject with all the arguments, stack locals
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->IsModuleContext());
+ DCHECK(context->IsModuleContext());
Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
// Allocate and initialize a JSObject with all the members of the debugged
if (scope_info->scope_type() == GLOBAL_SCOPE) {
info.MarkAsGlobal();
} else {
- ASSERT(scope_info->scope_type() == EVAL_SCOPE);
+ DCHECK(scope_info->scope_type() == EVAL_SCOPE);
info.MarkAsEval();
info.SetContext(Handle<Context>(function_->context()));
}
// More scopes?
bool Done() {
- ASSERT(!failed_);
+ DCHECK(!failed_);
return context_.is_null();
}
// Move to the next scope.
void Next() {
- ASSERT(!failed_);
+ DCHECK(!failed_);
ScopeType scope_type = Type();
if (scope_type == ScopeTypeGlobal) {
// The global scope is always the last in the chain.
- ASSERT(context_->IsNativeContext());
+ DCHECK(context_->IsNativeContext());
context_ = Handle<Context>();
return;
}
context_ = Handle<Context>(context_->previous(), isolate_);
} else {
if (nested_scope_chain_.last()->HasContext()) {
- ASSERT(context_->previous() != NULL);
+ DCHECK(context_->previous() != NULL);
context_ = Handle<Context>(context_->previous(), isolate_);
}
nested_scope_chain_.RemoveLast();
// Return the type of the current scope.
ScopeType Type() {
- ASSERT(!failed_);
+ DCHECK(!failed_);
if (!nested_scope_chain_.is_empty()) {
Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
switch (scope_info->scope_type()) {
case FUNCTION_SCOPE:
- ASSERT(context_->IsFunctionContext() ||
+ DCHECK(context_->IsFunctionContext() ||
!scope_info->HasContext());
return ScopeTypeLocal;
case MODULE_SCOPE:
- ASSERT(context_->IsModuleContext());
+ DCHECK(context_->IsModuleContext());
return ScopeTypeModule;
case GLOBAL_SCOPE:
- ASSERT(context_->IsNativeContext());
+ DCHECK(context_->IsNativeContext());
return ScopeTypeGlobal;
case WITH_SCOPE:
- ASSERT(context_->IsWithContext());
+ DCHECK(context_->IsWithContext());
return ScopeTypeWith;
case CATCH_SCOPE:
- ASSERT(context_->IsCatchContext());
+ DCHECK(context_->IsCatchContext());
return ScopeTypeCatch;
case BLOCK_SCOPE:
- ASSERT(!scope_info->HasContext() ||
+ DCHECK(!scope_info->HasContext() ||
context_->IsBlockContext());
return ScopeTypeBlock;
case EVAL_SCOPE:
}
}
if (context_->IsNativeContext()) {
- ASSERT(context_->global_object()->IsGlobalObject());
+ DCHECK(context_->global_object()->IsGlobalObject());
return ScopeTypeGlobal;
}
if (context_->IsFunctionContext()) {
if (context_->IsModuleContext()) {
return ScopeTypeModule;
}
- ASSERT(context_->IsWithContext());
+ DCHECK(context_->IsWithContext());
return ScopeTypeWith;
}
// Return the JavaScript object with the content of the current scope.
MaybeHandle<JSObject> ScopeObject() {
- ASSERT(!failed_);
+ DCHECK(!failed_);
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
return Handle<JSObject>(CurrentContext()->global_object());
case ScopeIterator::ScopeTypeLocal:
// Materialize the content of the local scope into a JSObject.
- ASSERT(nested_scope_chain_.length() == 1);
+ DCHECK(nested_scope_chain_.length() == 1);
return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
case ScopeIterator::ScopeTypeWith:
// Return the with object.
bool SetVariableValue(Handle<String> variable_name,
Handle<Object> new_value) {
- ASSERT(!failed_);
+ DCHECK(!failed_);
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
break;
}
Handle<ScopeInfo> CurrentScopeInfo() {
- ASSERT(!failed_);
+ DCHECK(!failed_);
if (!nested_scope_chain_.is_empty()) {
return nested_scope_chain_.last();
} else if (context_->IsBlockContext()) {
// Return the context for this scope. For the local context there might not
// be an actual context.
Handle<Context> CurrentContext() {
- ASSERT(!failed_);
+ DCHECK(!failed_);
if (Type() == ScopeTypeGlobal ||
nested_scope_chain_.is_empty()) {
return context_;
#ifdef DEBUG
// Debug print of the content of the current scope.
void DebugPrint() {
- ASSERT(!failed_);
+ OFStream os(stdout);
+ DCHECK(!failed_);
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
- PrintF("Global:\n");
- CurrentContext()->Print();
+ os << "Global:\n";
+ CurrentContext()->Print(os);
break;
case ScopeIterator::ScopeTypeLocal: {
- PrintF("Local:\n");
+ os << "Local:\n";
function_->shared()->scope_info()->Print();
if (!CurrentContext().is_null()) {
- CurrentContext()->Print();
+ CurrentContext()->Print(os);
if (CurrentContext()->has_extension()) {
Handle<Object> extension(CurrentContext()->extension(), isolate_);
if (extension->IsJSContextExtensionObject()) {
- extension->Print();
+ extension->Print(os);
}
}
}
}
case ScopeIterator::ScopeTypeWith:
- PrintF("With:\n");
- CurrentContext()->extension()->Print();
+ os << "With:\n";
+ CurrentContext()->extension()->Print(os);
break;
case ScopeIterator::ScopeTypeCatch:
- PrintF("Catch:\n");
- CurrentContext()->extension()->Print();
- CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
+ os << "Catch:\n";
+ CurrentContext()->extension()->Print(os);
+ CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
break;
case ScopeIterator::ScopeTypeClosure:
- PrintF("Closure:\n");
- CurrentContext()->Print();
+ os << "Closure:\n";
+ CurrentContext()->Print(os);
if (CurrentContext()->has_extension()) {
Handle<Object> extension(CurrentContext()->extension(), isolate_);
if (extension->IsJSContextExtensionObject()) {
- extension->Print();
+ extension->Print(os);
}
}
break;
// information we get from the context chain but nothing about
// completely stack allocated scopes or stack allocated locals.
// Or it could be due to stack overflow.
- ASSERT(isolate_->has_pending_exception());
+ DCHECK(isolate_->has_pending_exception());
failed_ = true;
}
}
RUNTIME_FUNCTION(Runtime_GetScopeCount) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// of the corresponding statement.
RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// 1: Scope object
RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// 1: Scope object
RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3 || args.length() == 4);
+ DCHECK(args.length() == 3 || args.length() == 4);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
// Check arguments.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
// Check arguments.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
// Return true if success and false otherwise
RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
HandleScope scope(isolate);
- ASSERT(args.length() == 6);
+ DCHECK(args.length() == 6);
// Check arguments.
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
#ifdef DEBUG
// Print the scopes for the top frame.
RUNTIME_FUNCTION(Runtime_GetThreadCount) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// 1: Thread id
RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// args[0]: disable break state
RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
isolate->debug()->set_disable_break(disable_break);
return isolate->heap()->undefined_value();
RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
// args[2]: number: break point object
RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
// args[3]: number: break point object
RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
// args[0]: number: break point object
RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
// Clear break point.
// args[1]: Boolean indicating on/off.
RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
// args[0]: boolean indicating uncaught exceptions
RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
// of frames to step down.
RUNTIME_FUNCTION(Runtime_PrepareStep) {
HandleScope scope(isolate);
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// Clear all stepping set by PrepareStep.
RUNTIME_FUNCTION(Runtime_ClearStepping) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
isolate->debug()->ClearStepping();
return isolate->heap()->undefined_value();
}
Handle<JSFunction> function) {
// Do not materialize the arguments object for eval or top-level code.
// Skip if "arguments" is already taken.
- if (!function->shared()->is_function() ||
- JSReceiver::HasOwnProperty(
- target, isolate->factory()->arguments_string())) {
- return target;
- }
+ if (!function->shared()->is_function()) return target;
+ Maybe<bool> maybe = JSReceiver::HasOwnProperty(
+ target, isolate->factory()->arguments_string());
+ if (!maybe.has_value) return MaybeHandle<JSObject>();
+ if (maybe.value) return target;
// FunctionGetArguments can't throw an exception.
Handle<JSObject> arguments = Handle<JSObject>::cast(
Handle<String> arguments_str = isolate->factory()->arguments_string();
RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(
- isolate, target, arguments_str, arguments, ::NONE, SLOPPY),
+ Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE),
JSObject);
return target;
}
// Compile and evaluate source for the given context.
static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
+ Handle<SharedFunctionInfo> outer_info,
Handle<Context> context,
Handle<Object> context_extension,
Handle<Object> receiver,
ASSIGN_RETURN_ON_EXCEPTION(
isolate, eval_fun,
Compiler::GetFunctionFromEval(source,
+ outer_info,
context,
SLOPPY,
NO_PARSE_RESTRICTION,
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
if (result->IsJSGlobalProxy()) {
- result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
+ PrototypeIterator iter(isolate, result);
+ // TODO(verwaest): This will crash when the global proxy is detached.
+ result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
}
// Clear the oneshot breakpoints so that the debugger does not step further.
}
+static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
+ Handle<JSObject> result =
+ isolate->factory()->NewJSObject(isolate->object_function());
+ Handle<Map> new_map = Map::Copy(Handle<Map>(result->map()));
+ new_map->set_prototype(*isolate->factory()->null_value());
+ JSObject::MigrateToMap(result, new_map);
+ return result;
+}
+
+
// Evaluate a piece of JavaScript in the context of a stack frame for
// debugging. Things that need special attention are:
// - Parameters and stack-allocated locals need to be materialized. Altered
// Check the execution state and decode arguments frame and source to be
// evaluated.
- ASSERT(args.length() == 6);
+ DCHECK(args.length() == 6);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
JavaScriptFrame* frame = it.frame();
FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
+ Handle<SharedFunctionInfo> outer_info(function->shared());
// Traverse the saved contexts chain to find the active context for the
// selected frame.
isolate->set_context(*(save->context()));
// Evaluate on the context of the frame.
- Handle<Context> context(Context::cast(frame->context()));
- ASSERT(!context.is_null());
+ Handle<Context> context(Context::cast(frame_inspector.GetContext()));
+ DCHECK(!context.is_null());
// Materialize stack locals and the arguments object.
- Handle<JSObject> materialized =
- isolate->factory()->NewJSObject(isolate->object_function());
+ Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, materialized,
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- DebugEvaluate(isolate, context, context_extension, receiver, source));
+ DebugEvaluate(isolate, outer_info,
+ context, context_extension, receiver, source));
// Write back potential changes to materialized stack locals to the stack.
UpdateStackLocalsFromMaterializedObject(
// Check the execution state and decode arguments frame and source to be
// evaluated.
- ASSERT(args.length() == 4);
+ DCHECK(args.length() == 4);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// Get the native context now set to the top context from before the
// debugger was invoked.
Handle<Context> context = isolate->native_context();
- Handle<Object> receiver = isolate->global_object();
+ Handle<JSObject> receiver(context->global_proxy());
+ Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- DebugEvaluate(isolate, context, context_extension, receiver, source));
+ DebugEvaluate(isolate, outer_info,
+ context, context_extension, receiver, source));
return *result;
}
RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
// Fill the script objects.
Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
// Check instance filter if supplied. This is normally used to avoid
// references from mirror objects (see Runtime_IsInPrototypeChain).
if (!instance_filter->IsUndefined()) {
- Object* V = obj;
- while (true) {
- Object* prototype = V->GetPrototype(isolate);
- if (prototype->IsNull()) {
- break;
- }
- if (instance_filter == prototype) {
+ for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
+ iter.Advance()) {
+ if (iter.GetCurrent() == instance_filter) {
obj = NULL; // Don't add this object.
break;
}
- V = prototype;
}
}
// args[2]: the the maximum number of objects to return
RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
// Check parameters.
CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
// Get the constructor function for context extension and arguments array.
- Handle<JSObject> arguments_boilerplate(
- isolate->context()->native_context()->sloppy_arguments_boilerplate());
Handle<JSFunction> arguments_function(
- JSFunction::cast(arguments_boilerplate->map()->constructor()));
+ JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
// Get the number of referencing objects.
int count;
}
// Return result as JS array.
- Handle<JSFunction> constructor(
- isolate->context()->native_context()->array_function());
+ Handle<JSFunction> constructor = isolate->array_function();
Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
JSArray::SetContent(Handle<JSArray>::cast(result), instances);
// args[1]: the the maximum number of objects to return
RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
// Check parameters.
}
// Return result as JS array.
- Handle<JSFunction> array_function(
- isolate->context()->native_context()->array_function());
+ Handle<JSFunction> array_function = isolate->array_function();
Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
JSArray::SetContent(Handle<JSArray>::cast(result), instances);
return *result;
// args[0]: the object to find the prototype for.
RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
HandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
}
// Patches script source (should be called upon BeforeCompile event).
RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
RUNTIME_FUNCTION(Runtime_SystemBreak) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
- OS::DebugBreak();
+ DCHECK(args.length() == 0);
+ base::OS::DebugBreak();
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
HandleScope scope(isolate);
#ifdef DEBUG
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
return isolate->heap()->exception();
}
- func->code()->PrintLn();
+ OFStream os(stdout);
+ func->code()->Print(os);
+ os << endl;
#endif // DEBUG
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
HandleScope scope(isolate);
#ifdef DEBUG
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
return isolate->heap()->exception();
}
- func->shared()->construct_stub()->PrintLn();
+ OFStream os(stdout);
+ func->shared()->construct_stub()->Print(os);
+ os << endl;
#endif // DEBUG
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
return f->shared()->inferred_name();
for (HeapObject* obj = iterator->next();
obj != NULL;
obj = iterator->next()) {
- ASSERT(obj != NULL);
+ DCHECK(obj != NULL);
if (!obj->IsSharedFunctionInfo()) {
continue;
}
RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSValue, script_value, 0);
RUNTIME_ASSERT(script_value->value()->IsScript());
RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(JSValue, script, 0);
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
RUNTIME_ASSERT(shared_array->length()->IsSmi());
+ RUNTIME_ASSERT(shared_array->HasFastElements())
int array_length = Smi::cast(shared_array->length())->value();
for (int i = 0; i < array_length; i++) {
Handle<Object> element =
RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
return heap->undefined_value();
}
- int count = 0;
JavaScriptFrameIterator it(isolate, id);
- for (; !it.done(); it.Advance()) {
- if (index < count + it.frame()->GetInlineCount()) break;
- count += it.frame()->GetInlineCount();
- }
- if (it.done()) return heap->undefined_value();
-
+ int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
+ if (inlined_jsframe_index == -1) return heap->undefined_value();
+ // We don't really care what the inlined frame index is, since we are
+ // throwing away the entire frame anyways.
const char* error_message = LiveEdit::RestartFrame(it.frame());
if (error_message) {
return *(isolate->factory()->InternalizeUtf8String(error_message));
RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
// to have a stack with C++ frame in the middle.
RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
if (without_debugger) {
maybe_result = Execution::Call(isolate,
function,
- isolate->global_object(),
+ handle(function->global_proxy()),
0,
NULL);
} else {
DebugScope debug_scope(isolate->debug());
maybe_result = Execution::Call(isolate,
function,
- isolate->global_object(),
+ handle(function->global_proxy()),
0,
NULL);
}
// Sets a v8 flag.
RUNTIME_FUNCTION(Runtime_SetFlags) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(String, arg, 0);
SmartArrayPointer<char> flags =
arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
// Presently, it only does a full GC.
RUNTIME_FUNCTION(Runtime_CollectGarbage) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
return isolate->heap()->undefined_value();
}
// Gets the current heap usage.
RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
if (!Smi::IsValid(usage)) {
return *isolate->factory()->NewNumberFromInt(usage);
HandleScope scope(isolate);
Factory* factory = isolate->factory();
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
HandleScope scope(isolate);
Factory* factory = isolate->factory();
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
const icu::Locale* available_locales = NULL;
HandleScope scope(isolate);
Factory* factory = isolate->factory();
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
icu::Locale default_locale;
return *factory->NewStringFromAsciiChecked(result);
}
- return *factory->NewStringFromStaticAscii("und");
+ return *factory->NewStringFromStaticChars("und");
}
HandleScope scope(isolate);
Factory* factory = isolate->factory();
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
// Can be bumped when callers' requirements change.
RUNTIME_ASSERT(length < 100);
Handle<FixedArray> output = factory->NewFixedArray(length);
- Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
- Handle<Name> base = factory->NewStringFromStaticAscii("base");
+ Handle<Name> maximized = factory->NewStringFromStaticChars("maximized");
+ Handle<Name> base = factory->NewStringFromStaticChars("base");
for (unsigned int i = 0; i < length; ++i) {
Handle<Object> locale_id;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
}
Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- result,
- maximized,
- factory->NewStringFromAsciiChecked(base_max_locale),
- NONE));
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- result,
- base,
- factory->NewStringFromAsciiChecked(base_locale),
- NONE));
+ Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale);
+ JSObject::AddProperty(result, maximized, value, NONE);
+ value = factory->NewStringFromAsciiChecked(base_locale);
+ JSObject::AddProperty(result, base, value, NONE);
output->set(i, *result);
}
RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
if (!input->IsJSObject()) {
Vector< Handle<Object> > arguments = HandleVector(&input, 1);
- Handle<Object> type_error =
- isolate->factory()->NewTypeError("not_intl_object", arguments);
- return isolate->Throw(*type_error);
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+ NewTypeError("not_intl_object", arguments));
}
Handle<JSObject> obj = Handle<JSObject>::cast(input);
Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
if (impl->IsTheHole()) {
Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
- Handle<Object> type_error =
- isolate->factory()->NewTypeError("not_intl_object", arguments);
- return isolate->Throw(*type_error);
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+ NewTypeError("not_intl_object", arguments));
}
return *impl;
}
RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- local_object,
- isolate->factory()->NewStringFromStaticAscii("dateFormat"),
- isolate->factory()->NewStringFromStaticAscii("valid"),
- NONE));
+ Factory* factory = isolate->factory();
+ Handle<String> key = factory->NewStringFromStaticChars("dateFormat");
+ Handle<String> value = factory->NewStringFromStaticChars("valid");
+ JSObject::AddProperty(local_object, key, value, NONE);
// Make object handle weak so we can delete the data format once GC kicks in.
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
RUNTIME_FUNCTION(Runtime_InternalDateParse) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Execution::NewDate(isolate, static_cast<double>(date)));
- ASSERT(result->IsJSDate());
+ DCHECK(result->IsJSDate());
return *result;
}
RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- local_object,
- isolate->factory()->NewStringFromStaticAscii("numberFormat"),
- isolate->factory()->NewStringFromStaticAscii("valid"),
- NONE));
+ Factory* factory = isolate->factory();
+ Handle<String> key = factory->NewStringFromStaticChars("numberFormat");
+ Handle<String> value = factory->NewStringFromStaticChars("valid");
+ JSObject::AddProperty(local_object, key, value, NONE);
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
GlobalHandles::MakeWeak(wrapper.location(),
RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
RUNTIME_FUNCTION(Runtime_CreateCollator) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- local_object,
- isolate->factory()->NewStringFromStaticAscii("collator"),
- isolate->factory()->NewStringFromStaticAscii("valid"),
- NONE));
+ Factory* factory = isolate->factory();
+ Handle<String> key = factory->NewStringFromStaticChars("collator");
+ Handle<String> value = factory->NewStringFromStaticChars("valid");
+ JSObject::AddProperty(local_object, key, value, NONE);
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
GlobalHandles::MakeWeak(wrapper.location(),
RUNTIME_FUNCTION(Runtime_InternalCompare) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
static const UNormalizationMode normalizationForms[] =
{ UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
RUNTIME_ASSERT(form_id >= 0 &&
- static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
+ static_cast<size_t>(form_id) < arraysize(normalizationForms));
v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
// Make sure that the pointer to adopted text is NULL.
local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
- RETURN_FAILURE_ON_EXCEPTION(isolate,
- JSObject::SetOwnPropertyIgnoreAttributes(
- local_object,
- isolate->factory()->NewStringFromStaticAscii("breakIterator"),
- isolate->factory()->NewStringFromStaticAscii("valid"),
- NONE));
+ Factory* factory = isolate->factory();
+ Handle<String> key = factory->NewStringFromStaticChars("breakIterator");
+ Handle<String> value = factory->NewStringFromStaticChars("valid");
+ JSObject::AddProperty(local_object, key, value, NONE);
// Make object handle weak so we can delete the break iterator once GC kicks
// in.
RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
int32_t status = rule_based_iterator->getRuleStatus();
// Keep return values in sync with JavaScript BreakType enum.
if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
- return *isolate->factory()->NewStringFromStaticAscii("none");
+ return *isolate->factory()->NewStringFromStaticChars("none");
} else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
- return *isolate->factory()->NewStringFromStaticAscii("number");
+ return *isolate->factory()->number_string();
} else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
- return *isolate->factory()->NewStringFromStaticAscii("letter");
+ return *isolate->factory()->NewStringFromStaticChars("letter");
} else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
- return *isolate->factory()->NewStringFromStaticAscii("kana");
+ return *isolate->factory()->NewStringFromStaticChars("kana");
} else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
- return *isolate->factory()->NewStringFromStaticAscii("ideo");
+ return *isolate->factory()->NewStringFromStaticChars("ideo");
} else {
- return *isolate->factory()->NewStringFromStaticAscii("unknown");
+ return *isolate->factory()->NewStringFromStaticChars("unknown");
}
}
#endif // V8_I18N_SUPPORT
RUNTIME_FUNCTION(Runtime_GetScript) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(String, script_name, 0);
// native code offset.
RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(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;
+ if (!isolate->bootstrapper()->IsActive()) {
+ // Optionally capture a more detailed stack trace for the message.
+ isolate->CaptureAndSetDetailedStackTrace(error_object);
+ // Capture a simple stack trace for the stack property.
+ isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
+ }
+ return isolate->heap()->undefined_value();
}
// Returns V8 version as a string.
RUNTIME_FUNCTION(Runtime_GetV8Version) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
const char* version_string = v8::V8::GetVersion();
}
+// Returns function of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+ return generator->function();
+}
+
+
+// Returns context of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetContext) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+ return generator->context();
+}
+
+
+// Returns receiver of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+ return generator->receiver();
+}
+
+
+// Returns generator continuation as a PC offset, or the magic -1 or 0 values.
+RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+ return Smi::FromInt(generator->continuation());
+}
+
+
+RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+ if (generator->is_suspended()) {
+ Handle<Code> code(generator->function()->code(), isolate);
+ int offset = generator->continuation();
+
+ RUNTIME_ASSERT(0 <= offset && offset < code->Size());
+ Address pc = code->address() + offset;
+
+ return Smi::FromInt(code->SourcePosition(pc));
+ }
+
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(Runtime_Abort) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_SMI_ARG_CHECKED(message_id, 0);
const char* message = GetBailoutReason(
static_cast<BailoutReason>(message_id));
- OS::PrintError("abort: %s\n", message);
+ base::OS::PrintError("abort: %s\n", message);
isolate->PrintStack(stderr);
- OS::Abort();
+ base::OS::Abort();
UNREACHABLE();
return NULL;
}
RUNTIME_FUNCTION(Runtime_AbortJS) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
- OS::PrintError("abort: %s\n", message->ToCString().get());
+ base::OS::PrintError("abort: %s\n", message->ToCString().get());
isolate->PrintStack(stderr);
- OS::Abort();
+ base::OS::Abort();
UNREACHABLE();
return NULL;
}
RUNTIME_FUNCTION(Runtime_FlattenString) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
return *String::Flatten(str);
}
RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
isolate->heap()->NotifyContextDisposed();
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
RUNTIME_ASSERT((index->value() & 1) == 1);
object->properties()->length());
}
Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
- RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
- return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
+ RUNTIME_ASSERT(raw_value->IsMutableHeapNumber());
+ return *Object::WrapForRead(isolate, raw_value, Representation::Double());
}
RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
if (!object->IsJSObject()) return Smi::FromInt(0);
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
}
-RUNTIME_FUNCTION(RuntimeHidden_GetFromCache) {
+RUNTIME_FUNCTION(Runtime_GetFromCache) {
SealHandleScope shs(isolate);
// This is only called from codegen, so checks might be more lax.
CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
}
int size = cache->size();
- ASSERT(size <= cache->length());
+ DCHECK(size <= cache->length());
for (int i = size - 2; i > finger_index; i -= 2) {
o = cache->get(i);
Handle<JSFunction> factory(JSFunction::cast(
cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
// TODO(antonm): consider passing a receiver when constructing a cache.
- Handle<Object> receiver(isolate->native_context()->global_object(),
- isolate);
+ Handle<JSObject> receiver(isolate->global_proxy());
// This handle is nor shared, nor used later, so it's safe.
Handle<Object> argv[] = { key_handle };
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, value,
- Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
+ Execution::Call(isolate, factory, receiver, arraysize(argv), argv));
}
#ifdef VERIFY_HEAP
}
}
- ASSERT(index % 2 == 0);
- ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
- ASSERT(index < cache_handle->length());
+ DCHECK(index % 2 == 0);
+ DCHECK(index >= JSFunctionResultCache::kEntriesIndex);
+ DCHECK(index < cache_handle->length());
cache_handle->set(index, *key_handle);
cache_handle->set(index + 1, *value);
RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return Smi::FromInt(message->start_position());
}
RUNTIME_FUNCTION(Runtime_MessageGetScript) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return message->script();
}
// Exclude the code in release mode.
RUNTIME_FUNCTION(Runtime_ListNatives) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
#define COUNT_ENTRY(Name, argc, ressize) + 1
int entry_count = 0
RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
- RUNTIME_HIDDEN_FUNCTION_LIST(COUNT_ENTRY)
INLINE_FUNCTION_LIST(COUNT_ENTRY)
INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
#undef COUNT_ENTRY
Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
int index = 0;
bool inline_runtime_functions = false;
-#define ADD_ENTRY(Name, argc, ressize) \
- { \
- HandleScope inner(isolate); \
- Handle<String> name; \
- /* Inline runtime functions have an underscore in front of the name. */ \
- if (inline_runtime_functions) { \
- name = factory->NewStringFromStaticAscii("_" #Name); \
- } else { \
- name = factory->NewStringFromStaticAscii(#Name); \
- } \
- Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \
- pair_elements->set(0, *name); \
- pair_elements->set(1, Smi::FromInt(argc)); \
- Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements); \
- elements->set(index++, *pair); \
+#define ADD_ENTRY(Name, argc, ressize) \
+ { \
+ HandleScope inner(isolate); \
+ Handle<String> name; \
+ /* Inline runtime functions have an underscore in front of the name. */ \
+ if (inline_runtime_functions) { \
+ name = factory->NewStringFromStaticChars("_" #Name); \
+ } else { \
+ name = factory->NewStringFromStaticChars(#Name); \
+ } \
+ Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \
+ pair_elements->set(0, *name); \
+ pair_elements->set(1, Smi::FromInt(argc)); \
+ Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements); \
+ elements->set(index++, *pair); \
}
inline_runtime_functions = false;
RUNTIME_FUNCTION_LIST(ADD_ENTRY)
INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
- // Calling hidden runtime functions should just throw.
- RUNTIME_HIDDEN_FUNCTION_LIST(ADD_ENTRY)
inline_runtime_functions = true;
INLINE_FUNCTION_LIST(ADD_ENTRY)
#undef ADD_ENTRY
- ASSERT_EQ(index, entry_count);
+ DCHECK_EQ(index, entry_count);
Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
return *result;
}
RUNTIME_FUNCTION(Runtime_HaveSameMap) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
+ DCHECK(args.length() == 2);
CONVERT_ARG_CHECKED(JSObject, obj1, 0);
CONVERT_ARG_CHECKED(JSObject, obj2, 1);
return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
}
RUNTIME_FUNCTION(Runtime_IsObserved) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
- ASSERT(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
+ DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
return isolate->heap()->ToBoolean(obj->map()->is_observed());
}
RUNTIME_FUNCTION(Runtime_SetIsObserved) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
RUNTIME_ASSERT(!obj->map()->is_observed());
- ASSERT(obj->IsJSObject());
+ DCHECK(obj->IsJSObject());
JSObject::SetObserved(Handle<JSObject>::cast(obj));
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
isolate->EnqueueMicrotask(microtask);
return isolate->heap()->undefined_value();
RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
isolate->RunMicrotasks();
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_GetObservationState) {
SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
return isolate->heap()->observation_state();
}
RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
HandleScope scope(isolate);
- ASSERT(args.length() == 0);
+ DCHECK(args.length() == 0);
// TODO(adamk): Currently this runtime function is only called three times per
// isolate. If it's called more often, the map should be moved into the
// strong root list.
RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
- Handle<Context> observer_context(observer->context()->native_context(),
- isolate);
+ Handle<Context> observer_context(observer->context()->native_context());
Handle<Context> object_context(object->GetCreationContext());
Handle<Context> record_context(record->GetCreationContext());
RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Handle<Context> creation_context(object->GetCreationContext(), isolate);
RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Handle<Context> context(object->GetCreationContext(), isolate);
RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Handle<Context> context(object->GetCreationContext(), isolate);
RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
Handle<Context> context(object_info->GetCreationContext(), isolate);
}
-RUNTIME_FUNCTION(RuntimeHidden_ArrayConstructor) {
+RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
HandleScope scope(isolate);
// If we get 2 arguments then they are the stub parameters (constructor, type
// info). If we get 4, then the first one is a pointer to the arguments
// with an assert).
Arguments empty_args(0, NULL);
bool no_caller_args = args.length() == 2;
- ASSERT(no_caller_args || args.length() == 4);
+ DCHECK(no_caller_args || args.length() == 4);
int parameters_start = no_caller_args ? 0 : 1;
Arguments* caller_args = no_caller_args
? &empty_args
#ifdef DEBUG
if (!no_caller_args) {
CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
- ASSERT(arg_count == caller_args->length());
+ DCHECK(arg_count == caller_args->length());
}
#endif
if (!type_info.is_null() &&
*type_info != isolate->heap()->undefined_value()) {
site = Handle<AllocationSite>::cast(type_info);
- ASSERT(!site->SitePointsToLiteral());
+ DCHECK(!site->SitePointsToLiteral());
}
return ArrayConstructorCommon(isolate,
}
-RUNTIME_FUNCTION(RuntimeHidden_InternalArrayConstructor) {
+RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
HandleScope scope(isolate);
Arguments empty_args(0, NULL);
bool no_caller_args = args.length() == 1;
- ASSERT(no_caller_args || args.length() == 3);
+ DCHECK(no_caller_args || args.length() == 3);
int parameters_start = no_caller_args ? 0 : 1;
Arguments* caller_args = no_caller_args
? &empty_args
#ifdef DEBUG
if (!no_caller_args) {
CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
- ASSERT(arg_count == caller_args->length());
+ DCHECK(arg_count == caller_args->length());
}
#endif
return ArrayConstructorCommon(isolate,
}
+RUNTIME_FUNCTION(Runtime_NormalizeElements) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
+ RUNTIME_ASSERT(!array->HasExternalArrayElements() &&
+ !array->HasFixedTypedArrayElements());
+ JSObject::NormalizeElements(array);
+ return *array;
+}
+
+
RUNTIME_FUNCTION(Runtime_MaxSmi) {
- ASSERT(args.length() == 0);
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 0);
return Smi::FromInt(Smi::kMaxValue);
}
-// ----------------------------------------------------------------------------
-// Implementation of Runtime
+// TODO(dcarney): remove this function when TurboFan supports it.
+// Takes the object to be iterated over and the result of GetPropertyNamesFast
+// Returns pair (cache_array, cache_type).
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInInit) {
+ SealHandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
+ // Not worth creating a macro atm as this function should be removed.
+ if (!args[0]->IsJSReceiver() || !args[1]->IsObject()) {
+ Object* error = isolate->ThrowIllegalOperation();
+ return MakePair(error, isolate->heap()->undefined_value());
+ }
+ Handle<JSReceiver> object = args.at<JSReceiver>(0);
+ Handle<Object> cache_type = args.at<Object>(1);
+ if (cache_type->IsMap()) {
+ // Enum cache case.
+ if (Map::EnumLengthBits::decode(Map::cast(*cache_type)->bit_field3()) ==
+ 0) {
+ // 0 length enum.
+ // Can't handle this case in the graph builder,
+ // so transform it into the empty fixed array case.
+ return MakePair(isolate->heap()->empty_fixed_array(), Smi::FromInt(1));
+ }
+ return MakePair(object->map()->instance_descriptors()->GetEnumCache(),
+ *cache_type);
+ } else {
+ // FixedArray case.
+ Smi* new_cache_type = Smi::FromInt(object->IsJSProxy() ? 0 : 1);
+ return MakePair(*Handle<FixedArray>::cast(cache_type), new_cache_type);
+ }
+}
-#define F(name, number_of_args, result_size) \
- { Runtime::k##name, Runtime::RUNTIME, #name, \
- FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
+// TODO(dcarney): remove this function when TurboFan supports it.
+RUNTIME_FUNCTION(Runtime_ForInCacheArrayLength) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, array, 1);
+ int length = 0;
+ if (cache_type->IsMap()) {
+ length = Map::cast(*cache_type)->EnumLength();
+ } else {
+ DCHECK(cache_type->IsSmi());
+ length = array->length();
+ }
+ return Smi::FromInt(length);
+}
+
+
+// TODO(dcarney): remove this function when TurboFan supports it.
+// Takes (the object to be iterated over,
+// cache_array from ForInInit,
+// cache_type from ForInInit,
+// the current index)
+// Returns pair (array[index], needs_filtering).
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
+ SealHandleScope scope(isolate);
+ DCHECK(args.length() == 4);
+ int32_t index;
+ // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
+ // Not worth creating a macro atm as this function should be removed.
+ if (!args[0]->IsJSReceiver() || !args[1]->IsFixedArray() ||
+ !args[2]->IsObject() || !args[3]->ToInt32(&index)) {
+ Object* error = isolate->ThrowIllegalOperation();
+ return MakePair(error, isolate->heap()->undefined_value());
+ }
+ Handle<JSReceiver> object = args.at<JSReceiver>(0);
+ Handle<FixedArray> array = args.at<FixedArray>(1);
+ Handle<Object> cache_type = args.at<Object>(2);
+ // Figure out first if a slow check is needed for this object.
+ bool slow_check_needed = false;
+ if (cache_type->IsMap()) {
+ if (object->map() != Map::cast(*cache_type)) {
+ // Object transitioned. Need slow check.
+ slow_check_needed = true;
+ }
+ } else {
+ // No slow check needed for proxies.
+ slow_check_needed = Smi::cast(*cache_type)->value() == 1;
+ }
+ return MakePair(array->get(index),
+ isolate->heap()->ToBoolean(slow_check_needed));
+}
-#define FH(name, number_of_args, result_size) \
- { Runtime::kHidden##name, Runtime::RUNTIME_HIDDEN, NULL, \
- FUNCTION_ADDR(RuntimeHidden_##name), number_of_args, result_size },
+template<typename T, int Bytes>
+inline static bool SimdTypeLoadValue(
+ Isolate* isolate,
+ Handle<JSArrayBuffer> buffer,
+ Handle<Object> byte_offset_obj,
+ T* result) {
+ size_t byte_offset = 0;
+ if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+ return false;
+ }
-#define I(name, number_of_args, result_size) \
- { Runtime::kInline##name, Runtime::INLINE, \
- "_" #name, NULL, number_of_args, result_size },
+ size_t buffer_byte_length =
+ NumberToSize(isolate, buffer->byte_length());
+ if (byte_offset + Bytes > buffer_byte_length) { // overflow
+ return false;
+ }
+ union Value {
+ T data;
+ uint8_t bytes[sizeof(T)];
+ };
-#define IO(name, number_of_args, result_size) \
- { Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, \
- "_" #name, FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
+ Value value;
+ memset(value.bytes, 0, sizeof(T));
+ uint8_t* source =
+ static_cast<uint8_t*>(buffer->backing_store()) + byte_offset;
+ DCHECK(Bytes <= sizeof(T));
+ CopyBytes<Bytes>(value.bytes, source);
+ *result = value.data;
+ return true;
+}
-static const Runtime::Function kIntrinsicFunctions[] = {
- RUNTIME_FUNCTION_LIST(F)
- INLINE_OPTIMIZED_FUNCTION_LIST(F)
- RUNTIME_HIDDEN_FUNCTION_LIST(FH)
- INLINE_FUNCTION_LIST(I)
- INLINE_OPTIMIZED_FUNCTION_LIST(IO)
-};
+template<typename T, int Bytes>
+static bool SimdTypeStoreValue(
+ Isolate* isolate,
+ Handle<JSArrayBuffer> buffer,
+ Handle<Object> byte_offset_obj,
+ T data) {
+ size_t byte_offset = 0;
+ if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+ return false;
+ }
-#undef IO
-#undef I
-#undef FH
-#undef F
+ size_t buffer_byte_length =
+ NumberToSize(isolate, buffer->byte_length());
+ if (byte_offset + Bytes > buffer_byte_length) { // overflow
+ return false;
+ }
+ union Value {
+ T data;
+ uint8_t bytes[sizeof(T)];
+ };
-void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
- Handle<NameDictionary> dict) {
- ASSERT(dict->NumberOfElements() == 0);
+ Value value;
+ value.data = data;
+
+ uint8_t* target =
+ static_cast<uint8_t*>(buffer->backing_store()) + byte_offset;
+ DCHECK(Bytes <= sizeof(T));
+ CopyBytes<Bytes>(target, value.bytes);
+ return true;
+}
+
+
+#define SIMD128_LOAD_RUNTIME_FUNCTION(Type, ValueType, Lanes, Bytes) \
+RUNTIME_FUNCTION(Runtime_##Type##Load##Lanes) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 2); \
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0); \
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
+ ValueType result; \
+ if (SimdTypeLoadValue<ValueType, Bytes>( \
+ isolate, buffer, offset, &result)) { \
+ return *isolate->factory()->New##Type(result); \
+ } else { \
+ THROW_NEW_ERROR_RETURN_FAILURE( \
+ isolate, NewRangeError("invalid_offset", \
+ HandleVector<Object>(NULL, 0))); \
+ } \
+}
+
+
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZW, 16)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZ, 12)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XY, 8)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, X, 4)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, XY, 16)
+SIMD128_LOAD_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, X, 8)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZW, 16)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZ, 12)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XY, 8)
+SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, X, 4)
+
+
+#define SIMD128_STORE_RUNTIME_FUNCTION(Type, ValueType, Lanes, Bytes) \
+RUNTIME_FUNCTION(Runtime_##Type##Store##Lanes) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 3); \
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0); \
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
+ CONVERT_ARG_CHECKED(Type, value, 2); \
+ ValueType v = value->get(); \
+ if (SimdTypeStoreValue<ValueType, Bytes>(isolate, buffer, offset, v)) { \
+ return isolate->heap()->undefined_value(); \
+ } else { \
+ THROW_NEW_ERROR_RETURN_FAILURE( \
+ isolate, NewRangeError("invalid_offset", \
+ HandleVector<Object>(NULL, 0))); \
+ } \
+}
+
+
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZW, 16)
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZ, 12)
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XY, 8)
+SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, X, 4)
+SIMD128_STORE_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, XY, 16)
+SIMD128_STORE_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, X, 8)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZW, 16)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZ, 12)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XY, 8)
+SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, X, 4)
+
+
+#define RETURN_Float32x4_RESULT(value) \
+ return *isolate->factory()->NewFloat32x4(value);
+
+
+#define RETURN_Float64x2_RESULT(value) \
+ return *isolate->factory()->NewFloat64x2(value);
+
+
+#define RETURN_Int32x4_RESULT(value) \
+ return *isolate->factory()->NewInt32x4(value);
+
+
+RUNTIME_FUNCTION(Runtime_CreateFloat32x4) {
HandleScope scope(isolate);
- for (int i = 0; i < kNumFunctions; ++i) {
- const char* name = kIntrinsicFunctions[i].name;
- if (name == NULL) continue;
- Handle<NameDictionary> new_dict = NameDictionary::Add(
- dict,
- isolate->factory()->InternalizeUtf8String(name),
- Handle<Smi>(Smi::FromInt(i), isolate),
- PropertyDetails(NONE, NORMAL, Representation::None()));
- // The dictionary does not need to grow.
- CHECK(new_dict.is_identical_to(dict));
- }
+ DCHECK(args.length() == 4);
+ RUNTIME_ASSERT(args[0]->IsNumber());
+ RUNTIME_ASSERT(args[1]->IsNumber());
+ RUNTIME_ASSERT(args[2]->IsNumber());
+ RUNTIME_ASSERT(args[3]->IsNumber());
+
+ float32x4_value_t value;
+ value.storage[0] = static_cast<float>(args.number_at(0));
+ value.storage[1] = static_cast<float>(args.number_at(1));
+ value.storage[2] = static_cast<float>(args.number_at(2));
+ value.storage[3] = static_cast<float>(args.number_at(3));
+
+ RETURN_Float32x4_RESULT(value);
}
-const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
- Heap* heap = name->GetHeap();
- int entry = heap->intrinsic_function_names()->FindEntry(name);
- if (entry != kNotFound) {
- Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
- int function_index = Smi::cast(smi_index)->value();
- return &(kIntrinsicFunctions[function_index]);
+RUNTIME_FUNCTION(Runtime_CreateFloat64x2) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ RUNTIME_ASSERT(args[0]->IsNumber());
+ RUNTIME_ASSERT(args[1]->IsNumber());
+
+ float64x2_value_t value;
+ value.storage[0] = args.number_at(0);
+ value.storage[1] = args.number_at(1);
+
+ RETURN_Float64x2_RESULT(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateInt32x4) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 4);
+ RUNTIME_ASSERT(args[0]->IsNumber());
+ RUNTIME_ASSERT(args[1]->IsNumber());
+ RUNTIME_ASSERT(args[2]->IsNumber());
+ RUNTIME_ASSERT(args[3]->IsNumber());
+
+ int32x4_value_t value;
+ value.storage[0] = NumberToInt32(args[0]);
+ value.storage[1] = NumberToInt32(args[1]);
+ value.storage[2] = NumberToInt32(args[2]);
+ value.storage[3] = NumberToInt32(args[3]);
+
+ RETURN_Int32x4_RESULT(value);
+}
+
+
+// Used to convert between uint32_t and float32 without breaking strict
+// aliasing rules.
+union float32_uint32 {
+ float f;
+ uint32_t u;
+ float32_uint32(float v) {
+ f = v;
+ }
+ float32_uint32(uint32_t v) {
+ u = v;
+ }
+};
+
+
+union float64_uint64 {
+ double f;
+ uint64_t u;
+ float64_uint64(double v) {
+ f = v;
+ }
+ float64_uint64(uint64_t v) {
+ u = v;
+ }
+};
+
+
+RUNTIME_FUNCTION(Runtime_Float32x4GetSignMask) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Float32x4, self, 0);
+ float32_uint32 x(self->x());
+ float32_uint32 y(self->y());
+ float32_uint32 z(self->z());
+ float32_uint32 w(self->w());
+ uint32_t mx = (x.u & 0x80000000) >> 31;
+ uint32_t my = (y.u & 0x80000000) >> 31;
+ uint32_t mz = (z.u & 0x80000000) >> 31;
+ uint32_t mw = (w.u & 0x80000000) >> 31;
+ uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
+ return *isolate->factory()->NewNumberFromUint(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Float64x2GetSignMask) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Float64x2, self, 0);
+ float64_uint64 x(self->x());
+ float64_uint64 y(self->y());
+ uint64_t mx = x.u >> 63;
+ uint64_t my = y.u >> 63;
+ uint32_t value = uint32_t(mx | (my << 1));
+ return *isolate->factory()->NewNumberFromUint(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Int32x4GetSignMask) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Int32x4, self, 0);
+ uint32_t mx = (self->x() & 0x80000000) >> 31;
+ uint32_t my = (self->y() & 0x80000000) >> 31;
+ uint32_t mz = (self->z() & 0x80000000) >> 31;
+ uint32_t mw = (self->w() & 0x80000000) >> 31;
+ uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
+ return *isolate->factory()->NewNumberFromUint(value);
+}
+
+
+#define LANE_VALUE(VALUE, LANE) \
+ VALUE->LANE()
+
+
+#define LANE_FLAG(VALUE, LANE) \
+ VALUE->LANE() != 0
+
+
+#define SIMD128_LANE_ACCESS_FUNCTIONS(V) \
+ V(Float32x4, GetX, NewNumber, x, LANE_VALUE) \
+ V(Float32x4, GetY, NewNumber, y, LANE_VALUE) \
+ V(Float32x4, GetZ, NewNumber, z, LANE_VALUE) \
+ V(Float32x4, GetW, NewNumber, w, LANE_VALUE) \
+ V(Float64x2, GetX, NewNumber, x, LANE_VALUE) \
+ V(Float64x2, GetY, NewNumber, y, LANE_VALUE) \
+ V(Int32x4, GetX, NewNumberFromInt, x, LANE_VALUE) \
+ V(Int32x4, GetY, NewNumberFromInt, y, LANE_VALUE) \
+ V(Int32x4, GetZ, NewNumberFromInt, z, LANE_VALUE) \
+ V(Int32x4, GetW, NewNumberFromInt, w, LANE_VALUE) \
+ V(Int32x4, GetFlagX, ToBoolean, x, LANE_FLAG) \
+ V(Int32x4, GetFlagY, ToBoolean, y, LANE_FLAG) \
+ V(Int32x4, GetFlagZ, ToBoolean, z, LANE_FLAG) \
+ V(Int32x4, GetFlagW, ToBoolean, w, LANE_FLAG)
+
+
+#define DECLARE_SIMD_LANE_ACCESS_FUNCTION( \
+ TYPE, NAME, HEAP_FUNCTION, LANE, ACCESS_FUNCTION) \
+RUNTIME_FUNCTION(Runtime_##TYPE##NAME) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 1); \
+ \
+ CONVERT_ARG_CHECKED(TYPE, a, 0); \
+ \
+ return *isolate->factory()->HEAP_FUNCTION( \
+ ACCESS_FUNCTION(a, LANE)); \
+}
+
+
+SIMD128_LANE_ACCESS_FUNCTIONS(DECLARE_SIMD_LANE_ACCESS_FUNCTION)
+
+
+template<typename T>
+static inline T Neg(T a) {
+ return -a;
+}
+
+
+template<typename T>
+static inline T Not(T a) {
+ return ~a;
+}
+
+
+template<typename T>
+static inline T Reciprocal(T a) {
+ UNIMPLEMENTED();
+}
+
+
+template<>
+inline float Reciprocal<float>(float a) {
+ return 1.0f / a;
+}
+
+
+template<typename T>
+static inline T ReciprocalSqrt(T a) {
+ UNIMPLEMENTED();
+}
+
+
+template<>
+inline float ReciprocalSqrt<float>(float a) {
+ return sqrtf(1.0f / a);
+}
+
+
+template<typename T>
+static inline T Sqrt(T a) {
+ UNIMPLEMENTED();
+}
+
+
+template<>
+inline float Sqrt<float>(float a) {
+ return sqrtf(a);
+}
+
+
+template<>
+inline double Sqrt<double>(double a) {
+ return sqrt(a);
+}
+
+
+#define SIMD128_UNARY_FUNCTIONS(V) \
+ V(Float32x4, Abs) \
+ V(Float32x4, Neg) \
+ V(Float32x4, Reciprocal) \
+ V(Float32x4, ReciprocalSqrt) \
+ V(Float32x4, Sqrt) \
+ V(Float64x2, Abs) \
+ V(Float64x2, Neg) \
+ V(Float64x2, Sqrt) \
+ V(Int32x4, Neg) \
+ V(Int32x4, Not)
+
+
+#define DECLARE_SIMD_UNARY_FUNCTION(TYPE, FUNCTION) \
+RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 1); \
+ \
+ CONVERT_ARG_CHECKED(TYPE, a, 0); \
+ \
+ TYPE::value_t result; \
+ for (int i = 0; i < TYPE::kLanes; i++) { \
+ result.storage[i] = FUNCTION(a->getAt(i)); \
+ } \
+ \
+ RETURN_##TYPE##_RESULT(result); \
+}
+
+
+SIMD128_UNARY_FUNCTIONS(DECLARE_SIMD_UNARY_FUNCTION)
+
+
+template<typename T1, typename T2>
+inline void BitsTo(T1 s, T2* t) {
+ memcpy(t, &s, sizeof(T2));
+}
+
+
+template<typename T1, typename T2>
+inline void To(T1 s, T2* t) {
+}
+
+
+template<>
+inline void To<int32_t, float>(int32_t s, float* t) {
+ *t = static_cast<float>(s);
+}
+
+
+template<>
+inline void To<float, int32_t>(float s, int32_t* t) {
+ *t = DoubleToInt32(static_cast<double>(s));
+}
+
+
+#define SIMD128_CONVERSION_FUNCTIONS(V) \
+ V(Float32x4, BitsTo, Int32x4) \
+ V(Float32x4, To, Int32x4) \
+ V(Int32x4, BitsTo, Float32x4) \
+ V(Int32x4, To, Float32x4)
+
+
+#define DECLARE_SIMD_CONVERSION_FUNCTION( \
+ SOURCE_TYPE, FUNCTION, TARGET_TYPE) \
+RUNTIME_FUNCTION( \
+ Runtime_##SOURCE_TYPE##FUNCTION##TARGET_TYPE) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 1); \
+ \
+ CONVERT_ARG_CHECKED(SOURCE_TYPE, a, 0); \
+ \
+ TARGET_TYPE::value_t result; \
+ for (int i = 0; i < SOURCE_TYPE::kLanes; i++) { \
+ FUNCTION(a->getAt(i), &result.storage[i]); \
+ } \
+ \
+ RETURN_##TARGET_TYPE##_RESULT(result); \
+}
+
+
+SIMD128_CONVERSION_FUNCTIONS(DECLARE_SIMD_CONVERSION_FUNCTION)
+
+
+template<typename T>
+static inline T Add(T a, T b) {
+ return a + b;
+}
+
+
+template<typename T>
+static inline T Div(T a, T b) {
+ return a / b;
+}
+
+
+template<typename T>
+static inline T Mul(T a, T b) {
+ return a * b;
+}
+
+
+template<typename T>
+static inline T Sub(T a, T b) {
+ return a - b;
+}
+
+
+template<typename T>
+static inline int32_t Equal(T a, T b) {
+ return a == b ? -1 : 0;
+}
+
+
+template<typename T>
+static inline int32_t NotEqual(T a, T b) {
+ return a != b ? -1 : 0;
+}
+
+
+template<typename T>
+static inline int32_t GreaterThanOrEqual(T a, T b) {
+ return a >= b ? -1 : 0;
+}
+
+
+template<typename T>
+static inline int32_t GreaterThan(T a, T b) {
+ return a > b ? -1 : 0;
+}
+
+
+template<typename T>
+static inline int32_t LessThan(T a, T b) {
+ return a < b ? -1 : 0;
+}
+
+
+template<typename T>
+static inline int32_t LessThanOrEqual(T a, T b) {
+ return a <= b ? -1 : 0;
+}
+
+
+template<typename T>
+static inline T And(T a, T b) {
+ return a & b;
+}
+
+
+template<typename T>
+static inline T Or(T a, T b) {
+ return a | b;
+}
+
+
+template<typename T>
+static inline T Xor(T a, T b) {
+ return a ^ b;
+}
+
+
+#define SIMD128_BINARY_FUNCTIONS(V) \
+ V(Float32x4, Add, Float32x4) \
+ V(Float32x4, Div, Float32x4) \
+ V(Float32x4, Max, Float32x4) \
+ V(Float32x4, Min, Float32x4) \
+ V(Float32x4, Mul, Float32x4) \
+ V(Float32x4, Sub, Float32x4) \
+ V(Float32x4, Equal, Int32x4) \
+ V(Float32x4, NotEqual, Int32x4) \
+ V(Float32x4, GreaterThanOrEqual, Int32x4) \
+ V(Float32x4, GreaterThan, Int32x4) \
+ V(Float32x4, LessThan, Int32x4) \
+ V(Float32x4, LessThanOrEqual, Int32x4) \
+ V(Float64x2, Add, Float64x2) \
+ V(Float64x2, Div, Float64x2) \
+ V(Float64x2, Max, Float64x2) \
+ V(Float64x2, Min, Float64x2) \
+ V(Float64x2, Mul, Float64x2) \
+ V(Float64x2, Sub, Float64x2) \
+ V(Int32x4, Add, Int32x4) \
+ V(Int32x4, And, Int32x4) \
+ V(Int32x4, Mul, Int32x4) \
+ V(Int32x4, Or, Int32x4) \
+ V(Int32x4, Sub, Int32x4) \
+ V(Int32x4, Xor, Int32x4) \
+ V(Int32x4, Equal, Int32x4) \
+ V(Int32x4, GreaterThan, Int32x4) \
+ V(Int32x4, LessThan, Int32x4)
+
+
+#define DECLARE_SIMD_BINARY_FUNCTION( \
+ TYPE, FUNCTION, RETURN_TYPE) \
+RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 2); \
+ \
+ CONVERT_ARG_CHECKED(TYPE, a, 0); \
+ CONVERT_ARG_CHECKED(TYPE, b, 1); \
+ \
+ RETURN_TYPE::value_t result; \
+ for (int i = 0; i < TYPE::kLanes; i++) { \
+ result.storage[i] = FUNCTION(a->getAt(i), b->getAt(i)); \
+ } \
+ \
+ RETURN_##RETURN_TYPE##_RESULT(result); \
+}
+
+
+SIMD128_BINARY_FUNCTIONS(DECLARE_SIMD_BINARY_FUNCTION)
+
+
+#define SIMD128_SHUFFLE_FUNCTIONS(V) \
+ V(Float32x4) \
+ V(Int32x4)
+
+
+#define DECLARE_SIMD_SHUFFLE_FUNCTION(TYPE) \
+RUNTIME_FUNCTION(Runtime_##TYPE##Shuffle) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 2); \
+ \
+ CONVERT_ARG_CHECKED(TYPE, a, 0); \
+ RUNTIME_ASSERT(args[1]->IsNumber()); \
+ uint32_t m = NumberToUint32(args[1]); \
+ \
+ TYPE::value_t result; \
+ for (int i = 0; i < TYPE::kLanes; i++) { \
+ result.storage[i] = a->getAt((m >> (i * 2)) & 0x3); \
+ } \
+ \
+ RETURN_##TYPE##_RESULT(result); \
+}
+
+
+SIMD128_SHUFFLE_FUNCTIONS(DECLARE_SIMD_SHUFFLE_FUNCTION)
+
+
+RUNTIME_FUNCTION(Runtime_Float32x4Scale) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+
+ CONVERT_ARG_CHECKED(Float32x4, self, 0);
+ RUNTIME_ASSERT(args[1]->IsNumber());
+
+ float _s = static_cast<float>(args.number_at(1));
+ float32x4_value_t result;
+ result.storage[0] = self->x() * _s;
+ result.storage[1] = self->y() * _s;
+ result.storage[2] = self->z() * _s;
+ result.storage[3] = self->w() * _s;
+
+ RETURN_Float32x4_RESULT(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Float64x2Scale) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+
+ CONVERT_ARG_CHECKED(Float64x2, self, 0);
+ RUNTIME_ASSERT(args[1]->IsNumber());
+
+ double _s = args.number_at(1);
+ float64x2_value_t result;
+ result.storage[0] = self->x() * _s;
+ result.storage[1] = self->y() * _s;
+
+ RETURN_Float64x2_RESULT(result);
+}
+
+
+#define ARG_TO_FLOAT32(x) \
+ CONVERT_DOUBLE_ARG_CHECKED(t, 1); \
+ float x = static_cast<float>(t);
+
+
+#define ARG_TO_FLOAT64(x) \
+ CONVERT_DOUBLE_ARG_CHECKED(x, 1); \
+
+
+#define ARG_TO_INT32(x) \
+ RUNTIME_ASSERT(args[1]->IsNumber()); \
+ int32_t x = NumberToInt32(args[1]);
+
+
+#define ARG_TO_BOOLEAN(x) \
+ CONVERT_BOOLEAN_ARG_CHECKED(flag, 1); \
+ int32_t x = flag ? -1 : 0;
+
+#define SIMD128_SET_LANE_FUNCTIONS(V) \
+ V(Float32x4, WithX, ARG_TO_FLOAT32, 0) \
+ V(Float32x4, WithY, ARG_TO_FLOAT32, 1) \
+ V(Float32x4, WithZ, ARG_TO_FLOAT32, 2) \
+ V(Float32x4, WithW, ARG_TO_FLOAT32, 3) \
+ V(Float64x2, WithX, ARG_TO_FLOAT64, 0) \
+ V(Float64x2, WithY, ARG_TO_FLOAT64, 1) \
+ V(Int32x4, WithX, ARG_TO_INT32, 0) \
+ V(Int32x4, WithY, ARG_TO_INT32, 1) \
+ V(Int32x4, WithZ, ARG_TO_INT32, 2) \
+ V(Int32x4, WithW, ARG_TO_INT32, 3) \
+ V(Int32x4, WithFlagX, ARG_TO_BOOLEAN, 0) \
+ V(Int32x4, WithFlagY, ARG_TO_BOOLEAN, 1) \
+ V(Int32x4, WithFlagZ, ARG_TO_BOOLEAN, 2) \
+ V(Int32x4, WithFlagW, ARG_TO_BOOLEAN, 3)
+
+
+#define DECLARE_SIMD_SET_LANE_FUNCTION( \
+ TYPE, NAME, ARG_FUNCTION, LANE) \
+RUNTIME_FUNCTION(Runtime_##TYPE##NAME) { \
+ HandleScope scope(isolate); \
+ DCHECK(args.length() == 2); \
+ \
+ CONVERT_ARG_CHECKED(TYPE, a, 0); \
+ ARG_FUNCTION(value); \
+ \
+ TYPE::value_t result; \
+ for (int i = 0; i < TYPE::kLanes; i++) { \
+ if (i != LANE) \
+ result.storage[i] = a->getAt(i); \
+ else \
+ result.storage[i] = value; \
+ } \
+ \
+ RETURN_##TYPE##_RESULT(result); \
+}
+
+
+SIMD128_SET_LANE_FUNCTIONS(DECLARE_SIMD_SET_LANE_FUNCTION)
+
+
+RUNTIME_FUNCTION(Runtime_Float32x4Clamp) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_CHECKED(Float32x4, self, 0);
+ CONVERT_ARG_CHECKED(Float32x4, lo, 1);
+ CONVERT_ARG_CHECKED(Float32x4, hi, 2);
+
+ float32x4_value_t result;
+ float _x = self->x() > lo->x() ? self->x() : lo->x();
+ float _y = self->y() > lo->y() ? self->y() : lo->y();
+ float _z = self->z() > lo->z() ? self->z() : lo->z();
+ float _w = self->w() > lo->w() ? self->w() : lo->w();
+ result.storage[0] = _x > hi->x() ? hi->x() : _x;
+ result.storage[1] = _y > hi->y() ? hi->y() : _y;
+ result.storage[2] = _z > hi->z() ? hi->z() : _z;
+ result.storage[3] = _w > hi->w() ? hi->w() : _w;
+
+ RETURN_Float32x4_RESULT(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Float64x2Clamp) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_CHECKED(Float64x2, self, 0);
+ CONVERT_ARG_CHECKED(Float64x2, lo, 1);
+ CONVERT_ARG_CHECKED(Float64x2, hi, 2);
+
+ float64x2_value_t result;
+ double _x = self->x() > lo->x() ? self->x() : lo->x();
+ double _y = self->y() > lo->y() ? self->y() : lo->y();
+ result.storage[0] = _x > hi->x() ? hi->x() : _x;
+ result.storage[1] = _y > hi->y() ? hi->y() : _y;
+
+ RETURN_Float64x2_RESULT(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Float32x4ShuffleMix) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_CHECKED(Float32x4, first, 0);
+ CONVERT_ARG_CHECKED(Float32x4, second, 1);
+ RUNTIME_ASSERT(args[2]->IsNumber());
+
+ uint32_t m = NumberToUint32(args[2]);
+ float32x4_value_t result;
+ float data1[4] = { first->x(), first->y(), first->z(), first->w() };
+ float data2[4] = { second->x(), second->y(), second->z(), second->w() };
+ result.storage[0] = data1[m & 0x3];
+ result.storage[1] = data1[(m >> 2) & 0x3];
+ result.storage[2] = data2[(m >> 4) & 0x3];
+ result.storage[3] = data2[(m >> 6) & 0x3];
+
+ RETURN_Float32x4_RESULT(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Float32x4Select) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_CHECKED(Int32x4, self, 0);
+ CONVERT_ARG_CHECKED(Float32x4, tv, 1);
+ CONVERT_ARG_CHECKED(Float32x4, fv, 2);
+
+ uint32_t _maskX = self->x();
+ uint32_t _maskY = self->y();
+ uint32_t _maskZ = self->z();
+ uint32_t _maskW = self->w();
+ // Extract floats and interpret them as masks.
+ float32_uint32 tvx(tv->x());
+ float32_uint32 tvy(tv->y());
+ float32_uint32 tvz(tv->z());
+ float32_uint32 tvw(tv->w());
+ float32_uint32 fvx(fv->x());
+ float32_uint32 fvy(fv->y());
+ float32_uint32 fvz(fv->z());
+ float32_uint32 fvw(fv->w());
+ // Perform select.
+ float32_uint32 tempX((_maskX & tvx.u) | (~_maskX & fvx.u));
+ float32_uint32 tempY((_maskY & tvy.u) | (~_maskY & fvy.u));
+ float32_uint32 tempZ((_maskZ & tvz.u) | (~_maskZ & fvz.u));
+ float32_uint32 tempW((_maskW & tvw.u) | (~_maskW & fvw.u));
+
+ float32x4_value_t result;
+ result.storage[0] = tempX.f;
+ result.storage[1] = tempY.f;
+ result.storage[2] = tempZ.f;
+ result.storage[3] = tempW.f;
+
+ RETURN_Float32x4_RESULT(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_Int32x4Select) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_CHECKED(Int32x4, self, 0);
+ CONVERT_ARG_CHECKED(Int32x4, tv, 1);
+ CONVERT_ARG_CHECKED(Int32x4, fv, 2);
+
+ uint32_t _maskX = self->x();
+ uint32_t _maskY = self->y();
+ uint32_t _maskZ = self->z();
+ uint32_t _maskW = self->w();
+
+ int32x4_value_t result;
+ result.storage[0] = (_maskX & tv->x()) | (~_maskX & fv->x());
+ result.storage[1] = (_maskY & tv->y()) | (~_maskY & fv->y());
+ result.storage[2] = (_maskZ & tv->z()) | (~_maskZ & fv->z());
+ result.storage[3] = (_maskW & tv->w()) | (~_maskW & fv->w());
+
+ RETURN_Int32x4_RESULT(result);
+}
+
+
+// ----------------------------------------------------------------------------
+// Reference implementation for inlined runtime functions. Only used when the
+// compiler does not support a certain intrinsic. Don't optimize these, but
+// implement the intrinsic in the respective compiler instead.
+
+// TODO(mstarzinger): These are place-holder stubs for TurboFan and will
+// eventually all have a C++ implementation and this macro will be gone.
+#define U(name) \
+ RUNTIME_FUNCTION(RuntimeReference_##name) { \
+ UNIMPLEMENTED(); \
+ return NULL; \
+ }
+
+U(IsStringWrapperSafeForDefaultValueOf)
+U(DebugBreakInOptimizedCode)
+
+#undef U
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsSmi) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsSmi());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsSmi() &&
+ Smi::cast(obj)->value() >= 0);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsArray) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsJSArray());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsRegExp) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsJSRegExp());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 0);
+ JavaScriptFrameIterator it(isolate);
+ JavaScriptFrame* frame = it.frame();
+ return isolate->heap()->ToBoolean(frame->IsConstructor());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_CallFunction) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_Call(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 0);
+ JavaScriptFrameIterator it(isolate);
+ JavaScriptFrame* frame = it.frame();
+ return Smi::FromInt(frame->GetArgumentsLength());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_Arguments) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_GetArgumentsProperty(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ValueOf) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ if (!obj->IsJSValue()) return obj;
+ return JSValue::cast(obj)->value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_SetValueOf) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ CONVERT_ARG_CHECKED(Object, value, 1);
+ if (!obj->IsJSValue()) return value;
+ JSValue::cast(obj)->set_value(value);
+ return value;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_DateField) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ CONVERT_SMI_ARG_CHECKED(index, 1);
+ if (!obj->IsJSDate()) {
+ HandleScope scope(isolate);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
+ }
+ JSDate* date = JSDate::cast(obj);
+ if (index == 0) return date->value();
+ return JSDate::GetField(date, Smi::FromInt(index));
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_CharFromCode(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCharAt) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ if (!args[0]->IsString()) return Smi::FromInt(0);
+ if (!args[1]->IsNumber()) return Smi::FromInt(0);
+ if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string();
+ Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
+ if (code->IsNaN()) return isolate->heap()->empty_string();
+ return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_OneByteSeqStringSetChar) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_INT32_ARG_CHECKED(index, 0);
+ CONVERT_INT32_ARG_CHECKED(value, 1);
+ CONVERT_ARG_CHECKED(SeqOneByteString, string, 2);
+ string->SeqOneByteStringSet(index, value);
+ return string;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_TwoByteSeqStringSetChar) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 3);
+ CONVERT_INT32_ARG_CHECKED(index, 0);
+ CONVERT_INT32_ARG_CHECKED(value, 1);
+ CONVERT_ARG_CHECKED(SeqTwoByteString, string, 2);
+ string->SeqTwoByteStringSet(index, value);
+ return string;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_CHECKED(Object, obj1, 0);
+ CONVERT_ARG_CHECKED(Object, obj2, 1);
+ return isolate->heap()->ToBoolean(obj1 == obj2);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsObject) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ if (!obj->IsHeapObject()) return isolate->heap()->false_value();
+ if (obj->IsNull()) return isolate->heap()->true_value();
+ if (obj->IsUndetectableObject()) return isolate->heap()->false_value();
+ Map* map = HeapObject::cast(obj)->map();
+ bool is_non_callable_spec_object =
+ map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
+ map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE;
+ return isolate->heap()->ToBoolean(is_non_callable_spec_object);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsFunction) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsJSFunction());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsUndetectableObject());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsSpecObject());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_MathPow) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_MathPowSlow(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
+ HeapNumber* number = HeapNumber::cast(obj);
+ return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ return isolate->heap()->false_value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GeneratorNext) {
+ UNREACHABLE(); // Optimization disabled in SetUpGenerators().
+ return NULL;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GeneratorThrow) {
+ UNREACHABLE(); // Optimization disabled in SetUpGenerators().
+ return NULL;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
+ return JSReceiver::cast(obj)->class_name();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCharCodeAt) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ if (!args[0]->IsString()) return isolate->heap()->undefined_value();
+ if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
+ if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
+ return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringAdd) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_StringAdd(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_SubString) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_SubString(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCompare) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_StringCompare(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_RegExpExec) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_RegExpExecRT(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_RegExpConstructResult) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_SMI_ARG_CHECKED(id, 0);
+ args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
+ return __RT_impl_Runtime_GetFromCache(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
+ SealHandleScope shs(isolate);
+ return __RT_impl_Runtime_NumberToStringRT(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
+ SealHandleScope shs(isolate);
+ return Smi::FromInt(isolate->debug()->is_active());
+}
+
+
+// ----------------------------------------------------------------------------
+// Implementation of Runtime
+
+#define F(name, number_of_args, result_size) \
+ { \
+ Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
+ number_of_args, result_size \
+ } \
+ ,
+
+
+#define I(name, number_of_args, result_size) \
+ { \
+ Runtime::kInline##name, Runtime::INLINE, "_" #name, \
+ FUNCTION_ADDR(RuntimeReference_##name), number_of_args, result_size \
+ } \
+ ,
+
+
+#define IO(name, number_of_args, result_size) \
+ { \
+ Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \
+ FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \
+ } \
+ ,
+
+
+static const Runtime::Function kIntrinsicFunctions[] = {
+ RUNTIME_FUNCTION_LIST(F)
+ INLINE_OPTIMIZED_FUNCTION_LIST(F)
+ INLINE_FUNCTION_LIST(I)
+ INLINE_OPTIMIZED_FUNCTION_LIST(IO)
+};
+
+#undef IO
+#undef I
+#undef F
+
+
+void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
+ Handle<NameDictionary> dict) {
+ DCHECK(dict->NumberOfElements() == 0);
+ HandleScope scope(isolate);
+ for (int i = 0; i < kNumFunctions; ++i) {
+ const char* name = kIntrinsicFunctions[i].name;
+ if (name == NULL) continue;
+ Handle<NameDictionary> new_dict = NameDictionary::Add(
+ dict,
+ isolate->factory()->InternalizeUtf8String(name),
+ Handle<Smi>(Smi::FromInt(i), isolate),
+ PropertyDetails(NONE, NORMAL, Representation::None()));
+ // The dictionary does not need to grow.
+ CHECK(new_dict.is_identical_to(dict));
+ }
+}
+
+
+const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
+ Heap* heap = name->GetHeap();
+ int entry = heap->intrinsic_function_names()->FindEntry(name);
+ if (entry != kNotFound) {
+ Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
+ int function_index = Smi::cast(smi_index)->value();
+ return &(kIntrinsicFunctions[function_index]);
+ }
+ return NULL;
+}
+
+
+const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
+ for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
+ if (entry == kIntrinsicFunctions[i].entry) {
+ return &(kIntrinsicFunctions[i]);
+ }
}
return NULL;
}