Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc
index f651ed4..ab436c2 100644
--- a/src/runtime/runtime-array.cc
+++ b/src/runtime/runtime-array.cc
@@ -5,11 +5,12 @@
#include "src/runtime/runtime-utils.h"
#include "src/arguments.h"
+#include "src/code-stubs.h"
#include "src/conversions-inl.h"
#include "src/elements.h"
#include "src/factory.h"
#include "src/isolate-inl.h"
-#include "src/key-accumulator.h"
+#include "src/keys.h"
#include "src/messages.h"
#include "src/prototype.h"
@@ -29,17 +30,20 @@
return Smi::FromInt(0);
}
-
-static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder,
- const char* name, Builtins::Name builtin_name) {
+static void InstallCode(Isolate* isolate, Handle<JSObject> holder,
+ const char* name, Handle<Code> code) {
Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
- Handle<Code> code(isolate->builtins()->builtin(builtin_name));
Handle<JSFunction> optimized =
isolate->factory()->NewFunctionWithoutPrototype(key, code);
optimized->shared()->DontAdaptArguments();
JSObject::AddProperty(holder, key, optimized, NONE);
}
+static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder,
+ const char* name, Builtins::Name builtin_name) {
+ InstallCode(isolate, holder, name,
+ handle(isolate->builtins()->builtin(builtin_name), isolate));
+}
RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
HandleScope scope(isolate);
@@ -48,7 +52,8 @@
isolate->factory()->NewJSObject(isolate->object_function());
InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
- InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
+ FastArrayPushStub stub(isolate);
+ InstallCode(isolate, holder, "push", stub.GetCode());
InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
@@ -88,29 +93,6 @@
}
-// Push an object unto an array of objects if it is not already in the
-// array. Returns true if the element was pushed on the stack and
-// false otherwise.
-RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
- RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
- int length = Smi::cast(array->length())->value();
- FixedArray* elements = FixedArray::cast(array->elements());
- for (int i = 0; i < length; i++) {
- if (elements->get(i) == *element) return isolate->heap()->false_value();
- }
-
- // Strict not needed. Used for cycle detection in Array join implementation.
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::AddDataElement(array, length, element, NONE));
- JSObject::ValidateElements(array);
- return isolate->heap()->true_value();
-}
-
-
// Moves all own elements of an object, that are below a limit, to positions
// starting at zero. All undefined values are placed after non-undefined values,
// and are followed by non-existing element. Does not change the length
@@ -234,12 +216,19 @@
JSObject::CollectOwnElementKeys(current, &accumulator, ALL_PROPERTIES);
}
// Erase any keys >= length.
- // TODO(adamk): Remove this step when the contract of %GetArrayKeys
- // is changed to let this happen on the JS side.
Handle<FixedArray> keys = accumulator.GetKeys(KEEP_NUMBERS);
+ int j = 0;
for (int i = 0; i < keys->length(); i++) {
- if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
+ if (NumberToUint32(keys->get(i)) >= length) continue;
+ if (i != j) keys->set(j, keys->get(i));
+ j++;
}
+
+ if (j != keys->length()) {
+ isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
+ *keys, keys->length() - j);
+ }
+
return *isolate->factory()->NewJSArrayWithElements(keys);
}
@@ -383,7 +372,6 @@
caller_args);
}
-
RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
HandleScope scope(isolate);
Arguments empty_args(0, NULL);
diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc
index e27685d..3f10225 100644
--- a/src/runtime/runtime-classes.cc
+++ b/src/runtime/runtime-classes.cc
@@ -124,14 +124,6 @@
Handle<Map> map =
isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
map->set_is_prototype_map(true);
- if (constructor->map()->is_strong()) {
- map->set_is_strong();
- if (super_class->IsNull()) {
- // Strong class is not permitted to extend null.
- THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kStrongExtendNull),
- Object);
- }
- }
Map::SetPrototype(map, prototype_parent);
map->SetConstructor(*constructor);
Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map);
@@ -206,19 +198,7 @@
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, constructor, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, prototype, 1);
-
JSObject::MigrateSlowToFast(constructor, 0, "RuntimeToFastProperties");
-
- if (constructor->map()->is_strong()) {
- DCHECK(prototype->map()->is_strong());
- MAYBE_RETURN(JSReceiver::SetIntegrityLevel(prototype, FROZEN,
- Object::THROW_ON_ERROR),
- isolate->heap()->exception());
- MAYBE_RETURN(JSReceiver::SetIntegrityLevel(constructor, FROZEN,
- Object::THROW_ON_ERROR),
- isolate->heap()->exception());
- }
return *constructor;
}
diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc
index 263c4f9..89a6fa1 100644
--- a/src/runtime/runtime-compiler.cc
+++ b/src/runtime/runtime-compiler.cc
@@ -21,6 +21,7 @@
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
#ifdef DEBUG
if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
PrintF("[unoptimized: ");
@@ -28,63 +29,28 @@
PrintF("]\n");
}
#endif
+
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
-
- // Compile the target function.
- DCHECK(function->shared()->allows_lazy_compilation());
-
- Handle<Code> code;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
- Compiler::GetLazyCode(function));
- DCHECK(code->IsJavaScriptCode());
-
- function->ReplaceCode(*code);
- return *code;
-}
-
-
-namespace {
-
-Object* CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
- Compiler::ConcurrencyMode mode) {
- StackLimitCheck check(isolate);
- if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
-
- Handle<Code> code;
- if (Compiler::GetOptimizedCode(function, mode).ToHandle(&code)) {
- // Optimization succeeded, return optimized code.
- function->ReplaceCode(*code);
- } else {
- // Optimization failed, get unoptimized code.
- if (isolate->has_pending_exception()) { // Possible stack overflow.
- return isolate->heap()->exception();
- }
- code = Handle<Code>(function->shared()->code(), isolate);
- if (code->kind() != Code::FUNCTION &&
- code->kind() != Code::OPTIMIZED_FUNCTION) {
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, code, Compiler::GetUnoptimizedCode(function));
- }
- function->ReplaceCode(*code);
+ if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
+ return isolate->heap()->exception();
}
-
- DCHECK(function->code()->kind() == Code::FUNCTION ||
- function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
- (function->code()->is_interpreter_entry_trampoline() &&
- function->shared()->HasBytecodeArray()) ||
- function->IsInOptimizationQueue());
+ DCHECK(function->is_compiled());
return function->code();
}
-} // namespace
-
RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- return CompileOptimized(isolate, function, Compiler::CONCURRENT);
+ StackLimitCheck check(isolate);
+ if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
+ if (!Compiler::CompileOptimized(function, Compiler::CONCURRENT)) {
+ return isolate->heap()->exception();
+ }
+ DCHECK(function->is_compiled());
+ return function->code();
}
@@ -92,7 +58,13 @@
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- return CompileOptimized(isolate, function, Compiler::NOT_CONCURRENT);
+ StackLimitCheck check(isolate);
+ if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
+ if (!Compiler::CompileOptimized(function, Compiler::NOT_CONCURRENT)) {
+ return isolate->heap()->exception();
+ }
+ DCHECK(function->is_compiled());
+ return function->code();
}
@@ -150,10 +122,6 @@
deoptimizer->MaterializeHeapObjects(&it);
delete deoptimizer;
- JavaScriptFrame* frame = it.frame();
- RUNTIME_ASSERT(frame->function()->IsJSFunction());
- DCHECK(frame->function() == *function);
-
// Ensure the context register is updated for materialized objects.
JavaScriptFrameIterator top_it(isolate);
JavaScriptFrame* top_frame = top_it.frame();
@@ -163,7 +131,10 @@
return isolate->heap()->undefined_value();
}
- // Search for other activations of the same function and code.
+ // Search for other activations of the same optimized code.
+ // At this point {it} is at the topmost frame of all the frames materialized
+ // by the deoptimizer. Note that this frame does not necessarily represent
+ // an activation of {function} because of potential inlined tail-calls.
ActivationsFinder activations_finder(*optimized_code);
activations_finder.VisitFrames(&it);
isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
@@ -240,59 +211,17 @@
DCHECK(caller_code->contains(frame->pc()));
#endif // DEBUG
-
BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
DCHECK(!ast_id.IsNone());
- // Disable concurrent OSR for asm.js, to enable frame specialization.
- Compiler::ConcurrencyMode mode = (isolate->concurrent_osr_enabled() &&
- !function->shared()->asm_function() &&
- function->shared()->ast_node_count() > 512)
- ? Compiler::CONCURRENT
- : Compiler::NOT_CONCURRENT;
-
- OptimizedCompileJob* job = NULL;
- if (mode == Compiler::CONCURRENT) {
- // Gate the OSR entry with a stack check.
- BackEdgeTable::AddStackCheck(caller_code, pc_offset);
- // Poll already queued compilation jobs.
- OptimizingCompileDispatcher* dispatcher =
- isolate->optimizing_compile_dispatcher();
- if (dispatcher->IsQueuedForOSR(function, ast_id)) {
- if (FLAG_trace_osr) {
- PrintF("[OSR - Still waiting for queued: ");
- function->PrintName();
- PrintF(" at AST id %d]\n", ast_id.ToInt());
- }
- return NULL;
- }
-
- job = dispatcher->FindReadyOSRCandidate(function, ast_id);
- }
-
MaybeHandle<Code> maybe_result;
- if (job != NULL) {
- if (FLAG_trace_osr) {
- PrintF("[OSR - Found ready: ");
- function->PrintName();
- PrintF(" at AST id %d]\n", ast_id.ToInt());
- }
- maybe_result = Compiler::GetConcurrentlyOptimizedCode(job);
- } else if (IsSuitableForOnStackReplacement(isolate, function)) {
+ if (IsSuitableForOnStackReplacement(isolate, function)) {
if (FLAG_trace_osr) {
PrintF("[OSR - Compiling: ");
function->PrintName();
PrintF(" at AST id %d]\n", ast_id.ToInt());
}
- maybe_result = Compiler::GetOptimizedCode(
- function, mode, ast_id,
- (mode == Compiler::NOT_CONCURRENT) ? frame : nullptr);
- Handle<Code> result;
- if (maybe_result.ToHandle(&result) &&
- result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
- // Optimization is queued. Return to check later.
- return NULL;
- }
+ maybe_result = Compiler::GetOptimizedCodeForOSR(function, ast_id, frame);
}
// Revert the patched back edge table, regardless of whether OSR succeeds.
diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
index c29ea9a..ad8375a 100644
--- a/src/runtime/runtime-debug.cc
+++ b/src/runtime/runtime-debug.cc
@@ -5,11 +5,13 @@
#include "src/runtime/runtime-utils.h"
#include "src/arguments.h"
-#include "src/debug/debug.h"
#include "src/debug/debug-evaluate.h"
#include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h"
+#include "src/debug/debug.h"
#include "src/frames-inl.h"
+#include "src/interpreter/bytecodes.h"
+#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/runtime/runtime.h"
@@ -18,11 +20,39 @@
RUNTIME_FUNCTION(Runtime_DebugBreak) {
SealHandleScope shs(isolate);
- DCHECK(args.length() == 0);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
+ isolate->debug()->set_return_value(value);
+
// Get the top-most JavaScript frame.
JavaScriptFrameIterator it(isolate);
- isolate->debug()->Break(args, it.frame());
- return isolate->debug()->SetAfterBreakTarget(it.frame());
+ isolate->debug()->Break(it.frame());
+
+ isolate->debug()->SetAfterBreakTarget(it.frame());
+ return *isolate->debug()->return_value();
+}
+
+RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
+ isolate->debug()->set_return_value(value);
+
+ // Get the top-most JavaScript frame.
+ JavaScriptFrameIterator it(isolate);
+ isolate->debug()->Break(it.frame());
+
+ // Return the handler from the original bytecode array.
+ DCHECK(it.frame()->is_interpreted());
+ InterpretedFrame* interpreted_frame =
+ reinterpret_cast<InterpretedFrame*>(it.frame());
+ SharedFunctionInfo* shared = interpreted_frame->function()->shared();
+ BytecodeArray* bytecode_array = shared->bytecode_array();
+ int bytecode_offset = interpreted_frame->GetBytecodeOffset();
+ interpreter::Bytecode bytecode =
+ interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
+ return isolate->interpreter()->GetBytecodeHandler(
+ bytecode, interpreter::OperandScale::kSingle);
}
@@ -302,8 +332,8 @@
if (name->AsArrayIndex(&index)) {
Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
Handle<Object> element_or_char;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element_or_char,
- Object::GetElement(isolate, obj, index));
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, element_or_char, JSReceiver::GetElement(isolate, obj, index));
details->set(0, *element_or_char);
details->set(1, PropertyDetails::Empty().AsSmi());
return *isolate->factory()->NewJSArrayWithElements(details);
@@ -418,8 +448,8 @@
RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
- Object::GetElement(isolate, obj, index));
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSReceiver::GetElement(isolate, obj, index));
return *result;
}
@@ -554,7 +584,11 @@
// Use the value from the stack.
if (scope_info->LocalIsSynthetic(i)) continue;
locals->set(local * 2, scope_info->LocalName(i));
- locals->set(local * 2 + 1, *(frame_inspector.GetExpression(i)));
+ Handle<Object> value = frame_inspector.GetExpression(i);
+ // TODO(yangguo): We convert optimized out values to {undefined} when they
+ // are passed to the debugger. Eventually we should handle them somehow.
+ if (value->IsOptimizedOut()) value = isolate->factory()->undefined_value();
+ locals->set(local * 2 + 1, *value);
local++;
}
if (local < local_count) {
@@ -587,31 +621,7 @@
// to the frame information.
Handle<Object> return_value = isolate->factory()->undefined_value();
if (at_return) {
- StackFrameIterator it2(isolate);
- Address internal_frame_sp = NULL;
- while (!it2.done()) {
- if (it2.frame()->is_internal()) {
- internal_frame_sp = it2.frame()->sp();
- } else {
- if (it2.frame()->is_java_script()) {
- if (it2.frame()->id() == it.frame()->id()) {
- // The internal frame just before the JavaScript frame contains the
- // value to return on top. A debug break at return will create an
- // internal frame to store the return value (eax/rax/r0) before
- // entering the debug break exit frame.
- if (internal_frame_sp != NULL) {
- return_value =
- Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
- break;
- }
- }
- }
-
- // Indicate that the previous frame was not an internal frame.
- internal_frame_sp = NULL;
- }
- it2.Advance();
- }
+ return_value = isolate->debug()->return_value();
}
// Now advance to the arguments adapter frame (if any). It contains all
@@ -740,33 +750,6 @@
}
-// Returns the list of step-in positions (text offset) in a function of the
-// stack frame in a range from the current debug break position to the end
-// of the corresponding statement.
-RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-
- // Get the frame where the debugging is performed.
- StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
- JavaScriptFrameIterator frame_it(isolate, id);
- RUNTIME_ASSERT(!frame_it.done());
-
- List<int> positions;
- isolate->debug()->GetStepinPositions(frame_it.frame(), id, &positions);
- Factory* factory = isolate->factory();
- Handle<FixedArray> array = factory->NewFixedArray(positions.length());
- for (int i = 0; i < positions.length(); ++i) {
- array->set(i, Smi::FromInt(positions[i]));
- }
- return *factory->NewJSArrayWithElements(array, FAST_SMI_ELEMENTS);
-}
-
-
// Return an array with scope details
// args[0]: number: break id
// args[1]: number: frame index
@@ -1652,15 +1635,6 @@
}
-RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
- DCHECK(args.length() == 1);
- HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
- isolate->debug()->OnPromiseEvent(data);
- return isolate->heap()->undefined_value();
-}
-
-
RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
DCHECK(args.length() == 1);
HandleScope scope(isolate);
diff --git a/src/runtime/runtime-forin.cc b/src/runtime/runtime-forin.cc
index c44945c..4b558d1 100644
--- a/src/runtime/runtime-forin.cc
+++ b/src/runtime/runtime-forin.cc
@@ -5,8 +5,10 @@
#include "src/runtime/runtime-utils.h"
#include "src/arguments.h"
+#include "src/elements.h"
#include "src/factory.h"
#include "src/isolate-inl.h"
+#include "src/keys.h"
#include "src/objects-inl.h"
namespace v8 {
@@ -20,30 +22,82 @@
// deletions during a for-in.
MaybeHandle<HeapObject> Enumerate(Handle<JSReceiver> receiver) {
Isolate* const isolate = receiver->GetIsolate();
+ FastKeyAccumulator accumulator(isolate, receiver, INCLUDE_PROTOS,
+ ENUMERABLE_STRINGS);
+ accumulator.set_filter_proxy_keys(false);
// Test if we have an enum cache for {receiver}.
- if (!receiver->IsSimpleEnum()) {
+ if (!accumulator.is_receiver_simple_enum()) {
Handle<FixedArray> keys;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, keys,
- JSReceiver::GetKeys(receiver, INCLUDE_PROTOS, ENUMERABLE_STRINGS),
- HeapObject);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, keys, accumulator.GetKeys(KEEP_NUMBERS),
+ HeapObject);
// Test again, since cache may have been built by GetKeys() calls above.
- if (!receiver->IsSimpleEnum()) return keys;
+ if (!accumulator.is_receiver_simple_enum()) return keys;
}
return handle(receiver->map(), isolate);
}
+// This is a slight modifcation of JSReceiver::HasProperty, dealing with
+// the oddities of JSProxy in for-in filter.
+MaybeHandle<Object> HasEnumerableProperty(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ Handle<Object> key) {
+ bool success = false;
+ Maybe<PropertyAttributes> result = Just(ABSENT);
+ LookupIterator it =
+ LookupIterator::PropertyOrElement(isolate, receiver, key, &success);
+ if (!success) return isolate->factory()->undefined_value();
+ for (; it.IsFound(); it.Next()) {
+ switch (it.state()) {
+ case LookupIterator::NOT_FOUND:
+ case LookupIterator::TRANSITION:
+ UNREACHABLE();
+ case LookupIterator::JSPROXY: {
+ // For proxies we have to invoke the [[GetOwnProperty]] trap.
+ result = JSProxy::GetPropertyAttributes(&it);
+ if (result.IsNothing()) return MaybeHandle<Object>();
+ if (result.FromJust() == ABSENT) {
+ // Continue lookup on the proxy's prototype.
+ Handle<JSProxy> proxy = it.GetHolder<JSProxy>();
+ Handle<Object> prototype;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, prototype,
+ JSProxy::GetPrototype(proxy), Object);
+ if (prototype->IsNull()) break;
+ // We already have a stack-check in JSProxy::GetPrototype.
+ return HasEnumerableProperty(
+ isolate, Handle<JSReceiver>::cast(prototype), key);
+ } else if (result.FromJust() & DONT_ENUM) {
+ return isolate->factory()->undefined_value();
+ } else {
+ return it.GetName();
+ }
+ }
+ case LookupIterator::INTERCEPTOR: {
+ result = JSObject::GetPropertyAttributesWithInterceptor(&it);
+ if (result.IsNothing()) return MaybeHandle<Object>();
+ if (result.FromJust() != ABSENT) return it.GetName();
+ continue;
+ }
+ case LookupIterator::ACCESS_CHECK: {
+ if (it.HasAccess()) continue;
+ result = JSObject::GetPropertyAttributesWithFailedAccessCheck(&it);
+ if (result.IsNothing()) return MaybeHandle<Object>();
+ if (result.FromJust() != ABSENT) return it.GetName();
+ return isolate->factory()->undefined_value();
+ }
+ case LookupIterator::INTEGER_INDEXED_EXOTIC:
+ // TypedArray out-of-bounds access.
+ return isolate->factory()->undefined_value();
+ case LookupIterator::ACCESSOR:
+ case LookupIterator::DATA:
+ return it.GetName();
+ }
+ }
+ return isolate->factory()->undefined_value();
+}
MaybeHandle<Object> Filter(Handle<JSReceiver> receiver, Handle<Object> key) {
Isolate* const isolate = receiver->GetIsolate();
- // TODO(turbofan): Fast case for array indices.
- Handle<Name> name;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
- Object);
- Maybe<bool> result = JSReceiver::HasProperty(receiver, name);
- MAYBE_RETURN_NULL(result);
- if (result.FromJust()) return name;
- return isolate->factory()->undefined_value();
+ return HasEnumerableProperty(isolate, receiver, key);
}
} // namespace
diff --git a/src/runtime/runtime-function.cc b/src/runtime/runtime-function.cc
index d424a9e..011f9ff 100644
--- a/src/runtime/runtime-function.cc
+++ b/src/runtime/runtime-function.cc
@@ -16,11 +16,20 @@
namespace internal {
RUNTIME_FUNCTION(Runtime_FunctionGetName) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, f, 0);
- return f->shared()->name();
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
+ if (function->IsJSBoundFunction()) {
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSBoundFunction::GetName(
+ isolate, Handle<JSBoundFunction>::cast(function)));
+ return *result;
+ } else {
+ RUNTIME_ASSERT(function->IsJSFunction());
+ return Handle<JSFunction>::cast(function)->shared()->name();
+ }
}
@@ -96,6 +105,14 @@
return Smi::FromInt(abstract_code->SourcePosition(offset));
}
+RUNTIME_FUNCTION(Runtime_FunctionGetContextData) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+
+ CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+ FixedArray* array = fun->native_context()->embedder_data();
+ return array->get(v8::Context::kDebugIdIndex);
+}
RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
SealHandleScope shs(isolate);
@@ -153,7 +170,7 @@
Handle<SharedFunctionInfo> target_shared(target->shared());
Handle<SharedFunctionInfo> source_shared(source->shared());
- if (!Compiler::Compile(source, KEEP_EXCEPTION)) {
+ if (!Compiler::Compile(source, Compiler::KEEP_EXCEPTION)) {
return isolate->heap()->exception();
}
@@ -168,7 +185,7 @@
// of the target shared function info.
target_shared->ReplaceCode(source_shared->code());
if (source_shared->HasBytecodeArray()) {
- target_shared->set_function_data(source_shared->bytecode_array());
+ target_shared->set_bytecode_array(source_shared->bytecode_array());
}
target_shared->set_scope_info(source_shared->scope_info());
target_shared->set_length(source_shared->length());
@@ -204,8 +221,8 @@
if (isolate->logger()->is_logging_code_events() ||
isolate->cpu_profiler()->is_profiling()) {
- isolate->logger()->LogExistingFunction(source_shared,
- Handle<Code>(source_shared->code()));
+ isolate->logger()->LogExistingFunction(
+ source_shared, Handle<AbstractCode>(source_shared->abstract_code()));
}
return *target;
@@ -253,7 +270,7 @@
HandleScope scope(isolate);
DCHECK_LE(2, args.length());
int const argc = args.length() - 2;
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, target, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
ScopedVector<Handle<Object>> argv(argc);
for (int i = 0; i < argc; ++i) {
@@ -267,61 +284,6 @@
}
-RUNTIME_FUNCTION(Runtime_TailCall) {
- HandleScope scope(isolate);
- DCHECK_LE(2, args.length());
- int const argc = args.length() - 2;
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
- ScopedVector<Handle<Object>> argv(argc);
- for (int i = 0; i < argc; ++i) {
- argv[i] = args.at<Object>(2 + i);
- }
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- Execution::Call(isolate, target, receiver, argc, argv.start()));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_Apply) {
- HandleScope scope(isolate);
- 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_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.
- static int kMaxArgc = 1000000;
- RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
-
- // If there are too many arguments, allocate argv via malloc.
- const int argv_small_size = 10;
- Handle<Object> argv_small_buffer[argv_small_size];
- base::SmartArrayPointer<Handle<Object> > argv_large_buffer;
- Handle<Object>* argv = argv_small_buffer;
- if (argc > argv_small_size) {
- argv = new Handle<Object>[argc];
- if (argv == NULL) return isolate->StackOverflow();
- argv_large_buffer = base::SmartArrayPointer<Handle<Object> >(argv);
- }
-
- for (int i = 0; i < argc; ++i) {
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, argv[i], Object::GetElement(isolate, arguments, offset + i));
- }
-
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Execution::Call(isolate, fun, receiver, argc, argv));
- return *result;
-}
-
-
// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
HandleScope scope(isolate);
@@ -342,14 +304,6 @@
}
-RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 0);
- THROW_NEW_ERROR_RETURN_FAILURE(isolate,
- NewTypeError(MessageTemplate::kStrongArity));
-}
-
-
RUNTIME_FUNCTION(Runtime_FunctionToString) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
diff --git a/src/runtime/runtime-generator.cc b/src/runtime/runtime-generator.cc
index dab0621..181b5f9 100644
--- a/src/runtime/runtime-generator.cc
+++ b/src/runtime/runtime-generator.cc
@@ -43,6 +43,8 @@
JavaScriptFrame* frame = stack_iterator.frame();
RUNTIME_ASSERT(frame->function()->shared()->is_generator());
DCHECK_EQ(frame->function(), generator_object->function());
+ DCHECK(frame->function()->shared()->is_compiled());
+ DCHECK(!frame->function()->IsOptimized());
// The caller should have saved the context and continuation already.
DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
@@ -88,18 +90,18 @@
JavaScriptFrame* frame = stack_iterator.frame();
DCHECK_EQ(frame->function(), generator_object->function());
- DCHECK(frame->function()->is_compiled());
+ DCHECK(frame->function()->shared()->is_compiled());
+ DCHECK(!frame->function()->IsOptimized());
STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
- Address pc = generator_object->function()->code()->instruction_start();
+ Code* code = generator_object->function()->shared()->code();
int offset = generator_object->continuation();
- DCHECK(offset > 0);
- frame->set_pc(pc + offset);
+ DCHECK_GT(offset, 0);
+ frame->set_pc(code->instruction_start() + offset);
if (FLAG_enable_embedded_constant_pool) {
- frame->set_constant_pool(
- generator_object->function()->code()->constant_pool());
+ frame->set_constant_pool(code->constant_pool());
}
generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
@@ -148,16 +150,6 @@
}
-// 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);
@@ -203,26 +195,23 @@
return isolate->heap()->undefined_value();
}
-
-// Optimization for the following three functions is disabled in
-// js/generator.js and compiler/ast-graph-builder.cc.
-
+// Optimization for builtins calling any of the following three functions is
+// disabled in js/generator.js and compiler.cc, hence they are unreachable.
RUNTIME_FUNCTION(Runtime_GeneratorNext) {
UNREACHABLE();
return nullptr;
}
-
RUNTIME_FUNCTION(Runtime_GeneratorReturn) {
UNREACHABLE();
return nullptr;
}
-
RUNTIME_FUNCTION(Runtime_GeneratorThrow) {
UNREACHABLE();
return nullptr;
}
+
} // namespace internal
} // namespace v8
diff --git a/src/runtime/runtime-i18n.cc b/src/runtime/runtime-i18n.cc
index e57f8d3..27f970b 100644
--- a/src/runtime/runtime-i18n.cc
+++ b/src/runtime/runtime-i18n.cc
@@ -158,8 +158,8 @@
Handle<Name> base = factory->NewStringFromStaticChars("base");
for (unsigned int i = 0; i < length; ++i) {
Handle<Object> locale_id;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, locale_id,
- Object::GetElement(isolate, input, i));
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, locale_id, JSReceiver::GetElement(isolate, input, i));
if (!locale_id->IsString()) {
return isolate->Throw(*factory->illegal_argument_string());
}
diff --git a/src/runtime/runtime-internal.cc b/src/runtime/runtime-internal.cc
index 0ca2e84..d871fc7 100644
--- a/src/runtime/runtime-internal.cc
+++ b/src/runtime/runtime-internal.cc
@@ -171,14 +171,6 @@
}
-RUNTIME_FUNCTION(Runtime_ThrowStrongModeImplicitConversion) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 0);
- THROW_NEW_ERROR_RETURN_FAILURE(
- isolate, NewTypeError(MessageTemplate::kStrongImplicitConversion));
-}
-
-
RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
@@ -271,7 +263,7 @@
RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, error_object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
if (!isolate->bootstrapper()->IsActive()) {
@@ -317,7 +309,6 @@
return *result;
}
-
#define CALLSITE_GET(NAME, RETURN) \
RUNTIME_FUNCTION(Runtime_CallSite##NAME##RT) { \
HandleScope scope(isolate); \
@@ -325,7 +316,7 @@
CONVERT_ARG_HANDLE_CHECKED(JSObject, call_site_obj, 0); \
Handle<String> result; \
CallSite call_site(isolate, call_site_obj); \
- RUNTIME_ASSERT(call_site.IsValid()) \
+ RUNTIME_ASSERT(call_site.IsValid()); \
return RETURN(call_site.NAME(), isolate); \
}
@@ -366,18 +357,6 @@
}
-RUNTIME_FUNCTION(Runtime_IncrementStatsCounter) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(String, name, 0);
-
- if (FLAG_native_code_counters) {
- StatsCounter(isolate, name->ToCString().get()).Increment();
- }
- return isolate->heap()->undefined_value();
-}
-
-
namespace {
bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
@@ -407,7 +386,7 @@
Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) {
MessageLocation location;
if (ComputeLocation(isolate, &location)) {
- Zone zone;
+ Zone zone(isolate->allocator());
base::SmartPointer<ParseInfo> info(
location.function()->shared()->is_function()
? new ParseInfo(&zone, location.function())
@@ -477,6 +456,12 @@
return isolate->heap()->undefined_value();
}
+RUNTIME_FUNCTION(Runtime_GetOrdinaryHasInstance) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(0, args.length());
+
+ return isolate->native_context()->ordinary_has_instance();
+}
RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
HandleScope scope(isolate);
diff --git a/src/runtime/runtime-interpreter.cc b/src/runtime/runtime-interpreter.cc
index 7150a8b..22ae911 100644
--- a/src/runtime/runtime-interpreter.cc
+++ b/src/runtime/runtime-interpreter.cc
@@ -16,30 +16,6 @@
namespace v8 {
namespace internal {
-RUNTIME_FUNCTION(Runtime_InterpreterToBoolean) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_CHECKED(Object, x, 0);
- return isolate->heap()->ToBoolean(x->BooleanValue());
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterLogicalNot) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_CHECKED(Object, x, 0);
- return isolate->heap()->ToBoolean(!x->BooleanValue());
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterTypeOf) {
- HandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- return Object::cast(*Object::TypeOf(isolate, x));
-}
-
-
RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
@@ -52,10 +28,24 @@
namespace {
+void AdvanceToOffsetForTracing(
+ interpreter::BytecodeArrayIterator& bytecode_iterator, int offset) {
+ while (bytecode_iterator.current_offset() +
+ bytecode_iterator.current_bytecode_size() <=
+ offset) {
+ bytecode_iterator.Advance();
+ }
+ DCHECK(bytecode_iterator.current_offset() == offset ||
+ ((bytecode_iterator.current_offset() + 1) == offset &&
+ bytecode_iterator.current_operand_scale() >
+ interpreter::OperandScale::kSingle));
+}
+
void PrintRegisters(std::ostream& os, bool is_input,
- Handle<BytecodeArray> bytecode_array, int bytecode_offset,
+ interpreter::BytecodeArrayIterator& bytecode_iterator,
Handle<Object> accumulator) {
- static const int kRegFieldWidth = static_cast<int>(strlen("accumulator"));
+ static const char kAccumulator[] = "accumulator";
+ static const int kRegFieldWidth = static_cast<int>(sizeof(kAccumulator) - 1);
static const char* kInputColourCode = "\033[0;36m";
static const char* kOutputColourCode = "\033[0;35m";
static const char* kNormalColourCode = "\033[0;m";
@@ -64,22 +54,24 @@
os << (is_input ? kInputColourCode : kOutputColourCode);
}
+ interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
+
// Print accumulator.
- os << " [ accumulator" << kArrowDirection;
- accumulator->ShortPrint();
- os << " ]" << std::endl;
+ if ((is_input && interpreter::Bytecodes::ReadsAccumulator(bytecode)) ||
+ (!is_input && interpreter::Bytecodes::WritesAccumulator(bytecode))) {
+ os << " [ " << kAccumulator << kArrowDirection;
+ accumulator->ShortPrint();
+ os << " ]" << std::endl;
+ }
// Find the location of the register file.
- JavaScriptFrameIterator frame_iterator(bytecode_array->GetIsolate());
+ JavaScriptFrameIterator frame_iterator(
+ bytecode_iterator.bytecode_array()->GetIsolate());
JavaScriptFrame* frame = frame_iterator.frame();
Address register_file =
frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp;
// Print the registers.
- interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
- bytecode_iterator.set_current_offset(
- bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag);
- interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
for (int operand_index = 0; operand_index < operand_count; operand_index++) {
interpreter::OperandType operand_type =
@@ -98,7 +90,7 @@
Object* reg_object = Memory::Object_at(reg_location);
os << " [ " << std::setw(kRegFieldWidth)
<< interpreter::Register(reg_index).ToString(
- bytecode_array->parameter_count())
+ bytecode_iterator.bytecode_array()->parameter_count())
<< kArrowDirection;
reg_object->ShortPrint(os);
os << " ]" << std::endl;
@@ -120,20 +112,23 @@
CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
OFStream os(stdout);
- // Print bytecode.
- const uint8_t* bytecode_address =
- reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset;
- Vector<char> buf = Vector<char>::New(50);
- SNPrintF(buf, "%p", bytecode_address);
- os << " -> " << buf.start() << " (" << bytecode_offset << ") : ";
- interpreter::Bytecodes::Decode(os, bytecode_address,
- bytecode_array->parameter_count());
- os << std::endl;
+ int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
+ interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
+ AdvanceToOffsetForTracing(bytecode_iterator, offset);
+ if (offset == bytecode_iterator.current_offset()) {
+ // Print bytecode.
+ const uint8_t* bytecode_address =
+ reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset;
+ os << " -> " << static_cast<const void*>(bytecode_address)
+ << " (" << bytecode_offset << ") : ";
+ interpreter::Bytecodes::Decode(os, bytecode_address,
+ bytecode_array->parameter_count());
+ os << std::endl;
+ // Print all input registers and accumulator.
+ PrintRegisters(os, true, bytecode_iterator, accumulator);
- // Print all input registers and accumulator.
- PrintRegisters(os, true, bytecode_array, bytecode_offset, accumulator);
-
- os << std::flush;
+ os << std::flush;
+ }
return isolate->heap()->undefined_value();
}
@@ -143,11 +138,21 @@
CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
- OFStream os(stdout);
- // Print all output registers and accumulator.
- PrintRegisters(os, false, bytecode_array, bytecode_offset, accumulator);
- os << std::flush;
+ int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
+ interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
+ AdvanceToOffsetForTracing(bytecode_iterator, offset);
+ // The offset comparison here ensures registers only printed when the
+ // (potentially) widened bytecode has completed. The iterator reports
+ // the offset as the offset of the prefix bytecode.
+ if (bytecode_iterator.current_operand_scale() ==
+ interpreter::OperandScale::kSingle ||
+ offset > bytecode_iterator.current_offset()) {
+ OFStream os(stdout);
+ // Print all output registers and accumulator.
+ PrintRegisters(os, false, bytecode_iterator, accumulator);
+ os << std::flush;
+ }
return isolate->heap()->undefined_value();
}
diff --git a/src/runtime/runtime-literals.cc b/src/runtime/runtime-literals.cc
index e730957..f14a7cf 100644
--- a/src/runtime/runtime-literals.cc
+++ b/src/runtime/runtime-literals.cc
@@ -16,7 +16,7 @@
static Handle<Map> ComputeObjectLiteralMap(
Handle<Context> context, Handle<FixedArray> constant_properties,
- bool is_strong, bool* is_result_from_cache) {
+ bool* is_result_from_cache) {
int properties_length = constant_properties->length();
int number_of_properties = properties_length / 2;
@@ -30,18 +30,16 @@
}
Isolate* isolate = context->GetIsolate();
return isolate->factory()->ObjectLiteralMapFromCache(
- context, number_of_properties, is_strong, is_result_from_cache);
+ context, number_of_properties, is_result_from_cache);
}
MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals,
- Handle<FixedArray> constant_properties, bool is_strong);
-
+ Handle<FixedArray> constant_properties);
MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals,
- Handle<FixedArray> constant_properties, bool should_have_fast_elements,
- bool has_function_literal, bool is_strong) {
+ Handle<FixedArray> constant_properties, bool should_have_fast_elements) {
Handle<Context> context = isolate->native_context();
// In case we have function literals, we want the object to be in
@@ -49,12 +47,8 @@
// maps with constant functions can't be shared if the functions are
// not the same (which is the common case).
bool is_result_from_cache = false;
- Handle<Map> map = has_function_literal
- ? Handle<Map>(is_strong
- ? context->js_object_strong_map()
- : context->object_function()->initial_map())
- : ComputeObjectLiteralMap(context, constant_properties, is_strong,
- &is_result_from_cache);
+ Handle<Map> map = ComputeObjectLiteralMap(context, constant_properties,
+ &is_result_from_cache);
PretenureFlag pretenure_flag =
isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
@@ -69,7 +63,7 @@
int length = constant_properties->length();
bool should_transform =
!is_result_from_cache && boilerplate->HasFastProperties();
- bool should_normalize = should_transform || has_function_literal;
+ bool should_normalize = should_transform;
if (should_normalize) {
// TODO(verwaest): We might not want to ever normalize here.
JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES,
@@ -84,44 +78,22 @@
// simple object or array literal.
Handle<FixedArray> array = Handle<FixedArray>::cast(value);
ASSIGN_RETURN_ON_EXCEPTION(
- isolate, value,
- CreateLiteralBoilerplate(isolate, literals, array, is_strong),
+ isolate, value, CreateLiteralBoilerplate(isolate, literals, array),
Object);
}
MaybeHandle<Object> maybe_result;
uint32_t element_index = 0;
- if (key->IsInternalizedString()) {
- if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
- // Array index as string (uint32).
- if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
- maybe_result = JSObject::SetOwnElementIgnoreAttributes(
- boilerplate, element_index, value, NONE);
- } else {
- Handle<String> name(String::cast(*key));
- DCHECK(!name->AsArrayIndex(&element_index));
- maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
- boilerplate, name, value, NONE);
- }
- } else if (key->ToArrayIndex(&element_index)) {
+ if (key->ToArrayIndex(&element_index)) {
// Array index (uint32).
if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
maybe_result = JSObject::SetOwnElementIgnoreAttributes(
boilerplate, element_index, value, NONE);
} else {
- // Non-uint32 number.
- DCHECK(key->IsNumber());
- double num = key->Number();
- char arr[100];
- Vector<char> buffer(arr, arraysize(arr));
- const char* str = DoubleToCString(num, buffer);
- Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
+ Handle<String> name = Handle<String>::cast(key);
+ DCHECK(!name->AsArrayIndex(&element_index));
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
- // the handle based operations. In that case, we need to
- // convert back to an exception.
RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
}
@@ -129,7 +101,7 @@
// containing function literals we defer this operation until after all
// computed properties have been assigned so that we can generate
// constant function properties.
- if (should_transform && !has_function_literal) {
+ if (should_transform) {
JSObject::MigrateSlowToFast(boilerplate,
boilerplate->map()->unused_property_fields(),
"FastLiteral");
@@ -137,10 +109,9 @@
return boilerplate;
}
-
MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals,
- Handle<FixedArray> elements, bool is_strong) {
+ Handle<FixedArray> elements) {
// Create the JSArray.
Handle<JSFunction> constructor = isolate->array_function();
@@ -159,9 +130,8 @@
DisallowHeapAllocation no_gc;
DCHECK(IsFastElementsKind(constant_elements_kind));
Context* native_context = isolate->context()->native_context();
- Strength strength = is_strong ? Strength::STRONG : Strength::WEAK;
- Object* map = native_context->get(
- Context::ArrayMapIndex(constant_elements_kind, strength));
+ Object* map =
+ native_context->get(Context::ArrayMapIndex(constant_elements_kind));
object->set_map(Map::cast(map));
}
@@ -188,20 +158,20 @@
Handle<FixedArray> fixed_array_values_copy =
isolate->factory()->CopyFixedArray(fixed_array_values);
copied_elements_values = fixed_array_values_copy;
- for (int i = 0; i < fixed_array_values->length(); i++) {
- HandleScope scope(isolate);
- if (fixed_array_values->get(i)->IsFixedArray()) {
- // The value contains the constant_properties of a
- // simple object or array literal.
- Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result,
- CreateLiteralBoilerplate(isolate, literals, fa, is_strong),
- Object);
- fixed_array_values_copy->set(i, *result);
- }
- }
+ FOR_WITH_HANDLE_SCOPE(
+ isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
+ if (fixed_array_values->get(i)->IsFixedArray()) {
+ // The value contains the constant_properties of a
+ // simple object or array literal.
+ Handle<FixedArray> fa(
+ FixedArray::cast(fixed_array_values->get(i)));
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ CreateLiteralBoilerplate(isolate, literals, fa), Object);
+ fixed_array_values_copy->set(i, *result);
+ }
+ });
}
}
object->set_elements(*copied_elements_values);
@@ -211,22 +181,18 @@
return object;
}
-
MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
- Isolate* isolate, Handle<LiteralsArray> literals, Handle<FixedArray> array,
- bool is_strong) {
+ Isolate* isolate, Handle<LiteralsArray> literals,
+ Handle<FixedArray> array) {
Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
- const bool kHasNoFunctionLiteral = false;
switch (CompileTimeValue::GetLiteralType(array)) {
case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
- return CreateObjectLiteralBoilerplate(isolate, literals, elements, true,
- kHasNoFunctionLiteral, is_strong);
+ return CreateObjectLiteralBoilerplate(isolate, literals, elements, true);
case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
- return CreateObjectLiteralBoilerplate(isolate, literals, elements, false,
- kHasNoFunctionLiteral, is_strong);
+ return CreateObjectLiteralBoilerplate(isolate, literals, elements, false);
case CompileTimeValue::ARRAY_LITERAL:
return Runtime::CreateArrayLiteralBoilerplate(isolate, literals,
- elements, is_strong);
+ elements);
default:
UNREACHABLE();
return MaybeHandle<Object>();
@@ -262,9 +228,7 @@
CONVERT_SMI_ARG_CHECKED(flags, 3);
Handle<LiteralsArray> literals(closure->literals(), isolate);
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
- bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
- bool is_strong = (flags & ObjectLiteral::kIsStrong) != 0;
RUNTIME_ASSERT(literals_index >= 0 &&
literals_index < literals->literals_count());
@@ -278,8 +242,7 @@
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, raw_boilerplate,
CreateObjectLiteralBoilerplate(isolate, literals, constant_properties,
- should_have_fast_elements,
- has_function_literal, is_strong));
+ should_have_fast_elements));
boilerplate = Handle<JSObject>::cast(raw_boilerplate);
AllocationSiteCreationContext creation_context(isolate);
@@ -306,10 +269,9 @@
return *copy;
}
-
MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
- Handle<FixedArray> elements, bool is_strong) {
+ Handle<FixedArray> elements) {
// Check if boilerplate exists. If not, create it first.
Handle<Object> literal_site(literals->literal(literals_index), isolate);
Handle<AllocationSite> site;
@@ -318,8 +280,7 @@
Handle<Object> boilerplate;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, boilerplate,
- Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements,
- is_strong),
+ Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
AllocationSite);
AllocationSiteCreationContext creation_context(isolate);
@@ -346,11 +307,9 @@
literals_index >= 0 && literals_index < literals->literals_count(),
JSObject);
Handle<AllocationSite> site;
- bool is_strong = (flags & ArrayLiteral::kIsStrong) != 0;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, site,
- GetLiteralAllocationSite(isolate, literals, literals_index, elements,
- is_strong),
+ GetLiteralAllocationSite(isolate, literals, literals_index, elements),
JSObject);
bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
diff --git a/src/runtime/runtime-liveedit.cc b/src/runtime/runtime-liveedit.cc
index 189ec08..da342de 100644
--- a/src/runtime/runtime-liveedit.cc
+++ b/src/runtime/runtime-liveedit.cc
@@ -186,7 +186,7 @@
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_ASSERT(SharedInfoWrapper::IsInstance(shared_array));
LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
return isolate->heap()->undefined_value();
@@ -207,19 +207,21 @@
USE(new_shared_array);
RUNTIME_ASSERT(old_shared_array->length()->IsSmi());
RUNTIME_ASSERT(new_shared_array->length() == old_shared_array->length());
- RUNTIME_ASSERT(old_shared_array->HasFastElements())
- RUNTIME_ASSERT(new_shared_array->HasFastElements())
+ RUNTIME_ASSERT(old_shared_array->HasFastElements());
+ RUNTIME_ASSERT(new_shared_array->HasFastElements());
int array_length = Smi::cast(old_shared_array->length())->value();
for (int i = 0; i < array_length; i++) {
Handle<Object> old_element;
Handle<Object> new_element;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, old_element, Object::GetElement(isolate, old_shared_array, i));
+ isolate, old_element,
+ JSReceiver::GetElement(isolate, old_shared_array, i));
RUNTIME_ASSERT(
old_element->IsJSValue() &&
Handle<JSValue>::cast(old_element)->value()->IsSharedFunctionInfo());
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, new_element, Object::GetElement(isolate, new_shared_array, i));
+ isolate, new_element,
+ JSReceiver::GetElement(isolate, new_shared_array, i));
RUNTIME_ASSERT(
new_element->IsUndefined() ||
(new_element->IsJSValue() &&
@@ -242,7 +244,7 @@
CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
Handle<JSArray> result = LiveEdit::CompareStrings(s1, s2);
- uint32_t array_length;
+ uint32_t array_length = 0;
CHECK(result->length()->ToArrayLength(&array_length));
if (array_length > 0) {
isolate->debug()->feature_tracker()->Track(DebugFeatureTracker::kLiveEdit);
diff --git a/src/runtime/runtime-maths.cc b/src/runtime/runtime-maths.cc
index 9c4fde1..91b6181 100644
--- a/src/runtime/runtime-maths.cc
+++ b/src/runtime/runtime-maths.cc
@@ -23,9 +23,6 @@
return *isolate->factory()->NewHeapNumber(std::name(x)); \
}
-RUNTIME_UNARY_MATH(Acos, acos)
-RUNTIME_UNARY_MATH(Asin, asin)
-RUNTIME_UNARY_MATH(Atan, atan)
RUNTIME_UNARY_MATH(LogRT, log)
#undef RUNTIME_UNARY_MATH
@@ -111,27 +108,6 @@
}
-RUNTIME_FUNCTION(Runtime_MathClz32) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- isolate->counters()->math_clz32_runtime()->Increment();
-
- CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
- return *isolate->factory()->NewNumberFromUint(
- base::bits::CountLeadingZeros32(x));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathFloor) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- isolate->counters()->math_floor_runtime()->Increment();
-
- CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- 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(Runtime_MathPow) {
@@ -174,75 +150,21 @@
}
-RUNTIME_FUNCTION(Runtime_RoundNumber) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
- isolate->counters()->math_round_runtime()->Increment();
-
- if (!input->IsHeapNumber()) {
- DCHECK(input->IsSmi());
- return *input;
- }
-
- Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
-
- double value = number->value();
- int exponent = number->get_exponent();
- int sign = number->get_sign();
-
- if (exponent < -1) {
- // Number in range ]-0.5..0.5[. These always round to +/-zero.
- if (sign) return isolate->heap()->minus_zero_value();
- return Smi::FromInt(0);
- }
-
- // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
- // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
- // argument holds for 32-bit smis).
- if (!sign && exponent < kSmiValueSize - 2) {
- return Smi::FromInt(static_cast<int>(value + 0.5));
- }
-
- // If the magnitude is big enough, there's no place for fraction part. If we
- // try to add 0.5 to this number, 1.0 will be added instead.
- if (exponent >= 52) {
- return *number;
- }
-
- if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
-
- // Do not call NumberFromDouble() to avoid extra checks.
- return *isolate->factory()->NewNumber(Floor(value + 0.5));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathSqrt) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- isolate->counters()->math_sqrt_runtime()->Increment();
-
- CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- lazily_initialize_fast_sqrt(isolate);
- return *isolate->factory()->NewNumber(fast_sqrt(x, isolate));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathFround) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
-
- CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- float xf = DoubleToFloat32(x);
- return *isolate->factory()->NewNumber(xf);
-}
-
-
RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
- // Random numbers in the snapshot are not really that random.
- DCHECK(!isolate->bootstrapper()->IsActive());
+ if (isolate->serializer_enabled()) {
+ // Random numbers in the snapshot are not really that random. And we cannot
+ // return a typed array as it cannot be serialized. To make calling
+ // Math.random possible when creating a custom startup snapshot, we simply
+ // return a normal array with a single random number.
+ Handle<HeapNumber> random_number = isolate->factory()->NewHeapNumber(
+ isolate->random_number_generator()->NextDouble());
+ Handle<FixedArray> array_backing = isolate->factory()->NewFixedArray(1);
+ array_backing->set(0, *random_number);
+ return *isolate->factory()->NewJSArrayWithElements(array_backing);
+ }
+
static const int kState0Offset = 0;
static const int kState1Offset = 1;
static const int kRandomBatchSize = 64;
diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc
index 46fbff3..efbdeb2 100644
--- a/src/runtime/runtime-numbers.cc
+++ b/src/runtime/runtime-numbers.cc
@@ -208,19 +208,6 @@
}
-RUNTIME_FUNCTION(Runtime_NumberImul) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
-
- // 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);
-}
-
-
// Compare two Smis as if they were converted to strings and then
// compared lexicographically.
RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
index 45a4992..5bdb085 100644
--- a/src/runtime/runtime-object.cc
+++ b/src/runtime/runtime-object.cc
@@ -125,6 +125,82 @@
return JSReceiver::DeleteProperty(&it, language_mode);
}
+// ES6 19.1.3.2
+RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
+ HandleScope scope(isolate);
+ Handle<Object> property = args.at<Object>(1);
+
+ Handle<Name> key;
+ uint32_t index;
+ bool key_is_array_index = property->ToArrayIndex(&index);
+
+ if (!key_is_array_index) {
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
+ Object::ToName(isolate, property));
+ key_is_array_index = key->AsArrayIndex(&index);
+ }
+
+ Handle<Object> object = args.at<Object>(0);
+
+ if (object->IsJSObject()) {
+ Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
+ // 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.
+ // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
+ // handle all cases directly (without this custom fast path).
+ {
+ LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
+ LookupIterator it =
+ key_is_array_index ? LookupIterator(isolate, js_obj, index, js_obj, c)
+ : LookupIterator(js_obj, key, js_obj, c);
+ Maybe<bool> maybe = JSReceiver::HasProperty(&it);
+ if (maybe.IsNothing()) return isolate->heap()->exception();
+ DCHECK(!isolate->has_pending_exception());
+ if (maybe.FromJust()) return isolate->heap()->true_value();
+ }
+
+ Map* map = js_obj->map();
+ if (!map->has_hidden_prototype() &&
+ (key_is_array_index ? !map->has_indexed_interceptor()
+ : !map->has_named_interceptor())) {
+ return isolate->heap()->false_value();
+ }
+
+ // Slow case.
+ LookupIterator::Configuration c = LookupIterator::HIDDEN;
+ LookupIterator it = key_is_array_index
+ ? LookupIterator(isolate, js_obj, index, js_obj, c)
+ : LookupIterator(js_obj, key, js_obj, c);
+
+ Maybe<bool> maybe = JSReceiver::HasProperty(&it);
+ if (maybe.IsNothing()) return isolate->heap()->exception();
+ DCHECK(!isolate->has_pending_exception());
+ return isolate->heap()->ToBoolean(maybe.FromJust());
+
+ } else if (object->IsJSProxy()) {
+ if (key.is_null()) {
+ DCHECK(key_is_array_index);
+ key = isolate->factory()->Uint32ToString(index);
+ }
+
+ Maybe<bool> result =
+ JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+
+ } else if (object->IsString()) {
+ return isolate->heap()->ToBoolean(
+ key_is_array_index
+ ? index < static_cast<uint32_t>(String::cast(*object)->length())
+ : key->Equals(isolate->heap()->length_string()));
+ } else if (object->IsNull() || object->IsUndefined()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
+ }
+
+ return isolate->heap()->false_value();
+}
MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object,
@@ -205,7 +281,7 @@
Factory* factory = isolate->factory();
// Get attributes.
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name,
+ LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name, obj,
LookupIterator::HIDDEN);
Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
@@ -293,7 +369,7 @@
Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
Handle<JSGlobalObject> global_object(script_context->global_object(),
isolate);
- LookupIterator it(global_object, name, LookupIterator::HIDDEN);
+ LookupIterator it(global_object, name, global_object, LookupIterator::HIDDEN);
// Switch to fast mode only if there is a data property and it's not on
// a hidden prototype.
@@ -328,7 +404,7 @@
Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
Handle<JSGlobalObject> global_object(script_context->global_object(),
isolate);
- LookupIterator it(global_object, name, LookupIterator::HIDDEN);
+ LookupIterator it(global_object, name, global_object, LookupIterator::HIDDEN);
// Switch to fast mode only if there is a data property and it's not on
// a hidden prototype.
@@ -413,7 +489,7 @@
#ifdef DEBUG
uint32_t index = 0;
DCHECK(!name->ToArrayIndex(&index));
- LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
+ LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
RUNTIME_ASSERT(!it.IsFound());
@@ -441,7 +517,7 @@
CHECK(key->ToArrayIndex(&index));
#ifdef DEBUG
- LookupIterator it(isolate, object, index,
+ LookupIterator it(isolate, object, index, object,
LookupIterator::OWN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
@@ -532,85 +608,6 @@
}
-static Object* HasOwnPropertyImplementation(Isolate* isolate,
- Handle<JSObject> object,
- Handle<Name> key) {
- Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
- if (!maybe.IsJust()) return isolate->heap()->exception();
- if (maybe.FromJust()) 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.
- if (object->map()->has_hidden_prototype()) {
- PrototypeIterator iter(isolate, object);
- DCHECK(!iter.IsAtEnd());
-
- // TODO(verwaest): The recursion is not necessary for keys that are array
- // indices. Removing this.
- // Casting to JSObject is fine because JSProxies are never used as
- // hidden prototypes.
- return HasOwnPropertyImplementation(
- isolate, PrototypeIterator::GetCurrent<JSObject>(iter), key);
- }
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
- CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
- uint32_t index;
- const bool key_is_array_index = key->AsArrayIndex(&index);
-
- // Only JS objects can have properties.
- if (object->IsJSObject()) {
- Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
- // 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.
- // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
- // handle all cases directly (without this custom fast path).
- Maybe<bool> maybe = Nothing<bool>();
- if (key_is_array_index) {
- LookupIterator it(js_obj->GetIsolate(), js_obj, index,
- LookupIterator::HIDDEN);
- maybe = JSReceiver::HasProperty(&it);
- } else {
- maybe = JSObject::HasRealNamedProperty(js_obj, key);
- }
- if (!maybe.IsJust()) return isolate->heap()->exception();
- DCHECK(!isolate->has_pending_exception());
- if (maybe.FromJust()) {
- return isolate->heap()->true_value();
- }
- Map* map = js_obj->map();
- if (!key_is_array_index && !map->has_named_interceptor() &&
- !map->has_hidden_prototype()) {
- return isolate->heap()->false_value();
- }
- // Slow case.
- return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj),
- Handle<Name>(key));
- } else if (object->IsString() && key_is_array_index) {
- // Well, there is one exception: Handle [] on strings.
- Handle<String> string = Handle<String>::cast(object);
- if (index < static_cast<uint32_t>(string->length())) {
- return isolate->heap()->true_value();
- }
- } else if (object->IsJSProxy()) {
- Maybe<bool> result =
- JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
- if (!result.IsJust()) return isolate->heap()->exception();
- return isolate->heap()->ToBoolean(result.FromJust());
- }
- return isolate->heap()->false_value();
-}
-
-
// ES6 section 12.9.3, operator in.
RUNTIME_FUNCTION(Runtime_HasProperty) {
HandleScope scope(isolate);
@@ -840,8 +837,8 @@
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name,
- LookupIterator::OWN);
+ LookupIterator it = LookupIterator::PropertyOrElement(
+ isolate, object, name, object, LookupIterator::OWN);
if (it.state() == LookupIterator::ACCESS_CHECK && !it.HasAccess()) {
return isolate->heap()->undefined_value();
}
@@ -869,8 +866,8 @@
isolate->factory()->empty_string());
}
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name,
- LookupIterator::OWN);
+ LookupIterator it = LookupIterator::PropertyOrElement(
+ isolate, object, name, object, LookupIterator::OWN);
// Cannot fail since this should only be called when
// creating an object literal.
CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
@@ -915,15 +912,6 @@
}
-RUNTIME_FUNCTION(Runtime_IsStrong) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(Object, obj, 0);
- return isolate->heap()->ToBoolean(obj->IsJSReceiver() &&
- JSReceiver::cast(obj)->map()->is_strong());
-}
-
-
RUNTIME_FUNCTION(Runtime_ClassOf) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
@@ -1118,6 +1106,9 @@
RUNTIME_FUNCTION(Runtime_InstanceOf) {
+ // TODO(4447): Remove this function when ES6 instanceof ships for good.
+ DCHECK(!FLAG_harmony_instanceof);
+
// ECMA-262, section 11.8.6, page 54.
HandleScope shs(isolate);
DCHECK_EQ(2, args.length());
@@ -1146,7 +1137,50 @@
Handle<Object> prototype;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, prototype,
- Object::GetProperty(callable, isolate->factory()->prototype_string()));
+ JSReceiver::GetProperty(Handle<JSReceiver>::cast(callable),
+ isolate->factory()->prototype_string()));
+ if (!prototype->IsJSReceiver()) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate,
+ NewTypeError(MessageTemplate::kInstanceofNonobjectProto, prototype));
+ }
+ // Return whether or not {prototype} is in the prototype chain of {object}.
+ Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
+ Maybe<bool> result =
+ JSReceiver::HasInPrototypeChain(isolate, receiver, prototype);
+ MAYBE_RETURN(result, isolate->heap()->exception());
+ return isolate->heap()->ToBoolean(result.FromJust());
+}
+
+RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) {
+ // ES6 section 19.2.3.6 Function.prototype[@@hasInstance](V)
+ HandleScope shs(isolate);
+ DCHECK_EQ(2, args.length());
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, callable, 1);
+ // {callable} must have a [[Call]] internal method.
+ if (!callable->IsCallable()) {
+ return isolate->heap()->false_value();
+ }
+ // If {object} is not a receiver, return false.
+ if (!object->IsJSReceiver()) {
+ return isolate->heap()->false_value();
+ }
+ // Check if {callable} is bound, if so, get [[BoundTargetFunction]] from it
+ // and use that instead of {callable}.
+ while (callable->IsJSBoundFunction()) {
+ callable =
+ handle(Handle<JSBoundFunction>::cast(callable)->bound_target_function(),
+ isolate);
+ }
+ DCHECK(callable->IsCallable());
+ // Get the "prototype" of {callable}; raise an error if it's not a receiver.
+ Handle<Object> prototype;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, prototype,
+ JSReceiver::GetProperty(Handle<JSReceiver>::cast(callable),
+ isolate->factory()->prototype_string()));
if (!prototype->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
diff --git a/src/runtime/runtime-regexp.cc b/src/runtime/runtime-regexp.cc
index df86aa8..aead017 100644
--- a/src/runtime/runtime-regexp.cc
+++ b/src/runtime/runtime-regexp.cc
@@ -642,7 +642,7 @@
// TODO(hpayer): We should shrink the large object page if the size
// of the object changed significantly.
if (!heap->lo_space()->Contains(*answer)) {
- heap->CreateFillerObjectAt(end_of_string, delta);
+ heap->CreateFillerObjectAt(end_of_string, delta, ClearRecordedSlots::kNo);
}
heap->AdjustLiveBytes(*answer, -delta, Heap::CONCURRENT_TO_SWEEPER);
return *answer;
@@ -734,9 +734,9 @@
// Create JSArray of substrings separated by separator.
int part_count = indices.length();
- Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
- JSObject::EnsureCanContainHeapObjectElements(result);
- result->set_length(Smi::FromInt(part_count));
+ Handle<JSArray> result =
+ isolate->factory()->NewJSArray(FAST_ELEMENTS, part_count, part_count,
+ INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
DCHECK(result->HasFastObjectElements());
@@ -746,14 +746,13 @@
elements->set(0, *subject);
} else {
int part_start = 0;
- for (int i = 0; i < part_count; i++) {
- HandleScope local_loop_handle(isolate);
+ FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < part_count, i++, {
int part_end = indices.at(i);
Handle<String> substring =
isolate->factory()->NewProperSubString(subject, part_start, part_end);
elements->set(i, *substring);
part_start = part_end + pattern_length;
- }
+ });
}
if (limit == 0xffffffffu) {
diff --git a/src/runtime/runtime-scopes.cc b/src/runtime/runtime-scopes.cc
index a8f3a74..de0d66a 100644
--- a/src/runtime/runtime-scopes.cc
+++ b/src/runtime/runtime-scopes.cc
@@ -44,7 +44,8 @@
}
// Do the lookup own properties only, see ES5 erratum.
- LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+ LookupIterator it(global, name, global,
+ LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
@@ -102,8 +103,7 @@
// Traverse the name/value pairs and set the properties.
int length = pairs->length();
- for (int i = 0; i < length; i += 2) {
- HandleScope scope(isolate);
+ FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 2, {
Handle<String> name(String::cast(pairs->get(i)));
Handle<Object> initial_value(pairs->get(i + 1), isolate);
@@ -142,7 +142,7 @@
static_cast<PropertyAttributes>(attr),
is_var, is_const, is_function);
if (isolate->has_pending_exception()) return result;
- }
+ });
return isolate->heap()->undefined_value();
}
@@ -182,7 +182,8 @@
Handle<JSGlobalObject> global = isolate->global_object();
// Lookup the property as own on the global object.
- LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+ LookupIterator it(global, name, global,
+ LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
DCHECK(maybe.IsJust());
PropertyAttributes old_attributes = maybe.FromJust();
@@ -394,7 +395,8 @@
// code can run in between that modifies the declared property.
DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
- LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+ LookupIterator it(holder, name, Handle<JSReceiver>::cast(holder),
+ LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
PropertyAttributes old_attributes = maybe.FromJust();
@@ -640,9 +642,9 @@
base::SmartArrayPointer<Handle<Object>> arguments =
GetCallerArguments(isolate, &argument_count);
int num_elements = std::max(0, argument_count - start_index);
- Handle<JSObject> result = isolate->factory()->NewJSArray(
- FAST_ELEMENTS, num_elements, num_elements, Strength::WEAK,
- DONT_INITIALIZE_ARRAY_ELEMENTS);
+ Handle<JSObject> result =
+ isolate->factory()->NewJSArray(FAST_ELEMENTS, num_elements, num_elements,
+ DONT_INITIALIZE_ARRAY_ELEMENTS);
{
DisallowHeapAllocation no_gc;
FixedArray* elements = FixedArray::cast(result->elements());
@@ -708,7 +710,7 @@
}
if (IsLexicalVariableMode(mode)) {
- LookupIterator it(global_object, name,
+ LookupIterator it(global_object, name, global_object,
LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
if (!maybe.IsJust()) return isolate->heap()->exception();
diff --git a/src/runtime/runtime-strings.cc b/src/runtime/runtime-strings.cc
index fcec47d..6786fa9 100644
--- a/src/runtime/runtime-strings.cc
+++ b/src/runtime/runtime-strings.cc
@@ -371,14 +371,13 @@
Handle<String> substring =
isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
elements->set(0, *substring);
- for (int i = 1; i < matches; i++) {
- HandleScope temp_scope(isolate);
+ FOR_WITH_HANDLE_SCOPE(isolate, int, i = 1, i, i < matches, i++, {
int from = offsets.at(i * 2);
int to = offsets.at(i * 2 + 1);
Handle<String> substring =
isolate->factory()->NewProperSubString(subject, from, to);
elements->set(i, *substring);
- }
+ });
Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
result->set_length(Smi::FromInt(matches));
return *result;
@@ -557,6 +556,7 @@
RUNTIME_ASSERT(fixed_array->get(0)->IsString());
String* first = String::cast(fixed_array->get(0));
String* separator_raw = *separator;
+
int first_length = first->length();
String::WriteToFlat(first, sink, 0, first_length);
sink += first_length;
@@ -580,6 +580,26 @@
return *answer;
}
+template <typename sinkchar>
+static void WriteRepeatToFlat(String* src, Vector<sinkchar> buffer, int cursor,
+ int repeat, int length) {
+ if (repeat == 0) return;
+
+ sinkchar* start = &buffer[cursor];
+ String::WriteToFlat<sinkchar>(src, start, 0, length);
+
+ int done = 1;
+ sinkchar* next = start + length;
+
+ while (done < repeat) {
+ int block = Min(done, repeat - done);
+ int block_chars = block * length;
+ CopyChars(next, start, block_chars);
+ next += block_chars;
+ done += block;
+ }
+}
+
template <typename Char>
static void JoinSparseArrayWithSeparator(FixedArray* elements,
int elements_length,
@@ -589,34 +609,30 @@
DisallowHeapAllocation no_gc;
int previous_separator_position = 0;
int separator_length = separator->length();
+ DCHECK_LT(0, separator_length);
int cursor = 0;
for (int i = 0; i < elements_length; i += 2) {
int position = NumberToInt32(elements->get(i));
String* string = String::cast(elements->get(i + 1));
int string_length = string->length();
if (string->length() > 0) {
- while (previous_separator_position < position) {
- String::WriteToFlat<Char>(separator, &buffer[cursor], 0,
- separator_length);
- cursor += separator_length;
- previous_separator_position++;
- }
+ int repeat = position - previous_separator_position;
+ WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat,
+ separator_length);
+ cursor += repeat * separator_length;
+ previous_separator_position = position;
String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length);
cursor += string->length();
}
}
- 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.
- 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], 0,
- separator_length);
- cursor += separator_length;
- previous_separator_position++;
- }
- }
+
+ int last_array_index = static_cast<int>(array_length - 1);
+ // Array length must be representable as a signed 32-bit number,
+ // otherwise the total string length would have been too large.
+ DCHECK(array_length <= 0x7fffffff); // Is int32_t.
+ int repeat = last_array_index - previous_separator_position;
+ WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length);
+ cursor += repeat * separator_length;
DCHECK(cursor <= buffer.length());
}
@@ -642,13 +658,6 @@
RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
RUNTIME_ASSERT((elements_length & 1) == 0); // Even length.
FixedArray* elements = FixedArray::cast(elements_array->elements());
- for (int i = 0; i < elements_length; i += 2) {
- RUNTIME_ASSERT(elements->get(i)->IsNumber());
- CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
- RUNTIME_ASSERT(position < array_length);
- RUNTIME_ASSERT(elements->get(i + 1)->IsString());
- }
-
{
DisallowHeapAllocation no_gc;
for (int i = 0; i < elements_length; i += 2) {
@@ -1145,24 +1154,93 @@
return *result;
}
-
-RUNTIME_FUNCTION(Runtime_StringEquals) {
+RUNTIME_FUNCTION(Runtime_StringLessThan) {
HandleScope handle_scope(isolate);
- DCHECK(args.length() == 2);
-
+ DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
-
- bool not_equal = !String::Equals(x, y);
- // 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.
- DCHECK(not_equal == 0 || not_equal == 1);
- STATIC_ASSERT(EQUAL == 0);
- STATIC_ASSERT(NOT_EQUAL == 1);
- return Smi::FromInt(not_equal);
+ switch (String::Compare(x, y)) {
+ case ComparisonResult::kLessThan:
+ return isolate->heap()->true_value();
+ case ComparisonResult::kEqual:
+ case ComparisonResult::kGreaterThan:
+ return isolate->heap()->false_value();
+ case ComparisonResult::kUndefined:
+ break;
+ }
+ UNREACHABLE();
+ return Smi::FromInt(0);
}
+RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) {
+ HandleScope handle_scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+ switch (String::Compare(x, y)) {
+ case ComparisonResult::kEqual:
+ case ComparisonResult::kLessThan:
+ return isolate->heap()->true_value();
+ case ComparisonResult::kGreaterThan:
+ return isolate->heap()->false_value();
+ case ComparisonResult::kUndefined:
+ break;
+ }
+ UNREACHABLE();
+ return Smi::FromInt(0);
+}
+
+RUNTIME_FUNCTION(Runtime_StringGreaterThan) {
+ HandleScope handle_scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+ switch (String::Compare(x, y)) {
+ case ComparisonResult::kGreaterThan:
+ return isolate->heap()->true_value();
+ case ComparisonResult::kEqual:
+ case ComparisonResult::kLessThan:
+ return isolate->heap()->false_value();
+ case ComparisonResult::kUndefined:
+ break;
+ }
+ UNREACHABLE();
+ return Smi::FromInt(0);
+}
+
+RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) {
+ HandleScope handle_scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+ switch (String::Compare(x, y)) {
+ case ComparisonResult::kEqual:
+ case ComparisonResult::kGreaterThan:
+ return isolate->heap()->true_value();
+ case ComparisonResult::kLessThan:
+ return isolate->heap()->false_value();
+ case ComparisonResult::kUndefined:
+ break;
+ }
+ UNREACHABLE();
+ return Smi::FromInt(0);
+}
+
+RUNTIME_FUNCTION(Runtime_StringEqual) {
+ HandleScope handle_scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+ return isolate->heap()->ToBoolean(String::Equals(x, y));
+}
+
+RUNTIME_FUNCTION(Runtime_StringNotEqual) {
+ HandleScope handle_scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+ return isolate->heap()->ToBoolean(!String::Equals(x, y));
+}
RUNTIME_FUNCTION(Runtime_FlattenString) {
HandleScope scope(isolate);
diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc
index 5f27a60..a0f0566 100644
--- a/src/runtime/runtime-test.cc
+++ b/src/runtime/runtime-test.cc
@@ -398,7 +398,7 @@
DCHECK(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
- if (!Compiler::Compile(func, KEEP_EXCEPTION)) {
+ if (!Compiler::Compile(func, Compiler::KEEP_EXCEPTION)) {
return isolate->heap()->exception();
}
OFStream os(stdout);
@@ -503,5 +503,14 @@
TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
+
+
+RUNTIME_FUNCTION(Runtime_SpeciesProtector) {
+ SealHandleScope shs(isolate);
+ DCHECK_EQ(0, args.length());
+ return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact());
+}
+
+
} // namespace internal
} // namespace v8
diff --git a/src/runtime/runtime-utils.h b/src/runtime/runtime-utils.h
index c673b5a..17c78d5 100644
--- a/src/runtime/runtime-utils.h
+++ b/src/runtime/runtime-utils.h
@@ -5,19 +5,49 @@
#ifndef V8_RUNTIME_RUNTIME_UTILS_H_
#define V8_RUNTIME_RUNTIME_UTILS_H_
+#include "src/base/logging.h"
#include "src/runtime/runtime.h"
namespace v8 {
namespace internal {
-#define RUNTIME_ASSERT(value) \
- if (!(value)) return isolate->ThrowIllegalOperation();
+#ifdef DEBUG
+
+#define RUNTIME_ASSERT(value) \
+ do { \
+ if (!(value)) { \
+ V8_RuntimeError(__FILE__, __LINE__, #value); \
+ return isolate->ThrowIllegalOperation(); \
+ } \
+ } while (0)
+
+#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
+ do { \
+ if (!(value)) { \
+ V8_RuntimeError(__FILE__, __LINE__, #value); \
+ isolate->ThrowIllegalOperation(); \
+ return MaybeHandle<T>(); \
+ } \
+ } while (0)
+
+#else
+
+#define RUNTIME_ASSERT(value) \
+ do { \
+ if (!(value)) { \
+ return isolate->ThrowIllegalOperation(); \
+ } \
+ } while (0)
#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
- if (!(value)) { \
- isolate->ThrowIllegalOperation(); \
- return MaybeHandle<T>(); \
- }
+ do { \
+ if (!(value)) { \
+ isolate->ThrowIllegalOperation(); \
+ return MaybeHandle<T>(); \
+ } \
+ } while (0)
+
+#endif
// Cast the given object to a value of the specified type and store
// it in a variable with the given name. If the object is not of the
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index 7019c3b..dc1678b 100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -35,7 +35,6 @@
F(FinishArrayPrototypeSetup, 1, 1) \
F(SpecialArrayFunctions, 0, 1) \
F(TransitionElementsKind, 2, 1) \
- F(PushIfAbsent, 2, 1) \
F(RemoveArrayHoles, 2, 1) \
F(MoveArrayContents, 2, 1) \
F(EstimateNumberOfElements, 1, 1) \
@@ -43,6 +42,7 @@
F(ArrayConstructor, -1, 1) \
F(NewArray, -1 /* >= 3 */, 1) \
F(InternalArrayConstructor, -1, 1) \
+ F(ArrayPush, -1, 1) \
F(NormalizeElements, 1, 1) \
F(GrowArrayElements, 2, 1) \
F(HasComplexElements, 1, 1) \
@@ -53,7 +53,6 @@
F(FixedArraySet, 3, 1) \
F(ArraySpeciesConstructor, 1, 1)
-
#define FOR_EACH_INTRINSIC_ATOMICS(F) \
F(AtomicsCompareExchange, 4, 1) \
F(AtomicsLoad, 2, 1) \
@@ -138,10 +137,10 @@
F(DateCurrentTime, 0, 1) \
F(ThrowNotDateError, 0, 1)
-
#define FOR_EACH_INTRINSIC_DEBUG(F) \
F(HandleDebuggerStatement, 0, 1) \
- F(DebugBreak, 0, 1) \
+ F(DebugBreak, 1, 1) \
+ F(DebugBreakOnBytecode, 1, 1) \
F(SetDebugEventListener, 2, 1) \
F(ScheduleBreak, 0, 1) \
F(DebugGetInternalProperties, 1, 1) \
@@ -156,7 +155,6 @@
F(GetFrameCount, 1, 1) \
F(GetFrameDetails, 2, 1) \
F(GetScopeCount, 2, 1) \
- F(GetStepInPositions, 2, 1) \
F(GetScopeDetails, 4, 1) \
F(GetAllScopesDetails, 4, 1) \
F(GetFunctionScopeCount, 1, 1) \
@@ -192,12 +190,10 @@
F(DebugPrepareStepInIfStepping, 1, 1) \
F(DebugPushPromise, 2, 1) \
F(DebugPopPromise, 0, 1) \
- F(DebugPromiseEvent, 1, 1) \
F(DebugAsyncTaskEvent, 1, 1) \
F(DebugIsActive, 0, 1) \
F(DebugBreakInOptimizedCode, 0, 1)
-
#define FOR_EACH_INTRINSIC_FORIN(F) \
F(ForInDone, 2, 1) \
F(ForInEnumerate, 1, 1) \
@@ -206,9 +202,6 @@
F(ForInStep, 1, 1)
#define FOR_EACH_INTRINSIC_INTERPRETER(F) \
- F(InterpreterToBoolean, 1, 1) \
- F(InterpreterLogicalNot, 1, 1) \
- F(InterpreterTypeOf, 1, 1) \
F(InterpreterNewClosure, 2, 1) \
F(InterpreterTraceBytecodeEntry, 3, 1) \
F(InterpreterTraceBytecodeExit, 3, 1) \
@@ -223,18 +216,16 @@
F(FunctionGetSourceCode, 1, 1) \
F(FunctionGetScriptSourcePosition, 1, 1) \
F(FunctionGetPositionForOffset, 2, 1) \
+ F(FunctionGetContextData, 1, 1) \
F(FunctionSetInstanceClassName, 2, 1) \
F(FunctionSetLength, 2, 1) \
F(FunctionSetPrototype, 2, 1) \
F(FunctionIsAPIFunction, 1, 1) \
F(SetCode, 2, 1) \
F(SetNativeFlag, 1, 1) \
- F(ThrowStrongModeTooFewArguments, 0, 1) \
F(IsConstructor, 1, 1) \
F(SetForceInlineFlag, 1, 1) \
F(Call, -1 /* >= 2 */, 1) \
- F(TailCall, -1 /* >= 2 */, 1) \
- F(Apply, 5, 1) \
F(ConvertReceiver, 1, 1) \
F(IsFunction, 1, 1) \
F(FunctionToString, 1, 1)
@@ -245,7 +236,6 @@
F(ResumeJSGeneratorObject, 3, 1) \
F(GeneratorClose, 1, 1) \
F(GeneratorGetFunction, 1, 1) \
- F(GeneratorGetContext, 1, 1) \
F(GeneratorGetReceiver, 1, 1) \
F(GeneratorGetInput, 1, 1) \
F(GeneratorGetContinuation, 1, 1) \
@@ -284,7 +274,6 @@
#define FOR_EACH_INTRINSIC_I18N(F)
#endif
-
#define FOR_EACH_INTRINSIC_INTERNAL(F) \
F(CheckIsBootstrapping, 0, 1) \
F(ExportFromRuntime, 1, 1) \
@@ -302,7 +291,6 @@
F(ThrowIllegalInvocation, 0, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowStackOverflow, 0, 1) \
- F(ThrowStrongModeImplicitConversion, 0, 1) \
F(PromiseRejectEvent, 3, 1) \
F(PromiseRevokeReject, 1, 1) \
F(StackGuard, 0, 1) \
@@ -324,15 +312,14 @@
F(CallSiteIsEvalRT, 1, 1) \
F(CallSiteIsConstructorRT, 1, 1) \
F(IS_VAR, 1, 1) \
- F(IncrementStatsCounter, 1, 1) \
F(ThrowConstructedNonConstructable, 1, 1) \
F(ThrowDerivedConstructorReturnedNonObject, 0, 1) \
F(ThrowCalledNonCallable, 1, 1) \
F(CreateListFromArrayLike, 1, 1) \
F(IncrementUseCounter, 1, 1) \
+ F(GetOrdinaryHasInstance, 0, 1) \
F(GetAndResetRuntimeCallStats, 0, 1)
-
#define FOR_EACH_INTRINSIC_JSON(F) \
F(QuoteJSONString, 1, 1) \
F(BasicJSONStringify, 1, 1) \
@@ -361,9 +348,6 @@
#define FOR_EACH_INTRINSIC_MATHS(F) \
- F(MathAcos, 1, 1) \
- F(MathAsin, 1, 1) \
- F(MathAtan, 1, 1) \
F(MathLogRT, 1, 1) \
F(DoubleHi, 1, 1) \
F(DoubleLo, 1, 1) \
@@ -371,13 +355,8 @@
F(RemPiO2, 2, 1) \
F(MathAtan2, 2, 1) \
F(MathExpRT, 1, 1) \
- F(MathClz32, 1, 1) \
- F(MathFloor, 1, 1) \
F(MathPow, 2, 1) \
F(MathPowRT, 2, 1) \
- F(RoundNumber, 1, 1) \
- F(MathSqrt, 1, 1) \
- F(MathFround, 1, 1) \
F(GenerateRandomNumbers, 1, 1)
@@ -394,7 +373,6 @@
F(NumberToStringSkipCache, 1, 1) \
F(NumberToIntegerMapMinusZero, 1, 1) \
F(NumberToSmi, 1, 1) \
- F(NumberImul, 2, 1) \
F(SmiLexicographicCompare, 2, 1) \
F(MaxSmi, 0, 1) \
F(IsSmi, 1, 1) \
@@ -404,6 +382,7 @@
#define FOR_EACH_INTRINSIC_OBJECT(F) \
F(GetPrototype, 1, 1) \
+ F(ObjectHasOwnProperty, 2, 1) \
F(InternalSetPrototype, 2, 1) \
F(SetPrototype, 2, 1) \
F(GetOwnProperty_Legacy, 2, 1) \
@@ -419,7 +398,6 @@
F(AppendElement, 2, 1) \
F(DeleteProperty_Sloppy, 2, 1) \
F(DeleteProperty_Strict, 2, 1) \
- F(HasOwnProperty, 2, 1) \
F(HasProperty, 2, 1) \
F(PropertyIsEnumerable, 2, 1) \
F(GetOwnPropertyKeys, 2, 1) \
@@ -440,7 +418,6 @@
F(HasFastPackedElements, 1, 1) \
F(ValueOf, 1, 1) \
F(IsJSReceiver, 1, 1) \
- F(IsStrong, 1, 1) \
F(ClassOf, 1, 1) \
F(DefineGetterPropertyUnchecked, 4, 1) \
F(DefineSetterPropertyUnchecked, 4, 1) \
@@ -457,6 +434,7 @@
F(SameValueZero, 2, 1) \
F(Compare, 3, 1) \
F(InstanceOf, 2, 1) \
+ F(OrdinaryHasInstance, 2, 1) \
F(HasInPrototypeChain, 2, 1) \
F(CreateIterResultObject, 2, 1) \
F(IsAccessCheckNeeded, 1, 1) \
@@ -854,7 +832,6 @@
F(Bool8x16Equal, 2, 1) \
F(Bool8x16NotEqual, 2, 1)
-
#define FOR_EACH_INTRINSIC_STRINGS(F) \
F(StringReplaceOneCharWithString, 3, 1) \
F(StringIndexOf, 3, 1) \
@@ -875,7 +852,12 @@
F(StringTrim, 3, 1) \
F(TruncateString, 2, 1) \
F(NewString, 2, 1) \
- F(StringEquals, 2, 1) \
+ F(StringLessThan, 2, 1) \
+ F(StringLessThanOrEqual, 2, 1) \
+ F(StringGreaterThan, 2, 1) \
+ F(StringGreaterThanOrEqual, 2, 1) \
+ F(StringEqual, 2, 1) \
+ F(StringNotEqual, 2, 1) \
F(FlattenString, 1, 1) \
F(StringCharFromCode, 1, 1) \
F(StringCharAt, 2, 1) \
@@ -885,7 +867,6 @@
F(TwoByteSeqStringSetChar, 3, 1) \
F(StringCharCodeAt, 2, 1)
-
#define FOR_EACH_INTRINSIC_SYMBOL(F) \
F(CreateSymbol, 1, 1) \
F(CreatePrivateSymbol, 1, 1) \
@@ -941,7 +922,8 @@
F(HasFixedInt32Elements, 1, 1) \
F(HasFixedFloat32Elements, 1, 1) \
F(HasFixedFloat64Elements, 1, 1) \
- F(HasFixedUint8ClampedElements, 1, 1)
+ F(HasFixedUint8ClampedElements, 1, 1) \
+ F(SpeciesProtector, 0, 1)
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
F(ArrayBufferGetByteLength, 1, 1) \
@@ -995,7 +977,6 @@
F(BinaryOpIC_MissWithAllocationSite, 3, 1) \
F(CallIC_Miss, 3, 1) \
F(CompareIC_Miss, 3, 1) \
- F(CompareNilIC_Miss, 1, 1) \
F(ElementsTransitionAndStoreIC_Miss, 5, 1) \
F(KeyedLoadIC_Miss, 4, 1) \
F(KeyedLoadIC_MissFromStubFailure, 4, 1) \
@@ -1151,7 +1132,7 @@
// Used in runtime.cc and hydrogen's VisitArrayLiteral.
MUST_USE_RESULT static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals,
- Handle<FixedArray> elements, bool is_strong);
+ Handle<FixedArray> elements);
static MaybeHandle<JSArray> GetInternalProperties(Isolate* isolate,
Handle<Object>);