diff options
Diffstat (limited to 'src/factory.cc')
-rw-r--r-- | src/factory.cc | 429 |
1 files changed, 285 insertions, 144 deletions
diff --git a/src/factory.cc b/src/factory.cc index 3e812d56..79147d62 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -6,12 +6,15 @@ #include "src/accessors.h" #include "src/allocation-site-scopes.h" +#include "src/ast/ast.h" #include "src/base/bits.h" #include "src/bootstrapper.h" #include "src/compiler.h" #include "src/conversions.h" #include "src/isolate-inl.h" #include "src/macro-assembler.h" +#include "src/objects/module-info.h" +#include "src/objects/scope-info.h" namespace v8 { namespace internal { @@ -86,12 +89,6 @@ Handle<HeapObject> Factory::NewFillerObject(int size, } -Handle<Box> Factory::NewBox(Handle<Object> value) { - Handle<Box> result = Handle<Box>::cast(NewStruct(BOX_TYPE)); - result->set_value(*value); - return result; -} - Handle<PrototypeInfo> Factory::NewPrototypeInfo() { Handle<PrototypeInfo> result = Handle<PrototypeInfo>::cast(NewStruct(PROTOTYPE_INFO_TYPE)); @@ -102,6 +99,14 @@ Handle<PrototypeInfo> Factory::NewPrototypeInfo() { return result; } +Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1, + Handle<Object> value2) { + Handle<Tuple2> result = Handle<Tuple2>::cast(NewStruct(TUPLE2_TYPE)); + result->set_value1(*value1); + result->set_value2(*value2); + return result; +} + Handle<Tuple3> Factory::NewTuple3(Handle<Object> value1, Handle<Object> value2, Handle<Object> value3) { Handle<Tuple3> result = Handle<Tuple3>::cast(NewStruct(TUPLE3_TYPE)); @@ -120,6 +125,15 @@ Handle<ContextExtension> Factory::NewContextExtension( return result; } +Handle<ConstantElementsPair> Factory::NewConstantElementsPair( + ElementsKind elements_kind, Handle<FixedArrayBase> constant_values) { + Handle<ConstantElementsPair> result = Handle<ConstantElementsPair>::cast( + NewStruct(CONSTANT_ELEMENTS_PAIR_TYPE)); + result->set_elements_kind(elements_kind); + result->set_constant_values(*constant_values); + return result; +} + Handle<Oddball> Factory::NewOddball(Handle<Map> map, const char* to_string, Handle<Object> to_number, const char* type_of, byte kind) { @@ -158,7 +172,6 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size, FixedArray); } - Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) { CALL_HEAP_FUNCTION( isolate(), @@ -166,6 +179,34 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) { FixedArray); } +Handle<BoilerplateDescription> Factory::NewBoilerplateDescription( + int boilerplate, int all_properties, int index_keys, bool has_seen_proto) { + DCHECK_GE(boilerplate, 0); + DCHECK_GE(all_properties, index_keys); + DCHECK_GE(index_keys, 0); + + int backing_store_size = + all_properties - index_keys - (has_seen_proto ? 1 : 0); + DCHECK_GE(backing_store_size, 0); + bool has_different_size_backing_store = boilerplate != backing_store_size; + + // Space for name and value for every boilerplate property. + int size = 2 * boilerplate; + + if (has_different_size_backing_store) { + // An extra entry for the backing store size. + size++; + } + + Handle<BoilerplateDescription> description = + Handle<BoilerplateDescription>::cast(NewFixedArray(size, TENURED)); + + if (has_different_size_backing_store) { + DCHECK((boilerplate != (all_properties - index_keys)) || has_seen_proto); + description->set_backing_store_size(isolate(), backing_store_size); + } + return description; +} Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size, PretenureFlag pretenure) { @@ -183,11 +224,7 @@ Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles( DCHECK(0 <= size); Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure); if (size > 0) { - Handle<FixedDoubleArray> double_array = - Handle<FixedDoubleArray>::cast(array); - for (int i = 0; i < size; ++i) { - double_array->set_the_hole(i); - } + Handle<FixedDoubleArray>::cast(array)->FillWithHoles(0, size); } return array; } @@ -263,6 +300,7 @@ Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) { MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, PretenureFlag pretenure) { int length = string.length(); + if (length == 0) return empty_string(); if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); Handle<SeqOneByteString> result; ASSIGN_RETURN_ON_EXCEPTION( @@ -356,6 +394,7 @@ MaybeHandle<String> Factory::NewStringFromUtf8SubString( MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string, int length, PretenureFlag pretenure) { + if (length == 0) return empty_string(); if (String::IsOneByte(string, length)) { if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); Handle<SeqOneByteString> result; @@ -440,38 +479,63 @@ Handle<String> Factory::NewInternalizedStringImpl( String); } +namespace { -MaybeHandle<Map> Factory::InternalizedStringMapForString( - Handle<String> string) { - // If the string is in new space it cannot be used as internalized. - if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); - - // Find the corresponding internalized string map for strings. +MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) { switch (string->map()->instance_type()) { - case STRING_TYPE: return internalized_string_map(); + case STRING_TYPE: + return f->internalized_string_map(); case ONE_BYTE_STRING_TYPE: - return one_byte_internalized_string_map(); - case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); + return f->one_byte_internalized_string_map(); + case EXTERNAL_STRING_TYPE: + return f->external_internalized_string_map(); case EXTERNAL_ONE_BYTE_STRING_TYPE: - return external_one_byte_internalized_string_map(); + return f->external_one_byte_internalized_string_map(); case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: - return external_internalized_string_with_one_byte_data_map(); + return f->external_internalized_string_with_one_byte_data_map(); case SHORT_EXTERNAL_STRING_TYPE: - return short_external_internalized_string_map(); + return f->short_external_internalized_string_map(); case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: - return short_external_one_byte_internalized_string_map(); + return f->short_external_one_byte_internalized_string_map(); case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: - return short_external_internalized_string_with_one_byte_data_map(); + return f->short_external_internalized_string_with_one_byte_data_map(); default: return MaybeHandle<Map>(); // No match found. } } +} // namespace + +MaybeHandle<Map> Factory::InternalizedStringMapForString( + Handle<String> string) { + // If the string is in new space it cannot be used as internalized. + if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); + + return GetInternalizedStringMap(this, string); +} + +template <class StringClass> +Handle<StringClass> Factory::InternalizeExternalString(Handle<String> string) { + Handle<StringClass> cast_string = Handle<StringClass>::cast(string); + Handle<Map> map = GetInternalizedStringMap(this, string).ToHandleChecked(); + Handle<StringClass> external_string = New<StringClass>(map, OLD_SPACE); + external_string->set_length(cast_string->length()); + external_string->set_hash_field(cast_string->hash_field()); + external_string->set_resource(nullptr); + isolate()->heap()->RegisterExternalString(*external_string); + return external_string; +} + +template Handle<ExternalOneByteString> + Factory::InternalizeExternalString<ExternalOneByteString>(Handle<String>); +template Handle<ExternalTwoByteString> + Factory::InternalizeExternalString<ExternalTwoByteString>(Handle<String>); MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( int length, PretenureFlag pretenure) { if (length > String::kMaxLength || length < 0) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); } + DCHECK(length > 0); // Use Factory::empty_string() instead. CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateRawOneByteString(length, pretenure), @@ -484,6 +548,7 @@ MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( if (length > String::kMaxLength || length < 0) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); } + DCHECK(length > 0); // Use Factory::empty_string() instead. CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateRawTwoByteString(length, pretenure), @@ -572,6 +637,12 @@ Handle<String> ConcatStringContent(Handle<StringType> result, MaybeHandle<String> Factory::NewConsString(Handle<String> left, Handle<String> right) { + if (left->IsThinString()) { + left = handle(Handle<ThinString>::cast(left)->actual(), isolate()); + } + if (right->IsThinString()) { + right = handle(Handle<ThinString>::cast(right)->actual(), isolate()); + } int left_length = left->length(); if (left_length == 0) return right; int right_length = right->length(); @@ -718,6 +789,10 @@ Handle<String> Factory::NewProperSubString(Handle<String> str, str = Handle<String>(slice->parent(), isolate()); offset += slice->offset(); } + if (str->IsThinString()) { + Handle<ThinString> thin = Handle<ThinString>::cast(str); + str = handle(thin->actual(), isolate()); + } DCHECK(str->IsSeqString() || str->IsExternalString()); Handle<Map> map = str->IsOneByteRepresentation() @@ -739,6 +814,7 @@ MaybeHandle<String> Factory::NewExternalStringFromOneByte( if (length > static_cast<size_t>(String::kMaxLength)) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } + if (length == 0) return empty_string(); Handle<Map> map; if (resource->IsCompressible()) { @@ -763,6 +839,7 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte( if (length > static_cast<size_t>(String::kMaxLength)) { THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } + if (length == 0) return empty_string(); // For small strings we check whether the resource contains only // one byte characters. If yes, we use a different string map. @@ -885,13 +962,24 @@ Handle<Context> Factory::NewModuleContext(Handle<Module> module, return context; } - Handle<Context> Factory::NewFunctionContext(int length, - Handle<JSFunction> function) { - DCHECK(function->shared()->scope_info()->scope_type() == FUNCTION_SCOPE); + Handle<JSFunction> function, + ScopeType scope_type) { + DCHECK(function->shared()->scope_info()->scope_type() == scope_type); DCHECK(length >= Context::MIN_CONTEXT_SLOTS); Handle<FixedArray> array = NewFixedArray(length); - array->set_map_no_write_barrier(*function_context_map()); + Handle<Map> map; + switch (scope_type) { + case EVAL_SCOPE: + map = eval_context_map(); + break; + case FUNCTION_SCOPE: + map = function_context_map(); + break; + default: + UNREACHABLE(); + } + array->set_map_no_write_barrier(*map); Handle<Context> context = Handle<Context>::cast(array); context->set_closure(*function); context->set_previous(function->context()); @@ -971,15 +1059,6 @@ Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function, return context; } -Handle<Context> Factory::NewPromiseResolvingFunctionContext(int length) { - DCHECK_GE(length, Context::MIN_CONTEXT_SLOTS); - Handle<FixedArray> array = NewFixedArray(length); - array->set_map_no_write_barrier(*function_context_map()); - Handle<Context> context = Handle<Context>::cast(array); - context->set_extension(*the_hole_value()); - return context; -} - Handle<Struct> Factory::NewStruct(InstanceType type) { CALL_HEAP_FUNCTION( isolate(), @@ -987,39 +1066,6 @@ Handle<Struct> Factory::NewStruct(InstanceType type) { Struct); } -Handle<PromiseResolveThenableJobInfo> Factory::NewPromiseResolveThenableJobInfo( - Handle<JSReceiver> thenable, Handle<JSReceiver> then, - Handle<JSFunction> resolve, Handle<JSFunction> reject, - Handle<Object> debug_id, Handle<Object> debug_name, - Handle<Context> context) { - Handle<PromiseResolveThenableJobInfo> result = - Handle<PromiseResolveThenableJobInfo>::cast( - NewStruct(PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE)); - result->set_thenable(*thenable); - result->set_then(*then); - result->set_resolve(*resolve); - result->set_reject(*reject); - result->set_debug_id(*debug_id); - result->set_debug_name(*debug_name); - result->set_context(*context); - return result; -} - -Handle<PromiseReactionJobInfo> Factory::NewPromiseReactionJobInfo( - Handle<Object> value, Handle<Object> tasks, Handle<Object> deferred, - Handle<Object> debug_id, Handle<Object> debug_name, - Handle<Context> context) { - Handle<PromiseReactionJobInfo> result = Handle<PromiseReactionJobInfo>::cast( - NewStruct(PROMISE_REACTION_JOB_INFO_TYPE)); - result->set_value(*value); - result->set_tasks(*tasks); - result->set_deferred(*deferred); - result->set_debug_id(*debug_id); - result->set_debug_name(*debug_name); - result->set_context(*context); - return result; -} - Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry( int aliased_context_slot) { Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast( @@ -1053,7 +1099,7 @@ Handle<Script> Factory::NewScript(Handle<String> source) { script->set_line_ends(heap->undefined_value()); script->set_eval_from_shared(heap->undefined_value()); script->set_eval_from_position(0); - script->set_shared_function_infos(Smi::kZero); + script->set_shared_function_infos(*empty_fixed_array(), SKIP_WRITE_BARRIER); script->set_flags(0); heap->set_script_list(*WeakFixedArray::Add(script_list(), script)); @@ -1113,7 +1159,6 @@ Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray( FixedTypedArrayBase); } - Handle<Cell> Factory::NewCell(Handle<Object> value) { AllowDeferredHandleDereference convert_to_cell; CALL_HEAP_FUNCTION( @@ -1122,6 +1167,23 @@ Handle<Cell> Factory::NewCell(Handle<Object> value) { Cell); } +Handle<Cell> Factory::NewNoClosuresCell(Handle<Object> value) { + Handle<Cell> cell = NewCell(value); + cell->set_map_no_write_barrier(*no_closures_cell_map()); + return cell; +} + +Handle<Cell> Factory::NewOneClosureCell(Handle<Object> value) { + Handle<Cell> cell = NewCell(value); + cell->set_map_no_write_barrier(*one_closure_cell_map()); + return cell; +} + +Handle<Cell> Factory::NewManyClosuresCell(Handle<Object> value) { + Handle<Cell> cell = NewCell(value); + cell->set_map_no_write_barrier(*many_closures_cell_map()); + return cell; +} Handle<PropertyCell> Factory::NewPropertyCell() { CALL_HEAP_FUNCTION( @@ -1265,27 +1327,13 @@ Handle<Object> Factory::NewNumberFromUint(uint32_t value, return NewHeapNumber(FastUI2D(value), IMMUTABLE, pretenure); } - -Handle<HeapNumber> Factory::NewHeapNumber(double value, - MutableMode mode, +Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode, PretenureFlag pretenure) { - CALL_HEAP_FUNCTION( - isolate(), - isolate()->heap()->AllocateHeapNumber(value, mode, pretenure), - HeapNumber); + CALL_HEAP_FUNCTION(isolate(), + isolate()->heap()->AllocateHeapNumber(mode, pretenure), + HeapNumber); } - -#define SIMD128_NEW_DEF(TYPE, Type, type, lane_count, lane_type) \ - Handle<Type> Factory::New##Type(lane_type lanes[lane_count], \ - PretenureFlag pretenure) { \ - CALL_HEAP_FUNCTION( \ - isolate(), isolate()->heap()->Allocate##Type(lanes, pretenure), Type); \ - } -SIMD128_TYPES(SIMD128_NEW_DEF) -#undef SIMD128_NEW_DEF - - Handle<Object> Factory::NewError(Handle<JSFunction> constructor, MessageTemplate::Template template_index, Handle<Object> arg0, Handle<Object> arg1, @@ -1356,6 +1404,7 @@ DEFINE_ERROR(ReferenceError, reference_error) DEFINE_ERROR(SyntaxError, syntax_error) DEFINE_ERROR(TypeError, type_error) DEFINE_ERROR(WasmCompileError, wasm_compile_error) +DEFINE_ERROR(WasmLinkError, wasm_link_error) DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error) #undef DEFINE_ERROR @@ -1374,7 +1423,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map, function->set_code(info->code()); function->set_context(*context_or_undefined); function->set_prototype_or_initial_map(*the_hole_value()); - function->set_literals(LiteralsArray::cast(*empty_literals_array())); + function->set_feedback_vector_cell(*undefined_cell()); function->set_next_function_link(*undefined_value(), SKIP_WRITE_BARRIER); isolate()->heap()->InitializeJSObjectBody(*function, *map, JSFunction::kSize); return function; @@ -1398,6 +1447,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map, map.is_identical_to(isolate()->strict_function_without_prototype_map()) || // TODO(titzer): wasm_function_map() could be undefined here. ugly. (*map == context->get(Context::WASM_FUNCTION_MAP_INDEX)) || + (*map == context->get(Context::NATIVE_FUNCTION_MAP_INDEX)) || map.is_identical_to(isolate()->proxy_function_map())); return NewFunction(map, info, context); } @@ -1505,6 +1555,17 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( } Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( + Handle<SharedFunctionInfo> info, Handle<Context> context, + Handle<Cell> vector, PretenureFlag pretenure) { + int map_index = + Context::FunctionMapIndex(info->language_mode(), info->kind()); + Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index))); + + return NewFunctionFromSharedFunctionInfo(initial_map, info, context, vector, + pretenure); +} + +Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( Handle<Map> initial_map, Handle<SharedFunctionInfo> info, Handle<Object> context_or_undefined, PretenureFlag pretenure) { DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type()); @@ -1523,6 +1584,35 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( return result; } +Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( + Handle<Map> initial_map, Handle<SharedFunctionInfo> info, + Handle<Object> context_or_undefined, Handle<Cell> vector, + PretenureFlag pretenure) { + DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type()); + Handle<JSFunction> result = + NewFunction(initial_map, info, context_or_undefined, pretenure); + + // Bump the closure count that is encoded in the vector cell's map. + if (vector->map() == *no_closures_cell_map()) { + vector->set_map(*one_closure_cell_map()); + } else if (vector->map() == *one_closure_cell_map()) { + vector->set_map(*many_closures_cell_map()); + } else { + DCHECK_EQ(vector->map(), *many_closures_cell_map()); + } + + result->set_feedback_vector_cell(*vector); + if (info->ic_age() != isolate()->heap()->global_ic_age()) { + info->ResetForNewContext(isolate()->heap()->global_ic_age()); + } + + if (context_or_undefined->IsContext()) { + // Give compiler a chance to pre-initialize. + Compiler::PostInstantiation(result, pretenure); + } + + return result; +} Handle<ScopeInfo> Factory::NewScopeInfo(int length) { Handle<FixedArray> array = NewFixedArray(length, TENURED); @@ -1650,9 +1740,9 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); } - -Handle<JSObject> Factory::NewJSObjectWithNullProto() { - Handle<JSObject> result = NewJSObject(isolate()->object_function()); +Handle<JSObject> Factory::NewJSObjectWithNullProto(PretenureFlag pretenure) { + Handle<JSObject> result = + NewJSObject(isolate()->object_function(), pretenure); Handle<Map> new_map = Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto"); Map::SetPrototype(new_map, null_value()); @@ -1692,12 +1782,12 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject( for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { PropertyDetails details = descs->GetDetails(i); // Only accessors are expected. - DCHECK_EQ(ACCESSOR_CONSTANT, details.type()); - PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, + DCHECK_EQ(kAccessor, details.kind()); + PropertyDetails d(kAccessor, details.attributes(), i + 1, PropertyCellType::kMutable); Handle<Name> name(descs->GetKey(i)); Handle<PropertyCell> cell = NewPropertyCell(); - cell->set_value(descs->GetCallbacksObject(i)); + cell->set_value(descs->GetValue(i)); // |dictionary| already contains enough space for all properties. USE(GlobalDictionary::Add(dictionary, name, cell, d)); } @@ -1806,7 +1896,13 @@ void Factory::NewJSArrayStorage(Handle<JSArray> array, Handle<JSModuleNamespace> Factory::NewJSModuleNamespace() { Handle<Map> map = isolate()->js_module_namespace_map(); - return Handle<JSModuleNamespace>::cast(NewJSObjectFromMap(map)); + Handle<JSModuleNamespace> module_namespace( + Handle<JSModuleNamespace>::cast(NewJSObjectFromMap(map))); + FieldIndex index = FieldIndex::ForDescriptor( + *map, JSModuleNamespace::kToStringTagFieldIndex); + module_namespace->FastPropertyAtPut(index, + isolate()->heap()->Module_string()); + return module_namespace; } Handle<JSGeneratorObject> Factory::NewJSGeneratorObject( @@ -1879,6 +1975,16 @@ Handle<JSIteratorResult> Factory::NewJSIteratorResult(Handle<Object> value, return js_iter_result; } +Handle<JSAsyncFromSyncIterator> Factory::NewJSAsyncFromSyncIterator( + Handle<JSReceiver> sync_iterator) { + Handle<Map> map(isolate()->native_context()->async_from_sync_iterator_map()); + Handle<JSAsyncFromSyncIterator> iterator = + Handle<JSAsyncFromSyncIterator>::cast(NewJSObjectFromMap(map)); + + iterator->set_sync_iterator(*sync_iterator); + return iterator; +} + Handle<JSMap> Factory::NewJSMap() { Handle<Map> map(isolate()->native_context()->js_map_map()); Handle<JSMap> js_map = Handle<JSMap>::cast(NewJSObjectFromMap(map)); @@ -2224,6 +2330,7 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, map->set_is_prototype_map(true); } JSObject::NotifyMapChange(old_map, map, isolate()); + old_map->NotifyLeafMapLayoutChange(); // Check that the already allocated object has the same size and type as // objects allocated using the constructor. @@ -2249,21 +2356,30 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, } Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( - Handle<String> name, int number_of_literals, FunctionKind kind, - Handle<Code> code, Handle<ScopeInfo> scope_info) { + Handle<String> name, FunctionKind kind, Handle<Code> code, + Handle<ScopeInfo> scope_info) { DCHECK(IsValidFunctionKind(kind)); Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo( name, code, IsConstructable(kind, scope_info->language_mode())); shared->set_scope_info(*scope_info); shared->set_outer_scope_info(*the_hole_value()); shared->set_kind(kind); - shared->set_num_literals(number_of_literals); if (IsGeneratorFunction(kind)) { shared->set_instance_class_name(isolate()->heap()->Generator_string()); } return shared; } +Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral( + FunctionLiteral* literal, Handle<Script> script) { + Handle<Code> code = isolate()->builtins()->CompileLazy(); + Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate())); + Handle<SharedFunctionInfo> result = + NewSharedFunctionInfo(literal->name(), literal->kind(), code, scope_info); + SharedFunctionInfo::InitFromFunctionLiteral(result, literal); + SharedFunctionInfo::SetScript(result, script); + return result; +} Handle<JSMessageObject> Factory::NewJSMessageObject( MessageTemplate::Template message, Handle<Object> argument, @@ -2280,6 +2396,7 @@ Handle<JSMessageObject> Factory::NewJSMessageObject( message_obj->set_end_position(end_position); message_obj->set_script(*script); message_obj->set_stack_frames(*stack_frames); + message_obj->set_error_level(v8::Isolate::kMessageError); return message_obj; } @@ -2295,6 +2412,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( // Set pointer fields. share->set_name(*name); + share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER); Handle<Code> code; if (!maybe_code.ToHandle(&code)) { code = isolate()->builtins()->Illegal(); @@ -2308,14 +2426,14 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( : isolate()->builtins()->ConstructedNonConstructable(); share->SetConstructStub(*construct_stub); share->set_instance_class_name(*Object_string()); - share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER); share->set_script(*undefined_value(), SKIP_WRITE_BARRIER); - share->set_debug_info(DebugInfo::uninitialized(), SKIP_WRITE_BARRIER); + share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER); share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER); StaticFeedbackVectorSpec empty_spec; - Handle<TypeFeedbackMetadata> feedback_metadata = - TypeFeedbackMetadata::New(isolate(), &empty_spec); + Handle<FeedbackMetadata> feedback_metadata = + FeedbackMetadata::New(isolate(), &empty_spec); share->set_feedback_metadata(*feedback_metadata, SKIP_WRITE_BARRIER); + share->set_function_literal_id(FunctionLiteral::kIdTypeInvalid); #if TRACE_MAPS share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId()); #endif @@ -2327,7 +2445,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( share->set_length(0); share->set_internal_formal_parameter_count(0); share->set_expected_nof_properties(0); - share->set_num_literals(0); share->set_start_position_and_type(0); share->set_end_position(0); share->set_function_token_position(0); @@ -2413,6 +2530,7 @@ Handle<String> Factory::NumberToString(Handle<Object> number, Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { + DCHECK(!shared->HasDebugInfo()); // Allocate initial fixed array for active break points before allocating the // debug info object to avoid allocation while setting up the debug info // object. @@ -2432,6 +2550,7 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { Handle<DebugInfo> debug_info = Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE)); debug_info->set_shared(*shared); + debug_info->set_debugger_hints(shared->debugger_hints()); debug_info->set_debug_bytecode_array(*maybe_debug_bytecode_array); debug_info->set_break_points(*break_points); @@ -2441,6 +2560,13 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { return debug_info; } +Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) { + Handle<BreakPointInfo> new_break_point_info = + Handle<BreakPointInfo>::cast(NewStruct(BREAK_POINT_INFO_TYPE)); + new_break_point_info->set_source_position(source_position); + new_break_point_info->set_break_point_objects(*undefined_value()); + return new_break_point_info; +} Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee, int length) { @@ -2616,31 +2742,31 @@ void Factory::SetFunctionInstanceDescriptor(Handle<Map> map, Handle<AccessorInfo> length = Accessors::FunctionLengthInfo(isolate(), roc_attribs); { // Add length. - AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())), - length, roc_attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(length->name())), length, roc_attribs); map->AppendDescriptor(&d); } STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1); Handle<AccessorInfo> name = - Accessors::FunctionNameInfo(isolate(), ro_attribs); + Accessors::FunctionNameInfo(isolate(), roc_attribs); { // Add name. - AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name, - roc_attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(name->name())), name, roc_attribs); map->AppendDescriptor(&d); } Handle<AccessorInfo> args = Accessors::FunctionArgumentsInfo(isolate(), ro_attribs); { // Add arguments. - AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args, - ro_attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(args->name())), args, ro_attribs); map->AppendDescriptor(&d); } Handle<AccessorInfo> caller = Accessors::FunctionCallerInfo(isolate(), ro_attribs); { // Add caller. - AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())), - caller, ro_attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(caller->name())), caller, ro_attribs); map->AppendDescriptor(&d); } if (IsFunctionModeWithPrototype(function_mode)) { @@ -2649,8 +2775,8 @@ void Factory::SetFunctionInstanceDescriptor(Handle<Map> map, } Handle<AccessorInfo> prototype = Accessors::FunctionPrototypeInfo(isolate(), ro_attribs); - AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())), - prototype, ro_attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(prototype->name())), prototype, ro_attribs); map->AppendDescriptor(&d); } } @@ -2684,8 +2810,8 @@ void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, { // Add length. Handle<AccessorInfo> length = Accessors::FunctionLengthInfo(isolate(), roc_attribs); - AccessorConstantDescriptor d(handle(Name::cast(length->name())), length, - roc_attribs); + Descriptor d = Descriptor::AccessorConstant( + handle(Name::cast(length->name())), length, roc_attribs); map->AppendDescriptor(&d); } @@ -2693,8 +2819,8 @@ void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, { // Add name. Handle<AccessorInfo> name = Accessors::FunctionNameInfo(isolate(), roc_attribs); - AccessorConstantDescriptor d(handle(Name::cast(name->name())), name, - roc_attribs); + Descriptor d = Descriptor::AccessorConstant( + handle(Name::cast(name->name())), name, roc_attribs); map->AppendDescriptor(&d); } if (IsFunctionModeWithPrototype(function_mode)) { @@ -2704,31 +2830,46 @@ void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, : ro_attribs; Handle<AccessorInfo> prototype = Accessors::FunctionPrototypeInfo(isolate(), attribs); - AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())), - prototype, attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(prototype->name())), prototype, attribs); map->AppendDescriptor(&d); } } -Handle<JSFixedArrayIterator> Factory::NewJSFixedArrayIterator( - Handle<FixedArray> array) { - // Create the "next" function (must be unique per iterator object). - Handle<Code> code( - isolate()->builtins()->builtin(Builtins::kFixedArrayIteratorNext)); - // TODO(neis): Don't create a new SharedFunctionInfo each time. - Handle<JSFunction> next = isolate()->factory()->NewFunctionWithoutPrototype( - isolate()->factory()->next_string(), code, false); - next->shared()->set_native(true); - - // Create the iterator. - Handle<Map> map(isolate()->native_context()->fixed_array_iterator_map()); - Handle<JSFixedArrayIterator> iterator = - Handle<JSFixedArrayIterator>::cast(NewJSObjectFromMap(map)); - iterator->set_initial_next(*next); - iterator->set_array(*array); - iterator->set_index(0); - iterator->InObjectPropertyAtPut(JSFixedArrayIterator::kNextIndex, *next); - return iterator; +Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) { + Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); + SetClassFunctionInstanceDescriptor(map); + map->set_is_constructor(true); + map->set_is_callable(); + Map::SetPrototype(map, empty_function); + return map; +} + +void Factory::SetClassFunctionInstanceDescriptor(Handle<Map> map) { + Map::EnsureDescriptorSlack(map, 2); + + PropertyAttributes rw_attribs = + static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); + PropertyAttributes roc_attribs = + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); + + STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); + { // Add length. + Handle<AccessorInfo> length = + Accessors::FunctionLengthInfo(isolate(), roc_attribs); + Descriptor d = Descriptor::AccessorConstant( + handle(Name::cast(length->name())), length, roc_attribs); + map->AppendDescriptor(&d); + } + + { + // Add prototype. + Handle<AccessorInfo> prototype = + Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); + Descriptor d = Descriptor::AccessorConstant( + Handle<Name>(Name::cast(prototype->name())), prototype, rw_attribs); + map->AppendDescriptor(&d); + } } } // namespace internal |