summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime.cc
diff options
context:
space:
mode:
authorTimothy J Fontaine <tjfontaine@gmail.com>2013-10-22 15:14:25 -0700
committerTimothy J Fontaine <tjfontaine@gmail.com>2013-10-23 09:17:31 -0700
commita53c763c16eeabb0901a05dbcf38a72fa96d2f26 (patch)
tree309bf250e1521cedf0e945d7a7629db511e64498 /deps/v8/src/runtime.cc
parent54910044b33a6405c72ad085915a55c575c027fc (diff)
downloadnode-a53c763c16eeabb0901a05dbcf38a72fa96d2f26.tar.gz
v8: upgrade 3.21.18.3
Diffstat (limited to 'deps/v8/src/runtime.cc')
-rw-r--r--deps/v8/src/runtime.cc833
1 files changed, 572 insertions, 261 deletions
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index 5b96d1fd4..c09fb1d49 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -80,6 +80,7 @@
#include "unicode/locid.h"
#include "unicode/numfmt.h"
#include "unicode/numsys.h"
+#include "unicode/rbbi.h"
#include "unicode/smpdtfmt.h"
#include "unicode/timezone.h"
#include "unicode/uchar.h"
@@ -289,9 +290,7 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
}
Handle<Object> result;
uint32_t element_index = 0;
- JSReceiver::StoreMode mode = value->IsJSObject()
- ? JSReceiver::FORCE_FIELD
- : JSReceiver::ALLOW_AS_CONSTANT;
+ 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).
@@ -686,10 +685,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
- proxy->Fix();
+ CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
+ JSProxy::Fix(proxy);
return isolate->heap()->undefined_value();
}
@@ -995,7 +994,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
JSArrayBuffer::cast(typed_array->buffer())->backing_store());
size_t source_byte_offset =
NumberToSize(isolate, typed_array->byte_offset());
- OS::MemCopy(
+ memcpy(
buffer->backing_store(),
backing_store + source_byte_offset,
byte_length);
@@ -1663,6 +1662,14 @@ static bool CheckAccessException(Object* callback,
(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;
}
@@ -1944,6 +1951,35 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
}
+// 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());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, 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);
+ 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();
+}
+
+
static Failure* ThrowRedeclarationError(Isolate* isolate,
const char* type,
Handle<String> name) {
@@ -2240,9 +2276,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
LookupResult lookup(isolate);
global->LocalLookup(*name, &lookup);
if (!lookup.IsFound()) {
- return global->SetLocalPropertyIgnoreAttributes(*name,
- *value,
- attributes);
+ HandleScope handle_scope(isolate);
+ Handle<GlobalObject> global(isolate->context()->global_object());
+ RETURN_IF_EMPTY_HANDLE(
+ isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
+ attributes));
+ return *value;
}
if (!lookup.IsReadOnly()) {
@@ -2459,41 +2499,41 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
DisallowHeapAllocation no_allocation;
ASSERT(args.length() == 5);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
- CONVERT_ARG_CHECKED(String, source, 1);
+ 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
// suggested by ECMA-262, 5th, section 15.10.4.1.
- if (source->length() == 0) source = isolate->heap()->query_colon_string();
+ if (source->length() == 0) source = isolate->factory()->query_colon_string();
- Object* global = args[2];
- if (!global->IsTrue()) global = isolate->heap()->false_value();
+ CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
+ if (!global->IsTrue()) global = isolate->factory()->false_value();
- Object* ignoreCase = args[3];
- if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value();
+ CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
+ if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
- Object* multiline = args[4];
- if (!multiline->IsTrue()) multiline = isolate->heap()->false_value();
+ CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
+ if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
Map* map = regexp->map();
Object* constructor = map->constructor();
if (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);
+ regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
// Both true and false are immovable immortal objects so no need for write
// barrier.
regexp->InObjectPropertyAtPut(
- JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER);
+ JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(
- JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER);
+ JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(
- JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER);
+ JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(
JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
- return regexp;
+ return *regexp;
}
// Map has changed, so use generic, but slower, method.
@@ -2501,34 +2541,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
PropertyAttributes writable =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
- Heap* heap = isolate->heap();
- MaybeObject* result;
- result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_string(),
- source,
- final);
- // TODO(jkummerow): Turn these back into ASSERTs when we can be certain
- // that it never fires in Release mode in the wild.
- CHECK(!result->IsFailure());
- result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_string(),
- global,
- final);
- CHECK(!result->IsFailure());
- result =
- regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_string(),
- ignoreCase,
- final);
- CHECK(!result->IsFailure());
- result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_string(),
- multiline,
- final);
- CHECK(!result->IsFailure());
- result =
- regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_string(),
- Smi::FromInt(0),
- writable);
- CHECK(!result->IsFailure());
- USE(result);
- return regexp;
+ Handle<Object> zero(Smi::FromInt(0), isolate);
+ Factory* factory = isolate->factory();
+ CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->source_string(), source, final));
+ CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->global_string(), global, final));
+ CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->ignore_case_string(), ignoreCase, final));
+ CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->multiline_string(), multiline, final));
+ CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->last_index_string(), zero, writable));
+ return *regexp;
}
@@ -2585,8 +2610,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsClassicModeFunction) {
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
bool threw = false;
- Handle<Object> delegate =
- Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
+ Handle<Object> delegate = Execution::TryGetFunctionDelegate(
+ isolate, Handle<JSReceiver>(callable), &threw);
if (threw) return Failure::Exception();
callable = JSFunction::cast(*delegate);
}
@@ -2604,8 +2629,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
bool threw = false;
- Handle<Object> delegate =
- Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
+ Handle<Object> delegate = Execution::TryGetFunctionDelegate(
+ isolate, Handle<JSReceiver>(callable), &threw);
if (threw) return Failure::Exception();
callable = JSFunction::cast(*delegate);
}
@@ -2780,16 +2805,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
ASSERT(fun->should_have_prototype());
- Object* obj;
- { MaybeObject* maybe_obj =
- Accessors::FunctionSetPrototype(fun, args[1], NULL);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ Accessors::FunctionSetPrototype(fun, value);
return args[0]; // return TOS
}
@@ -4689,6 +4711,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsValidSmi) {
+ HandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+
+ CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
+ if (Smi::IsValid(number)) {
+ return isolate->heap()->true_value();
+ } else {
+ return isolate->heap()->false_value();
+ }
+}
+
+
// Returns a single character string where first character equals
// string->Get(index).
static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
@@ -4728,10 +4763,10 @@ MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate,
}
if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- return object->GetPrototype(isolate)->GetElement(index);
+ return object->GetPrototype(isolate)->GetElement(isolate, index);
}
- return object->GetElement(index);
+ return object->GetElement(isolate, index);
}
@@ -4753,7 +4788,7 @@ MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
} else {
bool has_pending_exception = false;
Handle<Object> converted =
- Execution::ToString(key, &has_pending_exception);
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
name = Handle<Name>::cast(converted);
}
@@ -4795,7 +4830,7 @@ MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
} else {
bool has_pending_exception = false;
Handle<Object> converted =
- Execution::ToString(key, &has_pending_exception);
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
name = Handle<Name>::cast(converted);
}
@@ -5018,9 +5053,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
// Use IgnoreAttributes version since a readonly property may be
// overridden and SetProperty does not allow this.
- return js_object->SetLocalPropertyIgnoreAttributes(*name,
- *obj_value,
- attr);
+ Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+ js_object, name, obj_value, attr);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
return Runtime::ForceSetObjectProperty(isolate,
@@ -5093,7 +5129,7 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
if (object->IsJSProxy()) {
bool has_pending_exception = false;
Handle<Object> name = key->IsSymbol()
- ? key : Execution::ToString(key, &has_pending_exception);
+ ? key : Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
return JSProxy::cast(*object)->SetProperty(
Name::cast(*name), *value, attr, strict_mode);
@@ -5122,7 +5158,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
if (js_object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
bool has_exception;
- Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ Handle<Object> number =
+ Execution::ToNumber(isolate, value, &has_exception);
if (has_exception) return Failure::Exception();
value = number;
}
@@ -5141,7 +5178,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
if (js_object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
bool has_exception;
- Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ Handle<Object> number =
+ Execution::ToNumber(isolate, value, &has_exception);
if (has_exception) return Failure::Exception();
value = number;
}
@@ -5158,7 +5196,8 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+ Handle<Object> converted =
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
Handle<String> name = Handle<String>::cast(converted);
@@ -5203,13 +5242,17 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
} else {
if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
- return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
+ Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+ js_object, name, value, attr);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
}
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+ Handle<Object> converted =
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
Handle<String> name = Handle<String>::cast(converted);
@@ -5217,7 +5260,10 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
return js_object->SetElement(
index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
} else {
- return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
+ Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+ js_object, name, value, attr);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
}
@@ -5252,7 +5298,8 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
} else {
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+ Handle<Object> converted = Execution::ToString(
+ isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
name = Handle<String>::cast(converted);
}
@@ -5419,10 +5466,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
// Set a local property, even if it is READ_ONLY. If the property does not
// exist, it will be added with attributes NONE.
RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
- CONVERT_ARG_CHECKED(JSObject, object, 0);
- CONVERT_ARG_CHECKED(Name, name, 1);
+ 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) {
@@ -5432,9 +5480,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
(unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
attributes = static_cast<PropertyAttributes>(unchecked_value);
}
-
- return object->
- SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
+ Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
+ object, name, value, attributes);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
@@ -5844,7 +5893,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
HandleScope scope(isolate);
bool exception = false;
Handle<Object> converted =
- Execution::ToString(args.at<Object>(0), &exception);
+ Execution::ToString(isolate, args.at<Object>(0), &exception);
if (exception) return Failure::Exception();
Handle<String> key = Handle<String>::cast(converted);
@@ -5853,7 +5902,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
if (index < n) {
return frame->GetParameter(index);
} else {
- return isolate->initial_object_prototype()->GetElement(index);
+ return isolate->initial_object_prototype()->GetElement(isolate, index);
}
}
@@ -6500,8 +6549,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
int part_count = indices.length();
Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
- MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements();
- if (maybe_result->IsFailure()) return maybe_result;
+ JSObject::EnsureCanContainHeapObjectElements(result);
result->set_length(Smi::FromInt(part_count));
ASSERT(result->HasFastObjectElements());
@@ -6628,7 +6676,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(String, value, 0);
- return value->ToObject();
+ return value->ToObject(isolate);
}
@@ -6894,21 +6942,20 @@ static inline void StringBuilderConcatHelper(String* special,
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSArray, array, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
if (!args[1]->IsSmi()) {
isolate->context()->mark_out_of_memory();
return Failure::OutOfMemoryException(0x14);
}
int array_length = args.smi_at(1);
- CONVERT_ARG_CHECKED(String, special, 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
// This assumption is used by the slice encoding in one or two smis.
ASSERT(Smi::kMaxValue >= String::kMaxLength);
- MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements();
- if (maybe_result->IsFailure()) return maybe_result;
+ JSObject::EnsureCanContainHeapObjectElements(array);
int special_length = special->length();
if (!array->HasFastObjectElements()) {
@@ -6990,7 +7037,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
if (!maybe_object->ToObject(&object)) return maybe_object;
}
SeqOneByteString* answer = SeqOneByteString::cast(object);
- StringBuilderConcatHelper(special,
+ StringBuilderConcatHelper(*special,
answer->GetChars(),
fixed_array,
array_length);
@@ -7001,7 +7048,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
if (!maybe_object->ToObject(&object)) return maybe_object;
}
SeqTwoByteString* answer = SeqTwoByteString::cast(object);
- StringBuilderConcatHelper(special,
+ StringBuilderConcatHelper(*special,
answer->GetChars(),
fixed_array,
array_length);
@@ -7477,7 +7524,7 @@ static Object* FlatStringCompare(String* x, String* y) {
result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
}
ASSERT(result ==
- StringCharacterStreamCompare(Isolate::Current()->runtime_state(), x, y));
+ StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y));
return result;
}
@@ -7918,6 +7965,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosureFromStubFailure) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
+ Handle<Context> context(isolate->context());
+ PretenureFlag pretenure_flag = NOT_TENURED;
+ Handle<JSFunction> result =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
+ context,
+ pretenure_flag);
+ return *result;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -8091,7 +8152,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
if (!bound_function->IsJSFunction()) {
bool exception_thrown;
- bound_function = Execution::TryGetConstructorDelegate(bound_function,
+ bound_function = Execution::TryGetConstructorDelegate(isolate,
+ bound_function,
&exception_thrown);
if (exception_thrown) return Failure::Exception();
}
@@ -8252,9 +8314,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
return function->code();
}
function->shared()->code()->set_profiler_ticks(0);
- if (JSFunction::CompileOptimized(function,
- BailoutId::None(),
- CLEAR_EXCEPTION)) {
+ if (JSFunction::CompileOptimized(function, CLEAR_EXCEPTION)) {
return function->code();
}
if (FLAG_trace_opt) {
@@ -8267,7 +8327,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ParallelRecompile) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ConcurrentRecompile) {
HandleScope handle_scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -8276,22 +8336,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParallelRecompile) {
return isolate->heap()->undefined_value();
}
function->shared()->code()->set_profiler_ticks(0);
- ASSERT(FLAG_parallel_recompilation);
- Compiler::RecompileParallel(function);
+ ASSERT(FLAG_concurrent_recompilation);
+ if (!Compiler::RecompileConcurrent(function)) {
+ function->ReplaceCode(function->shared()->code());
+ }
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) {
- HandleScope handle_scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation);
- isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
- return function->code();
-}
-
-
class ActivationsFinder : public ThreadVisitor {
public:
Code* code_;
@@ -8347,6 +8399,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
JavaScriptFrame* frame = it.frame();
RUNTIME_ASSERT(frame->function()->IsJSFunction());
+ ASSERT(frame->function() == *function);
// Avoid doing too much work when running with --always-opt and keep
// the optimized code around.
@@ -8426,9 +8479,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsParallelRecompilationSupported) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsConcurrentRecompilationSupported) {
HandleScope scope(isolate);
- return FLAG_parallel_recompilation
+ return FLAG_concurrent_recompilation
? isolate->heap()->true_value() : isolate->heap()->false_value();
}
@@ -8446,12 +8499,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
unoptimized->kind() == Code::FUNCTION) {
CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
- for (int i = 0; i <= Code::kMaxLoopNestingMarker; i++) {
+ // Start patching from the currently patched loop nesting level.
+ int current_level = unoptimized->allow_osr_at_loop_nesting_level();
+ ASSERT(Deoptimizer::VerifyInterruptCode(
+ isolate, unoptimized, current_level));
+ 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("parallel"))) {
- function->MarkForParallelRecompilation();
+ } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent"))) {
+ function->MarkForConcurrentRecompilation();
}
}
@@ -8472,7 +8529,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimizeFunction) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
- if (!V8::UseCrankshaft()) {
+ if (!isolate->use_crankshaft()) {
return Smi::FromInt(4); // 4 == "never".
}
bool sync_with_compiler_thread = true;
@@ -8483,9 +8540,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
}
}
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- if (FLAG_parallel_recompilation && sync_with_compiler_thread) {
- while (function->IsInRecompileQueue() ||
- function->IsMarkedForInstallingRecompiledCode()) {
+ if (FLAG_concurrent_recompilation && sync_with_compiler_thread) {
+ while (function->IsInRecompileQueue()) {
isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
OS::Sleep(50);
}
@@ -8512,115 +8568,125 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
}
+static bool IsSuitableForOnStackReplacement(Isolate* isolate,
+ Handle<JSFunction> function,
+ Handle<Code> unoptimized) {
+ // Keep track of whether we've succeeded in optimizing.
+ if (!unoptimized->optimizable()) return false;
+ // If we are trying to do OSR when there are already optimized
+ // activations of the function, it means (a) the function is directly or
+ // indirectly recursive and (b) an optimized invocation has been
+ // deoptimized so that we are currently in an unoptimized activation.
+ // Check for optimized activations of this function.
+ for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
+ JavaScriptFrame* frame = it.frame();
+ if (frame->is_optimized() && frame->function() == *function) return false;
+ }
+
+ return true;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+ CONVERT_NUMBER_CHECKED(uint32_t, pc_offset, Uint32, args[1]);
+ Handle<Code> unoptimized(function->shared()->code(), isolate);
+
+#ifdef DEBUG
+ JavaScriptFrameIterator it(isolate);
+ JavaScriptFrame* frame = it.frame();
+ ASSERT_EQ(frame->function(), *function);
+ ASSERT_EQ(frame->LookupCode(), *unoptimized);
+ ASSERT(unoptimized->contains(frame->pc()));
+
+ ASSERT(pc_offset ==
+ static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()));
+#endif // DEBUG
// We're not prepared to handle a function with arguments object.
ASSERT(!function->shared()->uses_arguments());
- // We have hit a back edge in an unoptimized frame for a function that was
- // selected for on-stack replacement. Find the unoptimized code object.
- Handle<Code> unoptimized(function->shared()->code(), isolate);
- // Keep track of whether we've succeeded in optimizing.
- bool succeeded = unoptimized->optimizable();
- if (succeeded) {
- // If we are trying to do OSR when there are already optimized
- // activations of the function, it means (a) the function is directly or
- // indirectly recursive and (b) an optimized invocation has been
- // deoptimized so that we are currently in an unoptimized activation.
- // Check for optimized activations of this function.
- JavaScriptFrameIterator it(isolate);
- while (succeeded && !it.done()) {
- JavaScriptFrame* frame = it.frame();
- succeeded = !frame->is_optimized() || frame->function() != *function;
- it.Advance();
+ Handle<Code> result = Handle<Code>::null();
+ BailoutId ast_id = BailoutId::None();
+
+ if (FLAG_concurrent_recompilation && FLAG_concurrent_osr) {
+ if (isolate->optimizing_compiler_thread()->
+ IsQueuedForOSR(function, pc_offset)) {
+ // Still waiting for the optimizing compiler thread to finish. Carry on.
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - polling recompile tasks for ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+ return NULL;
}
- }
- BailoutId ast_id = BailoutId::None();
- if (succeeded) {
- // The top JS function is this one, the PC is somewhere in the
- // unoptimized code.
- JavaScriptFrameIterator it(isolate);
- JavaScriptFrame* frame = it.frame();
- ASSERT(frame->function() == *function);
- ASSERT(frame->LookupCode() == *unoptimized);
- ASSERT(unoptimized->contains(frame->pc()));
-
- // Use linear search of the unoptimized code's back edge table to find
- // the AST id matching the PC.
- uint32_t target_pc_offset =
- static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
- uint32_t loop_depth = 0;
-
- for (FullCodeGenerator::BackEdgeTableIterator back_edges(*unoptimized);
- !back_edges.Done();
- back_edges.Next()) {
- if (back_edges.pc_offset() == target_pc_offset) {
- ast_id = back_edges.ast_id();
- loop_depth = back_edges.loop_depth();
- break;
+ OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
+ FindReadyOSRCandidate(function, pc_offset);
+
+ if (compiler == NULL) {
+ if (IsSuitableForOnStackReplacement(isolate, function, unoptimized) &&
+ Compiler::RecompileConcurrent(function, pc_offset)) {
+ if (function->IsMarkedForLazyRecompilation() ||
+ function->IsMarkedForConcurrentRecompilation()) {
+ // Prevent regular recompilation if we queue this for OSR.
+ // TODO(yangguo): remove this as soon as OSR becomes one-shot.
+ function->ReplaceCode(function->shared()->code());
+ }
+ return NULL;
}
+ // Fall through to the end in case of failure.
+ } else {
+ // TODO(titzer): don't install the OSR code into the function.
+ ast_id = compiler->info()->osr_ast_id();
+ result = Compiler::InstallOptimizedCode(compiler);
}
+ } else if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
+ ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
ASSERT(!ast_id.IsNone());
-
if (FLAG_trace_osr) {
- PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
- ast_id.ToInt(), loop_depth);
+ PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
function->PrintName();
PrintF("]\n");
}
+ // Attempt OSR compilation.
+ result = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION);
+ }
- // Try to compile the optimized code. A true return value from
- // CompileOptimized means that compilation succeeded, not necessarily
- // that optimization succeeded.
- if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
- function->IsOptimized()) {
- DeoptimizationInputData* data = DeoptimizationInputData::cast(
- function->code()->deoptimization_data());
- if (data->OsrPcOffset()->value() >= 0) {
- if (FLAG_trace_osr) {
- PrintF("[on-stack replacement offset %d in optimized code]\n",
- data->OsrPcOffset()->value());
- }
- ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
- } else {
- // We may never generate the desired OSR entry if we emit an
- // early deoptimize.
- succeeded = false;
+ // Revert the patched interrupt now, regardless of whether OSR succeeds.
+ Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
+
+ // Check whether we ended up with usable optimized code.
+ if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
+ DeoptimizationInputData* data =
+ DeoptimizationInputData::cast(result->deoptimization_data());
+
+ if (data->OsrPcOffset()->value() >= 0) {
+ ASSERT(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());
}
- } else {
- succeeded = false;
+ // TODO(titzer): this is a massive hack to make the deopt counts
+ // match. Fix heuristics for reenabling optimizations!
+ function->shared()->increment_deopt_count();
+ return *result;
}
}
- // Revert to the original interrupt calls in the original unoptimized code.
if (FLAG_trace_osr) {
- PrintF("[restoring original interrupt calls in ");
+ PrintF("[OSR - optimization failed for ");
function->PrintName();
PrintF("]\n");
}
- InterruptStub interrupt_stub;
- Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate);
- Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
- Deoptimizer::RevertInterruptCode(*unoptimized,
- *interrupt_code,
- *replacement_code);
-
- // If the optimization attempt succeeded, return the AST id tagged as a
- // smi. This tells the builtin that we need to translate the unoptimized
- // frame to an optimized one.
- if (succeeded) {
- ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
- return Smi::FromInt(ast_id.ToInt());
- } else {
- if (function->IsMarkedForLazyRecompilation()) {
- function->ReplaceCode(function->shared()->code());
- }
- return Smi::FromInt(-1);
+
+ if (function->IsMarkedForLazyRecompilation() ||
+ function->IsMarkedForConcurrentRecompilation()) {
+ function->ReplaceCode(function->shared()->code());
}
+ return NULL;
}
@@ -8679,8 +8745,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
bool threw;
Handle<JSReceiver> hfun(fun);
Handle<Object> hreceiver(receiver, isolate);
- Handle<Object> result =
- Execution::Call(hfun, hreceiver, argc, argv, &threw, true);
+ Handle<Object> result = Execution::Call(
+ isolate, hfun, hreceiver, argc, argv, &threw, true);
if (threw) return Failure::Exception();
return *result;
@@ -8710,12 +8776,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
}
for (int i = 0; i < argc; ++i) {
- argv[i] = Object::GetElement(arguments, offset + i);
+ argv[i] = Object::GetElement(isolate, arguments, offset + i);
}
bool threw;
- Handle<Object> result =
- Execution::Call(fun, receiver, argc, argv, &threw, true);
+ Handle<Object> result = Execution::Call(
+ isolate, fun, receiver, argc, argv, &threw, true);
if (threw) return Failure::Exception();
return *result;
@@ -8726,7 +8792,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetFunctionDelegate(args.at<Object>(0));
+ return *Execution::GetFunctionDelegate(isolate, args.at<Object>(0));
}
@@ -8734,7 +8800,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetConstructorDelegate(args.at<Object>(0));
+ return *Execution::GetConstructorDelegate(isolate, args.at<Object>(0));
}
@@ -8783,7 +8849,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
extension_object = JSReceiver::cast(args[0]);
} else {
// Convert the object to a proper JavaScript object.
- MaybeObject* maybe_js_object = args[0]->ToObject();
+ MaybeObject* maybe_js_object = args[0]->ToObject(isolate);
if (!maybe_js_object->To(&extension_object)) {
if (Failure::cast(maybe_js_object)->IsInternalError()) {
HandleScope scope(isolate);
@@ -8937,7 +9003,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareModules) {
IsImmutableVariableMode(mode) ? FROZEN : SEALED;
Handle<AccessorInfo> info =
Accessors::MakeModuleExport(name, index, attr);
- Handle<Object> result = SetAccessor(module, info);
+ Handle<Object> result = JSObject::SetAccessor(module, info);
ASSERT(!(result.is_null() || result->IsUndefined()));
USE(result);
break;
@@ -9303,7 +9369,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
// First check if this is a real stack overflow.
if (isolate->stack_guard()->IsStackOverflow()) {
- SealHandleScope shs(isolate);
return isolate->StackOverflow();
}
@@ -9311,6 +9376,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_TryInstallRecompiledCode) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+ // First check if this is a real stack overflow.
+ if (isolate->stack_guard()->IsStackOverflow()) {
+ SealHandleScope shs(isolate);
+ return isolate->StackOverflow();
+ }
+
+ isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+ return (function->IsOptimized()) ? function->code()
+ : function->shared()->code();
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_Interrupt) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
@@ -9423,9 +9505,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
- MaybeObject* maybe_result_array =
- output->EnsureCanContainHeapObjectElements();
- if (maybe_result_array->IsFailure()) return maybe_result_array;
+ JSObject::EnsureCanContainHeapObjectElements(output);
RUNTIME_ASSERT(output->HasFastObjectElements());
DisallowHeapAllocation no_gc;
@@ -10097,7 +10177,7 @@ static bool IterateElements(Isolate* isolate,
} else if (receiver->HasElement(j)) {
// Call GetElement on receiver, not its prototype, or getters won't
// have the correct receiver.
- element_value = Object::GetElement(receiver, j);
+ element_value = Object::GetElement(isolate, receiver, j);
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
visitor->visit(j, element_value);
}
@@ -10122,7 +10202,8 @@ static bool IterateElements(Isolate* isolate,
} else if (receiver->HasElement(j)) {
// Call GetElement on receiver, not its prototype, or getters won't
// have the correct receiver.
- Handle<Object> element_value = Object::GetElement(receiver, j);
+ Handle<Object> element_value =
+ Object::GetElement(isolate, receiver, j);
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
visitor->visit(j, element_value);
}
@@ -10141,7 +10222,7 @@ static bool IterateElements(Isolate* isolate,
while (j < n) {
HandleScope loop_scope(isolate);
uint32_t index = indices[j];
- Handle<Object> element = Object::GetElement(receiver, index);
+ Handle<Object> element = Object::GetElement(isolate, receiver, index);
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
visitor->visit(index, element);
// Skip to next different index (i.e., omit duplicates).
@@ -10521,7 +10602,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
- return Execution::DebugBreakHelper();
+ return Execution::DebugBreakHelper(isolate);
}
@@ -12021,6 +12102,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
JavaScriptFrameIterator frame_it(isolate, id);
+ RUNTIME_ASSERT(!frame_it.done());
+
JavaScriptFrame* frame = frame_it.frame();
Handle<JSFunction> fun =
@@ -12040,11 +12123,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
BreakLocationIterator break_location_iterator(debug_info,
ALL_BREAK_LOCATIONS);
- break_location_iterator.FindBreakLocationFromAddress(frame->pc());
+ break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
int current_statement_pos = break_location_iterator.statement_position();
while (!break_location_iterator.Done()) {
+ bool accept;
if (break_location_iterator.pc() > frame->pc()) {
+ accept = true;
+ } else {
+ StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
+ // The break point is near our pc. Could be a step-in possibility,
+ // that is currently taken by active debugger call.
+ if (break_frame_id == StackFrame::NO_ID) {
+ // We are not stepping.
+ accept = false;
+ } else {
+ JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
+ // If our frame is a top frame and we are stepping, we can do step-in
+ // at this place.
+ accept = additional_frame_it.frame()->id() == id;
+ }
+ }
+ if (accept) {
if (break_location_iterator.IsStepInLocation(isolate)) {
Smi* position_value = Smi::FromInt(break_location_iterator.position());
JSObject::SetElement(array, len,
@@ -12476,7 +12576,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
// of frames to step down.
RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ ASSERT(args.length() == 4);
// Check arguments.
Object* check;
{ MaybeObject* maybe_check = Runtime_CheckExecutionState(
@@ -12487,6 +12587,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
return isolate->Throw(isolate->heap()->illegal_argument_string());
}
+ CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
+
+ StackFrame::Id frame_id;
+ if (wrapped_frame_id == 0) {
+ frame_id = StackFrame::NO_ID;
+ } else {
+ frame_id = UnwrapFrameId(wrapped_frame_id);
+ }
+
// Get the step action and check validity.
StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
if (step_action != StepIn &&
@@ -12497,6 +12606,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
return isolate->Throw(isolate->heap()->illegal_argument_string());
}
+ if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
+ step_action != StepMin && step_action != StepOut) {
+ return isolate->ThrowIllegalOperation();
+ }
+
// Get the number of steps.
int step_count = NumberToInt32(args[2]);
if (step_count < 1) {
@@ -12508,7 +12622,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
// Prepare step.
isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
- step_count);
+ step_count,
+ frame_id);
return isolate->heap()->undefined_value();
}
@@ -12574,7 +12689,7 @@ static MaybeObject* DebugEvaluate(Isolate* isolate,
shared, context, NOT_TENURED);
bool pending_exception;
Handle<Object> result = Execution::Call(
- eval_fun, receiver, 0, NULL, &pending_exception);
+ isolate, eval_fun, receiver, 0, NULL, &pending_exception);
if (pending_exception) return Failure::Exception();
@@ -12613,7 +12728,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Handle<Object> context_extension(args[5], isolate);
// Handle the processing of break.
- DisableBreak disable_break_save(disable_break);
+ DisableBreak disable_break_save(isolate, disable_break);
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -12680,7 +12795,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
Handle<Object> context_extension(args[3], isolate);
// Handle the processing of break.
- DisableBreak disable_break_save(disable_break);
+ DisableBreak disable_break_save(isolate, disable_break);
// Enter the top context from before the debugger was invoked.
SaveContext save(isolate);
@@ -12925,7 +13040,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
}
FixedArray* instances = FixedArray::cast(object);
- ASSERT(HEAP->IsHeapIterable());
+ ASSERT(isolate->heap()->IsHeapIterable());
// Fill the referencing objects.
HeapIterator heap_iterator2(heap);
count = DebugConstructedBy(&heap_iterator2,
@@ -12976,7 +13091,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
- CPU::DebugBreak();
+ OS::DebugBreak();
return isolate->heap()->undefined_value();
}
@@ -13345,11 +13460,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
bool pending_exception;
{
if (without_debugger) {
- result = Execution::Call(function, isolate->global_object(), 0, NULL,
+ result = Execution::Call(isolate,
+ function,
+ isolate->global_object(),
+ 0,
+ NULL,
&pending_exception);
} else {
- EnterDebugger enter_debugger;
- result = Execution::Call(function, isolate->global_object(), 0, NULL,
+ EnterDebugger enter_debugger(isolate);
+ result = Execution::Call(isolate,
+ function,
+ isolate->global_object(),
+ 0,
+ NULL,
&pending_exception);
}
}
@@ -13510,7 +13633,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
Handle<Name> base =
isolate->factory()->NewStringFromAscii(CStrVector("base"));
for (unsigned int i = 0; i < length; ++i) {
- MaybeObject* maybe_string = input->GetElement(i);
+ MaybeObject* maybe_string = input->GetElement(isolate, i);
Object* locale_id;
if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) {
return isolate->Throw(isolate->heap()->illegal_argument_string());
@@ -13623,11 +13746,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
isolate->factory()->NewStringFromAscii(CStrVector("valid")),
NONE));
- Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
- v8::Utils::ToLocal(local_object));
// Make object handle weak so we can delete the data format once GC kicks in.
- wrapper.MakeWeak<void>(NULL, &DateFormat::DeleteDateFormat);
- wrapper.ClearAndLeak();
+ Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+ GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
+ NULL,
+ DateFormat::DeleteDateFormat);
return *local_object;
}
@@ -13641,7 +13764,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
bool has_pending_exception = false;
- Handle<Object> value = Execution::ToNumber(date, &has_pending_exception);
+ Handle<Object> value =
+ Execution::ToNumber(isolate, date, &has_pending_exception);
if (has_pending_exception) {
ASSERT(isolate->has_pending_exception());
return Failure::Exception();
@@ -13681,7 +13805,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) {
bool has_pending_exception = false;
Handle<JSDate> result = Handle<JSDate>::cast(
- Execution::NewDate(static_cast<double>(date), &has_pending_exception));
+ Execution::NewDate(
+ isolate, static_cast<double>(date), &has_pending_exception));
if (has_pending_exception) {
ASSERT(isolate->has_pending_exception());
return Failure::Exception();
@@ -13726,12 +13851,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
isolate->factory()->NewStringFromAscii(CStrVector("valid")),
NONE));
- Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
- v8::Utils::ToLocal(local_object));
- // Make object handle weak so we can delete the number format once GC kicks
- // in.
- wrapper.MakeWeak<void>(NULL, &NumberFormat::DeleteNumberFormat);
- wrapper.ClearAndLeak();
+ Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+ GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
+ NULL,
+ NumberFormat::DeleteNumberFormat);
return *local_object;
}
@@ -13745,7 +13868,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
bool has_pending_exception = false;
- Handle<Object> value = Execution::ToNumber(number, &has_pending_exception);
+ Handle<Object> value = Execution::ToNumber(
+ isolate, number, &has_pending_exception);
if (has_pending_exception) {
ASSERT(isolate->has_pending_exception());
return Failure::Exception();
@@ -13839,11 +13963,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
isolate->factory()->NewStringFromAscii(CStrVector("valid")),
NONE));
- Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate),
- v8::Utils::ToLocal(local_object));
- // Make object handle weak so we can delete the collator once GC kicks in.
- wrapper.MakeWeak<void>(NULL, &Collator::DeleteCollator);
- wrapper.ClearAndLeak();
+ Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+ GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
+ NULL,
+ Collator::DeleteCollator);
return *local_object;
}
@@ -13874,6 +13997,158 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalCompare) {
return *isolate->factory()->NewNumberFromInt(result);
}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
+
+ Handle<ObjectTemplateInfo> break_iterator_template =
+ I18N::GetTemplate2(isolate);
+
+ // Create an empty object wrapper.
+ bool has_pending_exception = false;
+ Handle<JSObject> local_object = Execution::InstantiateObject(
+ break_iterator_template, &has_pending_exception);
+ if (has_pending_exception) {
+ ASSERT(isolate->has_pending_exception());
+ return Failure::Exception();
+ }
+
+ // Set break iterator as internal field of the resulting JS object.
+ icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
+ isolate, locale, options, resolved);
+
+ if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
+ // Make sure that the pointer to adopted text is NULL.
+ local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
+
+ RETURN_IF_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ local_object,
+ isolate->factory()->NewStringFromAscii(CStrVector("breakIterator")),
+ isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ NONE));
+
+ // Make object handle weak so we can delete the break iterator once GC kicks
+ // in.
+ Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+ GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
+ NULL,
+ BreakIterator::DeleteBreakIterator);
+ return *local_object;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorAdoptText) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 2);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
+
+ icu::BreakIterator* break_iterator =
+ BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+ if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
+ break_iterator_holder->GetInternalField(1));
+ delete u_text;
+
+ v8::String::Value text_value(v8::Utils::ToLocal(text));
+ u_text = new icu::UnicodeString(
+ reinterpret_cast<const UChar*>(*text_value), text_value.length());
+ break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
+
+ break_iterator->setText(*u_text);
+
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorFirst) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+ icu::BreakIterator* break_iterator =
+ BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+ if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ return *isolate->factory()->NewNumberFromInt(break_iterator->first());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorNext) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+ icu::BreakIterator* break_iterator =
+ BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+ if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ return *isolate->factory()->NewNumberFromInt(break_iterator->next());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorCurrent) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+ icu::BreakIterator* break_iterator =
+ BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+ if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ return *isolate->factory()->NewNumberFromInt(break_iterator->current());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorBreakType) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+ icu::BreakIterator* break_iterator =
+ BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+ if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+ // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
+ icu::RuleBasedBreakIterator* rule_based_iterator =
+ static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
+ 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()->NewStringFromAscii(CStrVector("none"));
+ } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
+ return *isolate->factory()->NewStringFromAscii(CStrVector("number"));
+ } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
+ return *isolate->factory()->NewStringFromAscii(CStrVector("letter"));
+ } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
+ return *isolate->factory()->NewStringFromAscii(CStrVector("kana"));
+ } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
+ return *isolate->factory()->NewStringFromAscii(CStrVector("ideo"));
+ } else {
+ return *isolate->factory()->NewStringFromAscii(CStrVector("unknown"));
+ }
+}
#endif // V8_I18N_SUPPORT
@@ -13952,13 +14227,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
HandleScope scope(isolate);
ASSERT_EQ(args.length(), 1);
- CONVERT_ARG_CHECKED(JSObject, error_object, 0);
- String* key = isolate->heap()->hidden_stack_trace_string();
- Object* result = error_object->GetHiddenProperty(key);
+ 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());
- error_object->DeleteHiddenProperty(key);
- return result;
+ JSObject::DeleteHiddenProperty(error_object, key);
+ return *result;
}
@@ -14064,7 +14339,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
// This handle is nor shared, nor used later, so it's safe.
Handle<Object> argv[] = { key_handle };
bool pending_exception;
- value = Execution::Call(factory,
+ value = Execution::Call(isolate,
+ factory,
receiver,
ARRAY_SIZE(argv),
argv,
@@ -14232,6 +14508,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessCheckNeeded) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(HeapObject, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsAccessCheckNeeded());
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -14309,6 +14593,34 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
+ ASSERT(object->IsAccessCheckNeeded());
+ Handle<Object> key = args.at<Object>(2);
+ SaveContext save(isolate);
+ isolate->set_context(observer->context());
+ if (!isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
+ v8::ACCESS_KEYS)) {
+ return isolate->heap()->false_value();
+ }
+ bool access_allowed = false;
+ uint32_t index = 0;
+ if (key->ToArrayIndex(&index) ||
+ (key->IsString() && String::cast(*key)->AsArrayIndex(&index))) {
+ access_allowed =
+ isolate->MayIndexedAccess(*object, index, v8::ACCESS_GET) &&
+ isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS);
+ } else {
+ access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) &&
+ isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS);
+ }
+ return isolate->heap()->ToBoolean(access_allowed);
+}
+
+
static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
Handle<JSFunction> constructor,
Handle<Object> type_info,
@@ -14433,7 +14745,6 @@ static const Runtime::Function kIntrinsicFunctions[] = {
MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
Object* dictionary) {
- ASSERT(Isolate::Current()->heap() == heap);
ASSERT(dictionary != NULL);
ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0);
for (int i = 0; i < kNumFunctions; ++i) {