void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
// Stack layout on entry.
- // sp[0] : index of rest parameter
- // sp[4] : number of parameters
- // sp[8] : receiver displacement
+ // sp[0] : language mode
+ // sp[4] : index of rest parameter
+ // sp[8] : number of parameters
+ // sp[12] : receiver displacement
Label runtime;
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
// Patch the arguments.length and the parameters pointer.
__ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ str(r1, MemOperand(sp, 1 * kPointerSize));
+ __ str(r1, MemOperand(sp, 2 * kPointerSize));
__ add(r3, r2, Operand::PointerOffsetFromSmiKey(r1));
__ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
- __ str(r3, MemOperand(sp, 2 * kPointerSize));
+ __ str(r3, MemOperand(sp, 3 * kPointerSize));
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
__ add(r3, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset));
__ mov(r2, Operand(Smi::FromInt(num_parameters)));
__ mov(r1, Operand(Smi::FromInt(rest_index)));
- __ Push(r3, r2, r1);
+ __ mov(r0, Operand(Smi::FromInt(language_mode())));
+ __ Push(r3, r2, r1, r0);
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
// Stack layout on entry.
- // jssp[0]: index of rest parameter (tagged)
- // jssp[8]: number of parameters (tagged)
- // jssp[16]: address of receiver argument
+ // jssp[0]: language mode (tagged)
+ // jssp[8]: index of rest parameter (tagged)
+ // jssp[16]: number of parameters (tagged)
+ // jssp[24]: address of receiver argument
//
// Returns pointer to result object in x0.
// Get the stub arguments from the frame, and make an untagged copy of the
// parameter count.
- Register rest_index_smi = x1;
- Register param_count_smi = x2;
- Register params = x3;
+ Register language_mode_smi = x1;
+ Register rest_index_smi = x2;
+ Register param_count_smi = x3;
+ Register params = x4;
Register param_count = x13;
- __ Pop(rest_index_smi, param_count_smi, params);
+ __ Pop(language_mode_smi, rest_index_smi, param_count_smi, params);
__ SmiUntag(param_count, param_count_smi);
// Test if arguments adaptor needed.
__ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ B(ne, &runtime);
- // x1 rest_index_smi index of rest parameter
- // x2 param_count_smi number of parameters passed to function (smi)
- // x3 params pointer to parameters
- // x11 caller_fp caller's frame pointer
- // x13 param_count number of parameters passed to function
+ // x1 language_mode_smi language mode
+ // x2 rest_index_smi index of rest parameter
+ // x3 param_count_smi number of parameters passed to function (smi)
+ // x4 params pointer to parameters
+ // x11 caller_fp caller's frame pointer
+ // x13 param_count number of parameters passed to function
// Patch the argument length and parameters pointer.
__ Ldr(param_count_smi,
__ Add(params, x10, StandardFrameConstants::kCallerSPOffset);
__ Bind(&runtime);
- __ Push(params, param_count_smi, rest_index_smi);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ Push(params, param_count_smi, rest_index_smi, language_mode_smi);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
__ Add(x3, fp, StandardFrameConstants::kCallerSPOffset + offset);
__ Mov(x2, Smi::FromInt(num_parameters));
__ Mov(x1, Smi::FromInt(rest_index));
- __ Push(x3, x2, x1);
+ __ Mov(x0, Smi::FromInt(language_mode()));
+ __ Push(x3, x2, x1, x0);
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
ArrayStorageAllocationMode mode =
has_double && IsFastObjectElementsKind(elements_kind)
? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
- Handle<JSArray> result_array =
- isolate->factory()->NewJSArray(elements_kind,
- result_len,
- result_len,
- mode);
+ Handle<JSArray> result_array = isolate->factory()->NewJSArray(
+ elements_kind, result_len, result_len, WEAK, mode);
if (result_len == 0) return *result_array;
int j = 0;
if (rest == NULL) return NULL;
DCHECK(index >= 0);
- const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 1);
- Node* object = NewNode(op, jsgraph()->SmiConstant(index));
+ const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 2);
+ Node* object = NewNode(op, jsgraph()->SmiConstant(index),
+ jsgraph()->SmiConstant(language_mode()));
// Assign the object to the rest array
DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
// Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
// initial length limit for arrays with "fast" elements kind.
+ // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub.
if ((flags & ArrayLiteral::kShallowElements) != 0 &&
+ (flags & ArrayLiteral::kIsStrong) == 0 &&
length < JSObject::kInitialMaxFastElementArray) {
Isolate* isolate = jsgraph()->isolate();
Callable callable = CodeFactory::FastCloneShallowArray(isolate);
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
+ ObjectStrength strength,
PretenureFlag pretenure) {
- Context* native_context = isolate()->context()->native_context();
- JSFunction* array_function = native_context->array_function();
- Map* map = array_function->initial_map();
- Map* transition_map = isolate()->get_initial_js_array_map(elements_kind);
- if (transition_map != NULL) map = transition_map;
+ Map* map = isolate()->get_initial_js_array_map(elements_kind, strength);
+ if (map == nullptr) {
+ DCHECK(strength == WEAK);
+ Context* native_context = isolate()->context()->native_context();
+ JSFunction* array_function = native_context->array_function();
+ map = array_function->initial_map();
+ }
return Handle<JSArray>::cast(NewJSObjectFromMap(handle(map), pretenure));
}
-Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
- int length,
- int capacity,
+Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
+ int capacity, ObjectStrength strength,
ArrayStorageAllocationMode mode,
PretenureFlag pretenure) {
- Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
+ Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
NewJSArrayStorage(array, length, capacity, mode);
return array;
}
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
ElementsKind elements_kind,
int length,
+ ObjectStrength strength,
PretenureFlag pretenure) {
DCHECK(length <= elements->length());
- Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
+ Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
array->set_elements(*elements);
array->set_length(Smi::FromInt(length));
// Create a JSArray with no elements.
Handle<JSArray> NewJSArray(
ElementsKind elements_kind,
+ ObjectStrength strength = WEAK,
PretenureFlag pretenure = NOT_TENURED);
// Create a JSArray with a specified length and elements initialized
// according to the specified mode.
Handle<JSArray> NewJSArray(
ElementsKind elements_kind, int length, int capacity,
+ ObjectStrength strength = WEAK,
ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
PretenureFlag pretenure = NOT_TENURED);
Handle<JSArray> NewJSArray(
int capacity,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
+ ObjectStrength strength = WEAK,
PretenureFlag pretenure = NOT_TENURED) {
if (capacity != 0) {
elements_kind = GetHoleyElementsKind(elements_kind);
}
- return NewJSArray(elements_kind, 0, capacity,
+ return NewJSArray(elements_kind, 0, capacity, strength,
INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, pretenure);
}
Handle<FixedArrayBase> elements,
ElementsKind elements_kind,
int length,
+ ObjectStrength strength = WEAK,
PretenureFlag pretenure = NOT_TENURED);
Handle<JSArray> NewJSArrayWithElements(
Handle<FixedArrayBase> elements,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
+ ObjectStrength strength = WEAK,
PretenureFlag pretenure = NOT_TENURED) {
- return NewJSArrayWithElements(
- elements, elements_kind, elements->length(), pretenure);
+ return NewJSArrayWithElements(elements, elements_kind, elements->length(),
+ strength, pretenure);
}
void NewJSArrayStorage(
bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime(
ArrayLiteral* expr) const {
- return expr->depth() > 1 ||
+ // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub.
+ return expr->depth() > 1 || expr->is_strong() ||
expr->values()->length() > JSObject::kInitialMaxFastElementArray;
}
// -----------------------------------------------------------------------------
// Declarations for use in both the preparser and the rest of V8.
+enum ObjectStrength {
+ WEAK,
+ FIRM // strong object
+};
+
// The Strict Mode (ECMA-262 5th edition, 4.2.2).
enum LanguageMode {
}
+inline ObjectStrength strength(LanguageMode language_mode) {
+ return is_strong(language_mode) ? FIRM : WEAK;
+}
+
+
// Mask for the sign bit in a smi.
const intptr_t kSmiSignMask = kIntptrSignBit;
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
// esp[0] : return address
- // esp[4] : index of rest parameter
- // esp[8] : number of parameters
- // esp[12] : receiver displacement
+ // esp[4] : language mode
+ // esp[8] : index of rest parameter
+ // esp[12] : number of parameters
+ // esp[16] : receiver displacement
// Check if the calling frame is an arguments adaptor frame.
Label runtime;
// Patch the arguments.length and the parameters pointer.
__ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ mov(Operand(esp, 2 * kPointerSize), ecx);
+ __ mov(Operand(esp, 3 * kPointerSize), ecx);
__ lea(edx, Operand(edx, ecx, times_2,
StandardFrameConstants::kCallerSPOffset));
- __ mov(Operand(esp, 3 * kPointerSize), edx);
+ __ mov(Operand(esp, 4 * kPointerSize), edx);
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
__ push(edx);
__ push(Immediate(Smi::FromInt(num_parameters)));
__ push(Immediate(Smi::FromInt(rest_index)));
+ __ push(Immediate(Smi::FromInt(language_mode())));
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
}
-Map* Isolate::get_initial_js_array_map(ElementsKind kind) {
+Map* Isolate::get_initial_js_array_map(ElementsKind kind,
+ ObjectStrength strength) {
Context* native_context = context()->native_context();
- Object* maybe_map_array = native_context->js_array_maps();
+ Object* maybe_map_array = strength ? native_context->js_array_strong_maps()
+ : native_context->js_array_maps();
if (!maybe_map_array->IsUndefined()) {
Object* maybe_transitioned_map =
FixedArray::cast(maybe_map_array)->get(kind);
date_cache_ = date_cache;
}
- Map* get_initial_js_array_map(ElementsKind kind);
+ Map* get_initial_js_array_map(ElementsKind kind,
+ ObjectStrength strength = WEAK);
static const int kArrayProtectorValid = 1;
static const int kArrayProtectorInvalid = 0;
fast_elements->set(i, *elements[i]);
}
Handle<Object> json_array = factory()->NewJSArrayWithElements(
- fast_elements, FAST_ELEMENTS, pretenure_);
+ fast_elements, FAST_ELEMENTS, WEAK, pretenure_);
return scope.CloseAndEscape(json_array);
}
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
- // sp[0] : index of rest parameter
- // sp[4] : number of parameters
- // sp[8] : receiver displacement
+ // sp[0] : language mode
+ // sp[4] : index of rest parameter
+ // sp[8] : number of parameters
+ // sp[12] : receiver displacement
// Check if the calling frame is an arguments adaptor frame.
Label runtime;
// Patch the arguments.length and the parameters pointer.
__ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ sw(a1, MemOperand(sp, 1 * kPointerSize));
+ __ sw(a1, MemOperand(sp, 2 * kPointerSize));
__ sll(at, a1, kPointerSizeLog2 - kSmiTagSize);
__ Addu(a3, a2, Operand(at));
__ Addu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset));
- __ sw(a3, MemOperand(sp, 2 * kPointerSize));
+ __ sw(a3, MemOperand(sp, 3 * kPointerSize));
// Do the runtime call to allocate the arguments object.
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
Operand(StandardFrameConstants::kCallerSPOffset + offset));
__ li(a2, Operand(Smi::FromInt(num_parameters)));
__ li(a1, Operand(Smi::FromInt(rest_index)));
- __ Push(a3, a2, a1);
+ __ li(a0, Operand(Smi::FromInt(language_mode())));
+ __ Push(a3, a2, a1, a0);
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
- // sp[0] : index of rest parameter
- // sp[4] : number of parameters
- // sp[8] : receiver displacement
+ // sp[0] : language mode
+ // sp[4] : index of rest parameter
+ // sp[8] : number of parameters
+ // sp[12] : receiver displacement
// Check if the calling frame is an arguments adaptor frame.
Label runtime;
// Patch the arguments.length and the parameters pointer.
__ ld(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ sd(a1, MemOperand(sp, 1 * kPointerSize));
+ __ sd(a1, MemOperand(sp, 2 * kPointerSize));
__ SmiScale(at, a1, kPointerSizeLog2);
__ Daddu(a3, a2, Operand(at));
__ Daddu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset));
- __ sd(a3, MemOperand(sp, 2 * kPointerSize));
+ __ sd(a3, MemOperand(sp, 3 * kPointerSize));
// Do the runtime call to allocate the arguments object.
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
Operand(StandardFrameConstants::kCallerSPOffset + offset));
__ li(a2, Operand(Smi::FromInt(num_parameters)));
__ li(a1, Operand(Smi::FromInt(rest_index)));
- __ Push(a3, a2, a1);
+ __ li(a0, Operand(Smi::FromInt(language_mode())));
+ __ Push(a3, a2, a1, a0);
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
// Stack layout on entry.
- // sp[0] : index of rest parameter
- // sp[4] : number of parameters
- // sp[8] : receiver displacement
+ // sp[0] : language mode
+ // sp[4] : index of rest parameter
+ // sp[8] : number of parameters
+ // sp[12] : receiver displacement
Label runtime;
__ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
// Patch the arguments.length and the parameters pointer.
__ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ StoreP(r4, MemOperand(sp, 1 * kPointerSize));
+ __ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
__ SmiToPtrArrayOffset(r6, r4);
__ add(r6, r5, r6);
__ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset));
- __ StoreP(r6, MemOperand(sp, 2 * kPointerSize));
+ __ StoreP(r6, MemOperand(sp, 3 * kPointerSize));
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
__ addi(r6, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset));
__ mov(r5, Operand(Smi::FromInt(num_parameters)));
__ mov(r4, Operand(Smi::FromInt(rest_index)));
- __ Push(r6, r5, r4);
+ __ mov(r7, Operand(Smi::FromInt(language_mode())));
+ __ Push(r6, r5, r4, r7);
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
}
-static Handle<JSArray> NewRestParam(Isolate* isolate,
- Object** parameters,
- int num_params,
- int rest_index) {
+static Handle<JSArray> NewRestParam(Isolate* isolate, Object** parameters,
+ int num_params, int rest_index,
+ LanguageMode language_mode) {
parameters -= rest_index;
int num_elements = std::max(0, num_params - rest_index);
Handle<FixedArray> elements =
for (int i = 0; i < num_elements; ++i) {
elements->set(i, *--parameters);
}
- return isolate->factory()->NewJSArrayWithElements(elements, FAST_ELEMENTS,
- num_elements);
+ return isolate->factory()->NewJSArrayWithElements(
+ elements, FAST_ELEMENTS, num_elements, strength(language_mode));
}
RUNTIME_FUNCTION(Runtime_NewRestParam) {
HandleScope scope(isolate);
- DCHECK(args.length() == 3);
+ DCHECK(args.length() == 4);
Object** parameters = reinterpret_cast<Object**>(args[0]);
CONVERT_SMI_ARG_CHECKED(num_params, 1);
CONVERT_SMI_ARG_CHECKED(rest_index, 2);
+ CONVERT_SMI_ARG_CHECKED(language_mode, 3);
- return *NewRestParam(isolate, parameters, num_params, rest_index);
+ return *NewRestParam(isolate, parameters, num_params, rest_index,
+ static_cast<LanguageMode>(language_mode));
}
RUNTIME_FUNCTION(Runtime_NewRestParamSlow) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
+ DCHECK(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(rest_index, 0);
+ CONVERT_SMI_ARG_CHECKED(language_mode, 1);
JavaScriptFrameIterator it(isolate);
int argument_count = frame->GetArgumentsLength();
Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
- return *NewRestParam(isolate, parameters, argument_count, rest_index);
+ return *NewRestParam(isolate, parameters, argument_count, rest_index,
+ static_cast<LanguageMode>(language_mode));
}
F(NewArguments, 1, 1) /* TODO(turbofan): Only temporary */ \
F(NewSloppyArguments, 3, 1) \
F(NewStrictArguments, 3, 1) \
- F(NewRestParam, 3, 1) \
- F(NewRestParamSlow, 1, 1) \
+ F(NewRestParam, 4, 1) \
+ F(NewRestParamSlow, 2, 1) \
F(NewClosureFromStubFailure, 1, 1) \
F(NewClosure, 3, 1) \
F(NewScriptContext, 2, 1) \
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
// rsp[0] : return address
- // rsp[8] : index of rest parameter
- // rsp[16] : number of parameters
- // rsp[24] : receiver displacement
+ // rsp[8] : language mode
+ // rsp[16] : index of rest parameter
+ // rsp[24] : number of parameters
+ // rsp[32] : receiver displacement
// Check if the calling frame is an arguments adaptor frame.
Label runtime;
__ j(not_equal, &runtime);
// Patch the arguments.length and the parameters pointer.
- StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ StackArgumentsAccessor args(rsp, 4, ARGUMENTS_DONT_CONTAIN_RECEIVER);
__ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ movp(args.GetArgumentOperand(1), rcx);
__ SmiToInteger64(rcx, rcx);
__ movp(args.GetArgumentOperand(0), rdx);
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
__ Push(rdx);
__ Push(Smi::FromInt(num_parameters));
__ Push(Smi::FromInt(rest_index));
+ __ Push(Smi::FromInt(language_mode()));
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
// esp[0] : return address
- // esp[4] : index of rest parameter
- // esp[8] : number of parameters
- // esp[12] : receiver displacement
+ // esp[4] : language mode
+ // esp[8] : index of rest parameter
+ // esp[12] : number of parameters
+ // esp[16] : receiver displacement
// Check if the calling frame is an arguments adaptor frame.
Label runtime;
// Patch the arguments.length and the parameters pointer.
__ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ mov(Operand(esp, 2 * kPointerSize), ecx);
+ __ mov(Operand(esp, 3 * kPointerSize), ecx);
__ lea(edx, Operand(edx, ecx, times_2,
StandardFrameConstants::kCallerSPOffset));
- __ mov(Operand(esp, 3 * kPointerSize), edx);
+ __ mov(Operand(esp, 4 * kPointerSize), edx);
__ bind(&runtime);
- __ TailCallRuntime(Runtime::kNewRestParam, 3, 1);
+ __ TailCallRuntime(Runtime::kNewRestParam, 4, 1);
}
__ push(edx);
__ push(Immediate(Smi::FromInt(num_parameters)));
__ push(Immediate(Smi::FromInt(rest_index)));
+ __ push(Immediate(Smi::FromInt(language_mode())));
RestParamAccessStub stub(isolate());
__ CallStub(&stub);
// Allocate a JS array to OLD_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewJSArray(10);
- objs[next_objs_index++] = factory->NewJSArray(10,
- FAST_HOLEY_ELEMENTS,
- TENURED);
+ objs[next_objs_index++] =
+ factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
{
AlwaysAllocateScope always_allocate(isolate);
SimulateFullSpace(space);
- prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ prototype =
+ factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
}
// Add a prototype on an evacuation candidate and verify that transition
JSArray::kSize + AllocationMemento::kSize +
kPointerSize);
- Handle<JSArray> array = factory->NewJSArrayWithElements(array_data,
- FAST_SMI_ELEMENTS,
- NOT_TENURED);
+ Handle<JSArray> array =
+ factory->NewJSArrayWithElements(array_data, FAST_SMI_ELEMENTS);
CHECK_EQ(Smi::FromInt(2), array->length());
CHECK(array->HasFastSmiOrObjectElements());
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, WEAK, NOT_TENURED);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
AlwaysAllocateScope always_allocate(isolate);
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ obj_value =
+ factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
}
CHECK(isolate->heap()->old_space()->Contains(*obj));
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, WEAK, NOT_TENURED);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ obj_value =
+ factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
CHECK_NE(ec_page, Page::FromAddress(obj->address()));
}
// Flags: --strong-mode --allow-natives-syntax
// Flags: --harmony-arrow-functions --harmony-rest-parameters
-// Flags: --harmony-destructuring
+// Flags: --harmony-destructuring --harmony-spread-arrays
'use strict';
-let GeneratorFunctionPrototype = (function*(){}).__proto__;
-
-function assertStrongObject(o) {
- assertTrue(%IsStrong(o));
- assertSame(Object.prototype, o.__proto__);
-}
-
-function assertStrongArray(a) {
- assertTrue(%IsStrong(a));
- assertSame(Array.prototype, a.__proto__);
-}
-
-function assertStrongFunction(f) {
- assertTrue(%IsStrong(f));
- assertSame(Function.prototype, f.__proto__);
-}
-
-function assertStrongGenerator(g) {
- assertTrue(%IsStrong(g));
- assertSame(GeneratorFunctionPrototype, g.__proto__);
-}
-
(function WeakObjectLiterals() {
- assertTrue(!%IsStrong({}));
- assertTrue(!%IsStrong({a: 0, b: 0}));
- assertTrue(!%IsStrong({a: [], b: {}}));
- assertTrue(!%IsStrong({a: [], b: {}}.a));
- assertTrue(!%IsStrong({a: [], b: {}}.b));
- assertTrue(!%IsStrong({a: {b: {c: {}}}}.a));
- assertTrue(!%IsStrong({a: {b: {c: {}}}}.a.b));
- assertTrue(!%IsStrong({a: {b: {c: {}}}}.a.b.c));
- assertTrue(!%IsStrong({f: function(){}}));
- assertTrue(!%IsStrong(Realm.eval(Realm.current(),
- "({f: function(){}})")));
+ function assertWeakObject(x) {
+ assertFalse(%IsStrong(x));
+ assertSame(Object.prototype, Object.getPrototypeOf(x));
+ }
+ assertWeakObject({});
+ assertWeakObject({a: 0, b: 0});
+ assertWeakObject({a: [], b: {}});
+ assertWeakObject({a: [], b: {}}.b);
+ assertWeakObject({a: {b: {c: {}}}}.a);
+ assertWeakObject({a: {b: {c: {}}}}.a.b);
+ assertWeakObject({a: {b: {c: {}}}}.a.b.c);
+ assertWeakObject([[1], {}, [[3]]][1]);
+ assertWeakObject({f: function(){}});
+ assertWeakObject(
+ Realm.eval(Realm.current(), "({f: function(){}})"));
})();
(function StrongObjectLiterals() {
'use strong';
+ function assertStrongObject(x) {
+ assertTrue(%IsStrong(x));
+ assertSame(Object.prototype, Object.getPrototypeOf(x));
+ }
assertStrongObject({});
assertStrongObject({a: 0, b: 0});
assertStrongObject({a: [], b: {}});
- assertStrongArray({a: [], b: {}}.a);
assertStrongObject({a: [], b: {}}.b);
assertStrongObject({a: {b: {c: {}}}}.a);
assertStrongObject({a: {b: {c: {}}}}.a.b);
x191: 0, x192: 0, x193: 0, x194: 0, x195: 0,
x196: 0, x197: 0, x198: 0, x199: 0, x200: 0,
});
+ assertStrongObject([[1], {}, [[3]]][1]);
assertStrongObject({[Date() + ""]: 0, [Symbol()]: 0});
assertStrongObject({m() { super.m() }});
+ assertTrue(%IsStrong({__proto__: {}, get a() {}, set b(x) {}}));
// Object literals with constant functions are treated specially,
// but currently only on the toplevel (using Realm.eval to emulate that).
assertStrongObject({f: function(){}});
- assertStrongObject(Realm.eval(Realm.current(),
- "'use strong'; ({f: function(){}})"));
- assertTrue(%IsStrong({__proto__: {}, get a() {}, set b(x) {}}));
+ assertStrongObject(
+ Realm.eval(Realm.current(), "'use strong'; ({f: function(){}})"));
})();
(function WeakArrayLiterals(...args) {
+ function assertWeakArray(x) {
+ assertFalse(%IsStrong(x));
+ assertSame(Array.prototype, Object.getPrototypeOf(x));
+ }
let [...r] = [];
- assertTrue(!%IsStrong(args));
- assertTrue(!%IsStrong(r));
- assertTrue(!%IsStrong([]));
- assertTrue(!%IsStrong([1, 2, 3]));
- assertTrue(!%IsStrong([[[]]]));
- assertTrue(!%IsStrong([[1], {}, [[3]]]));
- assertTrue(!%IsStrong([[1], {}, [[3]]][0]));
- assertTrue(!%IsStrong([[1], {}, [[3]]][1]));
- assertTrue(!%IsStrong([[1], {}, [[3]]][2]));
- assertTrue(!%IsStrong([[1], {}, [[3]]][2][0]));
+ assertWeakArray(args);
+ assertWeakArray(r);
+ assertWeakArray([]);
+ assertWeakArray([1, 2, 3]);
+ assertWeakArray([1, 2, ...[3, 4], 5]);
+ assertWeakArray([[[]]]);
+ assertWeakArray([[1], {}, [[3]]]);
+ assertWeakArray([[1], {}, [[3]]][0]);
+ assertWeakArray([[1], {}, [[3]]][2]);
+ assertWeakArray([[1], {}, [[3]]][2][0]);
+ assertWeakArray({a: [], b: {}}.a);
})();
(function StrongArrayLiterals(...args) {
'use strong';
+ function assertStrongArray(x) {
+ assertTrue(%IsStrong(x));
+ assertSame(Array.prototype, Object.getPrototypeOf(x));
+ }
let [...r] = [];
- // TODO(rossberg): teach strongness to FastCloneShallowArrayStub
- // assertTrue(%IsStrong(args));
- // assertTrue(%IsStrong(r));
- // assertTrue(%IsStrong([]));
- // assertTrue(%IsStrong([1, 2, 3]));
- // assertTrue(%IsStrong([1, 2, ...[3, 4], 5]));
+ assertStrongArray(args);
+ assertStrongArray(r);
+ assertStrongArray([]);
+ assertStrongArray([1, 2, 3]);
+ assertStrongArray([1, 2, ...[3, 4], 5]);
assertStrongArray([[[]]]);
assertStrongArray([[1], {}, [[3]]]);
assertStrongArray([[1], {}, [[3]]][0]);
- assertStrongObject([[1], {}, [[3]]][1]);
assertStrongArray([[1], {}, [[3]]][2]);
assertStrongArray([[1], {}, [[3]]][2][0]);
+ assertStrongArray({a: [], b: {}}.a);
})();
(function WeakFunctionLiterals() {
+ function assertWeakFunction(x) {
+ assertFalse(%IsStrong(x));
+ assertFalse(%IsStrong(x.prototype));
+ assertSame(Function.prototype, Object.getPrototypeOf(x));
+ }
function f() {}
- assertTrue(!%IsStrong(f));
- assertTrue(!%IsStrong(function(){}));
- assertTrue(!%IsStrong(function f(){}));
- assertTrue(!%IsStrong(() => {}));
- assertTrue(!%IsStrong(x => x));
- assertTrue(!%IsStrong({m(){}}.m));
- assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
- {get a(){}}, 'a').get));
- assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
- {set a(x){}}, 'a').set));
- assertTrue(!%IsStrong((class {static m(){}}).m));
- assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
- class {static get a(){}}, 'a').get));
- assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
- class {static set a(x){}}, 'a').set));
- assertTrue(!%IsStrong((new class {m(){}}).m));
- assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
- (class {get a(){}}).prototype, 'a').get));
- assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
- (class {set a(x){}}).prototype, 'a').set));
+ assertWeakFunction(f);
+ assertWeakFunction(function(){});
+ assertWeakFunction(function f(){});
+ assertWeakFunction(() => {});
+ assertWeakFunction(x => x);
+ assertWeakFunction({m(){}}.m);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ {get a(){}}, 'a').get);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ {set a(x){}}, 'a').set);
+ assertWeakFunction((class {static m(){}}).m);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ class {static get a(){}}, 'a').get);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ class {static set a(x){}}, 'a').set);
+ assertWeakFunction((new class {m(){}}).m);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ (class {get a(){}}).prototype, 'a').get);
+ assertWeakFunction(Object.getOwnPropertyDescriptor(
+ (class {set a(x){}}).prototype, 'a').set);
})();
(function StrongFunctionLiterals() {
'use strong';
+ function assertStrongFunction(x) {
+ assertTrue(%IsStrong(x));
+ assertFalse('prototype' in x);
+ assertSame(Function.prototype, Object.getPrototypeOf(x));
+ }
function f() {}
assertStrongFunction(f);
assertStrongFunction(function(){});
})();
(function SelfStrongFunctionLiterals() {
+ function assertStrongFunction(x) {
+ assertTrue(%IsStrong(x));
+ assertFalse('prototype' in x);
+ assertSame(Function.prototype, Object.getPrototypeOf(x));
+ }
function f() {'use strong'}
assertStrongFunction(f);
assertStrongFunction(function(){'use strong'});
(class {set a(x){'use strong'}}).prototype, 'a').set);
})();
+let GeneratorPrototype = (function*(){}).__proto__;
+
(function WeakGeneratorLiterals() {
+ function assertWeakGenerator(x) {
+ assertFalse(%IsStrong(x));
+ assertFalse(%IsStrong(x.prototype));
+ assertSame(GeneratorPrototype, Object.getPrototypeOf(x));
+ assertFalse(%IsStrong(x()));
+ }
function* g() {}
- assertTrue(!%IsStrong(g));
- assertTrue(!%IsStrong(function*(){}));
- assertTrue(!%IsStrong(function* g(){}));
- assertTrue(!%IsStrong({*m(){}}.m));
- assertTrue(!%IsStrong((class {static *m(){}}).m));
- assertTrue(!%IsStrong((new class {*m(){}}).m));
+ assertWeakGenerator(g);
+ assertWeakGenerator(function*(){});
+ assertWeakGenerator(function* g(){});
+ assertWeakGenerator({*m(){}}.m);
+ assertWeakGenerator((class {static *m(){}}).m);
+ assertWeakGenerator((new class {*m(){}}).m);
})();
(function StrongGeneratorLiterals() {
'use strong';
+ function assertStrongGenerator(x) {
+ assertTrue(%IsStrong(x));
+ // TODO(rossberg): strongify generator prototypes
+ // assertTrue(%IsStrong(x.prototype));
+ assertSame(GeneratorPrototype, Object.getPrototypeOf(x));
+ // TODO(rossberg): strongify generator instances
+ // assertTrue(%IsStrong(x()));
+ }
function* g() {}
assertStrongGenerator(g);
assertStrongGenerator(function*(){});
})();
(function SelfStrongGeneratorLiterals() {
+ function assertStrongGenerator(x) {
+ assertTrue(%IsStrong(x));
+ // TODO(rossberg): strongify generator prototypes
+ // assertTrue(%IsStrong(x.prototype));
+ assertSame(GeneratorPrototype, Object.getPrototypeOf(x));
+ // TODO(rossberg): strongify generator instances
+ // assertTrue(%IsStrong(x()));
+ }
function* g() {'use strong'}
assertStrongGenerator(g);
assertStrongGenerator(function*(){'use strong'});
})();
(function WeakClassLiterals() {
- function assertWeakClass(C) {
- assertTrue(!%IsStrong(C));
- assertTrue(!%IsStrong(C.prototype));
+ function assertWeakClass(x) {
+ assertFalse(%IsStrong(x));
+ assertFalse(%IsStrong(x.prototype));
+ assertFalse(%IsStrong(new x));
}
class C {};
class D extends C {};
class E extends Object {};
- class F extends null {};
+ // class F extends null {};
const S = (() => {'use strong'; return class {}})();
class G extends S {};
assertWeakClass(C);
assertWeakClass(D);
assertWeakClass(E);
- assertWeakClass(F);
+ // assertWeakClass(F);
assertWeakClass(G);
assertWeakClass(class {});
assertWeakClass(class extends Object {});
- assertWeakClass(class extends null {});
+ // assertWeakClass(class extends null {});
assertWeakClass(class extends C {});
assertWeakClass(class extends S {});
assertWeakClass(class extends class {} {});
assertWeakClass(class C {});
assertWeakClass(class D extends Object {});
- assertWeakClass(class D extends null {});
+ // assertWeakClass(class D extends null {});
assertWeakClass(class D extends C {});
assertWeakClass(class D extends S {});
assertWeakClass(class D extends class {} {});
(function StrongClassLiterals() {
'use strong';
- function assertStrongClass(C) {
- assertTrue(%IsStrong(C));
- // TODO(rossberg): prototype object is not yet strongified
- // assertTrue(%IsStrong(C.prototype));
+ function assertStrongClass(x) {
+ assertTrue(%IsStrong(x));
+ // TODO(rossberg): strongify class prototype and instance
+ // assertTrue(%IsStrong(x.prototype));
+ // assertTrue(%IsStrong(new x));
}
class C {};
class D extends C {};
class E extends Object {};
- class F extends null {};
const W = (1, eval)(() => {'use strict'; return class {}})();
class G extends W {};
assertStrongClass(C);
assertStrongClass(D);
assertStrongClass(E);
- assertStrongClass(F);
assertStrongClass(G);
assertStrongClass(class {});
assertStrongClass(class extends Object {});
- assertStrongClass(class extends null {});
assertStrongClass(class extends C {});
assertStrongClass(class extends W {});
assertStrongClass(class extends class {} {});
assertStrongClass(class C {});
assertStrongClass(class D extends Object {});
- assertStrongClass(class D extends null {});
assertStrongClass(class D extends C {});
assertStrongClass(class D extends W {});
assertStrongClass(class D extends class {} {});
})();
(function WeakRegExpLiterals() {
- assertTrue(!%IsStrong(/abc/));
+ function assertWeakRegExp(x) {
+ assertFalse(%IsStrong(x));
+ }
+ assertWeakRegExp(/abc/);
})();
(function StrongRegExpLiterals() {
'use strong';
- // TODO(rossberg): implement strong regexp literals
- // assertTrue(%IsStrong(/abc/));
+ function assertStrongRegExp(x) {
+ // TODO(rossberg): strongify regexps
+ // assertTrue(%IsStrong(x));
+ }
+ assertStrongRegExp(/abc/);
})();