v8/src/contexts.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

649 lines
36 KiB
C
Raw Normal View History

// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CONTEXTS_H_
#define V8_CONTEXTS_H_
#include "src/objects/fixed-array.h"
namespace v8 {
namespace internal {
class JSGlobalObject;
class JSGlobalProxy;
class NativeContext;
class RegExpMatchInfo;
enum ContextLookupFlags {
FOLLOW_CONTEXT_CHAIN = 1 << 0,
FOLLOW_PROTOTYPE_CHAIN = 1 << 1,
STOP_AT_DECLARATION_SCOPE = 1 << 2,
SKIP_WITH_CONTEXT = 1 << 3,
DONT_FOLLOW_CHAINS = 0,
FOLLOW_CHAINS = FOLLOW_CONTEXT_CHAIN | FOLLOW_PROTOTYPE_CHAIN,
};
// Heap-allocated activation contexts.
//
// Contexts are implemented as FixedArray objects; the Context
// class is a convenience interface casted on a FixedArray object.
//
// Note: Context must have no virtual functions and Context objects
// must always be allocated via Heap::AllocateContext() or
// Factory::NewContext.
#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
V(ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, JSFunction, \
async_function_await_caught) \
V(ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX, JSFunction, \
async_function_await_uncaught) \
V(ASYNC_FUNCTION_PROMISE_CREATE_INDEX, JSFunction, \
async_function_promise_create) \
V(ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, JSFunction, \
async_function_promise_release) \
V(IS_ARRAYLIKE, JSFunction, is_arraylike) \
V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \
V(MAKE_ERROR_INDEX, JSFunction, make_error) \
V(MAKE_RANGE_ERROR_INDEX, JSFunction, make_range_error) \
V(MAKE_SYNTAX_ERROR_INDEX, JSFunction, make_syntax_error) \
V(MAKE_TYPE_ERROR_INDEX, JSFunction, make_type_error) \
V(MAKE_URI_ERROR_INDEX, JSFunction, make_uri_error) \
V(OBJECT_CREATE, JSFunction, object_create) \
V(OBJECT_DEFINE_PROPERTIES, JSFunction, object_define_properties) \
V(OBJECT_DEFINE_PROPERTY, JSFunction, object_define_property) \
V(OBJECT_GET_PROTOTYPE_OF, JSFunction, object_get_prototype_of) \
V(OBJECT_IS_EXTENSIBLE, JSFunction, object_is_extensible) \
V(OBJECT_IS_FROZEN, JSFunction, object_is_frozen) \
V(OBJECT_IS_SEALED, JSFunction, object_is_sealed) \
V(OBJECT_KEYS, JSFunction, object_keys) \
V(REGEXP_INTERNAL_MATCH, JSFunction, regexp_internal_match) \
V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
V(REFLECT_DEFINE_PROPERTY_INDEX, JSFunction, reflect_define_property) \
V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
V(MATH_FLOOR_INDEX, JSFunction, math_floor) \
V(MATH_POW_INDEX, JSFunction, math_pow) \
V(NEW_PROMISE_CAPABILITY_INDEX, JSFunction, new_promise_capability) \
V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \
promise_internal_constructor) \
V(IS_PROMISE_INDEX, JSFunction, is_promise) \
V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
V(ASYNC_GENERATOR_AWAIT_CAUGHT, JSFunction, async_generator_await_caught) \
V(ASYNC_GENERATOR_AWAIT_UNCAUGHT, JSFunction, async_generator_await_uncaught)
#define NATIVE_CONTEXT_IMPORTED_FIELDS(V) \
V(ARRAY_ENTRIES_ITERATOR_INDEX, JSFunction, array_entries_iterator) \
V(ARRAY_FOR_EACH_ITERATOR_INDEX, JSFunction, array_for_each_iterator) \
V(ARRAY_KEYS_ITERATOR_INDEX, JSFunction, array_keys_iterator) \
V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator) \
V(CANONICALIZE_LOCALE_LIST_FUNCTION_INDEX, JSFunction, \
canonicalize_locale_list) \
V(ERROR_FUNCTION_INDEX, JSFunction, error_function) \
V(ERROR_TO_STRING, JSFunction, error_to_string) \
V(EVAL_ERROR_FUNCTION_INDEX, JSFunction, eval_error_function) \
V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \
V(GLOBAL_PROXY_FUNCTION_INDEX, JSFunction, global_proxy_function) \
V(MAP_DELETE_INDEX, JSFunction, map_delete) \
V(MAP_GET_INDEX, JSFunction, map_get) \
V(MAP_HAS_INDEX, JSFunction, map_has) \
V(MAP_SET_INDEX, JSFunction, map_set) \
V(FUNCTION_HAS_INSTANCE_INDEX, JSFunction, function_has_instance) \
V(OBJECT_VALUE_OF, JSFunction, object_value_of) \
V(OBJECT_TO_STRING, JSFunction, object_to_string) \
V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \
V(PROMISE_FUNCTION_INDEX, JSFunction, promise_function) \
V(RANGE_ERROR_FUNCTION_INDEX, JSFunction, range_error_function) \
V(REFERENCE_ERROR_FUNCTION_INDEX, JSFunction, reference_error_function) \
V(CACHED_OR_NEW_SERVICE_LOCALE_FUNCTION_INDEX, JSFunction, \
cached_or_new_service) \
V(RESOLVE_LOCALE_FUNCTION_INDEX, JSFunction, resolve_locale) \
V(SET_ADD_INDEX, JSFunction, set_add) \
V(SET_DELETE_INDEX, JSFunction, set_delete) \
V(SET_HAS_INDEX, JSFunction, set_has) \
V(SYNTAX_ERROR_FUNCTION_INDEX, JSFunction, syntax_error_function) \
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
V(WASM_COMPILE_ERROR_FUNCTION_INDEX, JSFunction, \
wasm_compile_error_function) \
V(WASM_LINK_ERROR_FUNCTION_INDEX, JSFunction, wasm_link_error_function) \
V(WASM_RUNTIME_ERROR_FUNCTION_INDEX, JSFunction, \
wasm_runtime_error_function) \
V(WEAKMAP_SET_INDEX, JSFunction, weakmap_set) \
V(WEAKMAP_GET_INDEX, JSFunction, weakmap_get) \
V(WEAKSET_ADD_INDEX, JSFunction, weakset_add)
#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSGlobalProxy, global_proxy_object) \
V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \
/* Below is alpha-sorted */ \
V(ACCESSOR_PROPERTY_DESCRIPTOR_MAP_INDEX, Map, \
accessor_property_descriptor_map) \
V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun) \
V(ARRAY_BUFFER_MAP_INDEX, Map, array_buffer_map) \
V(ARRAY_BUFFER_NOINIT_FUN_INDEX, JSFunction, array_buffer_noinit_fun) \
V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \
V(ASYNC_FROM_SYNC_ITERATOR_MAP_INDEX, Map, async_from_sync_iterator_map) \
V(ASYNC_FUNCTION_AWAIT_REJECT_SHARED_FUN, SharedFunctionInfo, \
async_function_await_reject_shared_fun) \
V(ASYNC_FUNCTION_AWAIT_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
async_function_await_resolve_shared_fun) \
V(ASYNC_FUNCTION_FUNCTION_INDEX, JSFunction, async_function_constructor) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
V(ASYNC_GENERATOR_FUNCTION_FUNCTION_INDEX, JSFunction, \
async_generator_function_function) \
V(ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN, SharedFunctionInfo, \
async_iterator_value_unwrap_shared_fun) \
V(ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN, SharedFunctionInfo, \
async_generator_await_reject_shared_fun) \
V(ASYNC_GENERATOR_AWAIT_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
async_generator_await_resolve_shared_fun) \
V(ASYNC_GENERATOR_YIELD_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
async_generator_yield_resolve_shared_fun) \
V(ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
async_generator_return_resolve_shared_fun) \
V(ASYNC_GENERATOR_RETURN_CLOSED_RESOLVE_SHARED_FUN, SharedFunctionInfo, \
async_generator_return_closed_resolve_shared_fun) \
V(ASYNC_GENERATOR_RETURN_CLOSED_REJECT_SHARED_FUN, SharedFunctionInfo, \
async_generator_return_closed_reject_shared_fun) \
V(ATOMICS_OBJECT, JSObject, atomics_object) \
V(BIGINT_FUNCTION_INDEX, JSFunction, bigint_function) \
V(BIGINT64_ARRAY_FUN_INDEX, JSFunction, bigint64_array_fun) \
V(BIGUINT64_ARRAY_FUN_INDEX, JSFunction, biguint64_array_fun) \
V(BOOLEAN_FUNCTION_INDEX, JSFunction, boolean_function) \
V(BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX, Map, \
bound_function_with_constructor_map) \
V(BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX, Map, \
bound_function_without_constructor_map) \
V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
call_as_constructor_delegate) \
V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \
V(CALLSITE_FUNCTION_INDEX, JSFunction, callsite_function) \
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
V(DATA_PROPERTY_DESCRIPTOR_MAP_INDEX, Map, data_property_descriptor_map) \
V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \
V(DATE_FUNCTION_INDEX, JSFunction, date_function) \
V(DEBUG_CONTEXT_ID_INDEX, Object, debug_context_id) \
V(EMPTY_FUNCTION_INDEX, JSFunction, empty_function) \
V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
error_message_for_code_gen_from_strings) \
V(ERRORS_THROWN_INDEX, Smi, errors_thrown) \
V(EXTRAS_EXPORTS_OBJECT_INDEX, JSObject, extras_binding_object) \
V(EXTRAS_UTILS_OBJECT_INDEX, Object, extras_utils_object) \
V(FAST_ALIASED_ARGUMENTS_MAP_INDEX, Map, fast_aliased_arguments_map) \
V(FAST_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, FixedArray, \
fast_template_instantiations_cache) \
V(FLOAT32_ARRAY_FUN_INDEX, JSFunction, float32_array_fun) \
V(FLOAT64_ARRAY_FUN_INDEX, JSFunction, float64_array_fun) \
V(FUNCTION_FUNCTION_INDEX, JSFunction, function_function) \
V(GENERATOR_FUNCTION_FUNCTION_INDEX, JSFunction, \
generator_function_function) \
V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, generator_object_prototype_map) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
V(ASYNC_GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, \
async_generator_object_prototype_map) \
[es2015] Refactor the JSArrayIterator. This changes the JSArrayIterator to always have only a single instance type, instead of the zoo of instance types that we had before, and which became less useful with the specification update to when "next" is loaded from the iterator now. This greatly simplifies the baseline implementation of the array iterator, which now only looks at the iterated object during %ArrayIteratorPrototype%.next invocations. In TurboFan we introduce a new JSCreateArrayIterator operator, that holds the IterationKind and get's the iterated object as input. When optimizing %ArrayIteratorPrototype%.next in the JSCallReducer, we check whether the receiver is a JSCreateArrayIterator, and if so, we try to infer maps for the iterated object from there. If we find any, we speculatively assume that these won't have changed during iteration (as we did before with the previous approach), and generate fast code for both JSArray and JSTypedArray iteration. Drive-by-fix: Drop the fast_array_iteration protector, it's not necessary anymore since we have the deoptimization guard bit in the JSCallReducer now. This addresses the performance cliff noticed in webpack 4. The minimal repro on the tracking bug goes from console.timeEnd: mono, 124.773000 console.timeEnd: poly, 670.353000 to console.timeEnd: mono, 118.709000 console.timeEnd: poly, 141.393000 so that's a 4.7x improvement. Also make presubmit happy by adding the missing #undef's. Bug: v8:7510, v7:7514 Change-Id: I79a46bfa2cd0f0710e09365ef72519b1bbb667b5 Reviewed-on: https://chromium-review.googlesource.com/946098 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#51725}
2018-03-02 19:31:01 +00:00
V(INITIAL_ARRAY_ITERATOR_MAP_INDEX, Map, initial_array_iterator_map) \
V(INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX, JSObject, \
initial_array_iterator_prototype) \
V(INITIAL_ARRAY_PROTOTYPE_INDEX, JSObject, initial_array_prototype) \
V(INITIAL_ERROR_PROTOTYPE_INDEX, JSObject, initial_error_prototype) \
V(INITIAL_GENERATOR_PROTOTYPE_INDEX, JSObject, initial_generator_prototype) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
V(INITIAL_ASYNC_GENERATOR_PROTOTYPE_INDEX, JSObject, \
initial_async_generator_prototype) \
V(INITIAL_ITERATOR_PROTOTYPE_INDEX, JSObject, initial_iterator_prototype) \
V(INITIAL_MAP_PROTOTYPE_MAP_INDEX, Map, initial_map_prototype_map) \
V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype) \
V(INITIAL_SET_PROTOTYPE_MAP_INDEX, Map, initial_set_prototype_map) \
V(INITIAL_STRING_ITERATOR_MAP_INDEX, Map, initial_string_iterator_map) \
V(INITIAL_STRING_ITERATOR_PROTOTYPE_INDEX, JSObject, \
initial_string_iterator_prototype) \
V(INITIAL_STRING_PROTOTYPE_INDEX, JSObject, initial_string_prototype) \
V(INITIAL_WEAKMAP_PROTOTYPE_MAP_INDEX, Map, initial_weakmap_prototype_map) \
V(INITIAL_WEAKSET_PROTOTYPE_MAP_INDEX, Map, initial_weakset_prototype_map) \
V(INT16_ARRAY_FUN_INDEX, JSFunction, int16_array_fun) \
V(INT32_ARRAY_FUN_INDEX, JSFunction, int32_array_fun) \
V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \
V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map) \
V(INTL_DATE_TIME_FORMAT_FUNCTION_INDEX, JSFunction, \
intl_date_time_format_function) \
V(INTL_NUMBER_FORMAT_FUNCTION_INDEX, JSFunction, \
intl_number_format_function) \
V(INTL_LOCALE_FUNCTION_INDEX, JSFunction, intl_locale_function) \
V(INTL_COLLATOR_FUNCTION_INDEX, JSFunction, intl_collator_function) \
V(INTL_PLURAL_RULES_FUNCTION_INDEX, JSFunction, intl_plural_rules_function) \
V(INTL_V8_BREAK_ITERATOR_FUNCTION_INDEX, JSFunction, \
intl_v8_break_iterator_function) \
V(JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX, Map, \
js_array_packed_smi_elements_map) \
V(JS_ARRAY_HOLEY_SMI_ELEMENTS_MAP_INDEX, Map, \
js_array_holey_smi_elements_map) \
V(JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX, Map, js_array_packed_elements_map) \
V(JS_ARRAY_HOLEY_ELEMENTS_MAP_INDEX, Map, js_array_holey_elements_map) \
V(JS_ARRAY_PACKED_DOUBLE_ELEMENTS_MAP_INDEX, Map, \
js_array_packed_double_elements_map) \
V(JS_ARRAY_HOLEY_DOUBLE_ELEMENTS_MAP_INDEX, Map, \
js_array_holey_double_elements_map) \
V(JS_MAP_FUN_INDEX, JSFunction, js_map_fun) \
V(JS_MAP_MAP_INDEX, Map, js_map_map) \
V(JS_MODULE_NAMESPACE_MAP, Map, js_module_namespace_map) \
V(JS_SET_FUN_INDEX, JSFunction, js_set_fun) \
V(JS_SET_MAP_INDEX, Map, js_set_map) \
V(JS_WEAK_MAP_FUN_INDEX, JSFunction, js_weak_map_fun) \
V(JS_WEAK_SET_FUN_INDEX, JSFunction, js_weak_set_fun) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(MAP_KEY_ITERATOR_MAP_INDEX, Map, map_key_iterator_map) \
V(MAP_KEY_VALUE_ITERATOR_MAP_INDEX, Map, map_key_value_iterator_map) \
V(MAP_VALUE_ITERATOR_MAP_INDEX, Map, map_value_iterator_map) \
V(MATH_RANDOM_INDEX_INDEX, Smi, math_random_index) \
V(MATH_RANDOM_STATE_INDEX, ByteArray, math_random_state) \
V(MATH_RANDOM_CACHE_INDEX, FixedDoubleArray, math_random_cache) \
V(MESSAGE_LISTENERS_INDEX, TemplateList, message_listeners) \
V(NATIVES_UTILS_OBJECT_INDEX, Object, natives_utils_object) \
V(NORMALIZED_MAP_CACHE_INDEX, Object, normalized_map_cache) \
V(NUMBER_FUNCTION_INDEX, JSFunction, number_function) \
V(OBJECT_FUNCTION_INDEX, JSFunction, object_function) \
V(OBJECT_FUNCTION_PROTOTYPE_MAP_INDEX, Map, object_function_prototype_map) \
V(OPAQUE_REFERENCE_FUNCTION_INDEX, JSFunction, opaque_reference_function) \
V(PROXY_CALLABLE_MAP_INDEX, Map, proxy_callable_map) \
V(PROXY_CONSTRUCTOR_MAP_INDEX, Map, proxy_constructor_map) \
V(PROXY_FUNCTION_INDEX, JSFunction, proxy_function) \
V(PROXY_MAP_INDEX, Map, proxy_map) \
V(PROXY_REVOCABLE_RESULT_MAP_INDEX, Map, proxy_revocable_result_map) \
V(PROXY_REVOKE_SHARED_FUN, SharedFunctionInfo, proxy_revoke_shared_fun) \
V(PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN, SharedFunctionInfo, \
promise_get_capabilities_executor_shared_fun) \
[builtins] Refactor the promise resolution and rejection logic. This introduces dedicated builtins - FulfillPromise, - RejectPromise, and - ResolvePromise, which perform the corresponding operations from the language specification, and removes the redundant entry points and the excessive inlining of these operations into other builtins. We also add the same logic on the C++ side, so that we don't need to go into JavaScript land when resolving/rejecting from the API. The C++ side has a complete implementation, including full support for the debugger and the current PromiseHook machinery. This is to avoid constantly crossing the boundary for those cases, and to also simplify the CSA side (and soon the TurboFan side), where we only do the fast-path and bail out to the runtime for the general handling. On top of this we introduce %_RejectPromise and %_ResolvePromise, which are entry points used by the bytecode and parser desugarings for async functions, and also used by the V8 Extras API. Thanks to this we can uniformly optimize these in TurboFan, where we have corresponding operators JSRejectPromise and JSResolvePromise, which currently just call into the builtins, but middle-term can be further optimized, i.e. to skip the "then" lookup for JSResolvePromise when we know something about the resolution. In TurboFan we can also already inline the default PromiseCapability [[Reject]] and [[Resolve]] functions, although this is not as effective as it can be right now, until we have inlining support for the Promise constructor (being worked on by petermarshall@ right now) and/or SFI based CALL_IC feedback. Overall this change is meant as a refactoring without significant performance impact anywhere; it seems to improve performance of simple async functions a bit, but otherwise is neutral. Bug: v8:7253 Change-Id: Id0b979f9b2843560e38cd8df4b02627dad4b6d8c Reviewed-on: https://chromium-review.googlesource.com/911632 Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#51260}
2018-02-12 19:10:29 +00:00
V(PROMISE_CAPABILITY_DEFAULT_REJECT_SHARED_FUN_INDEX, SharedFunctionInfo, \
promise_capability_default_reject_shared_fun) \
V(PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX, SharedFunctionInfo, \
promise_capability_default_resolve_shared_fun) \
V(PROMISE_THEN_FINALLY_SHARED_FUN, SharedFunctionInfo, \
promise_then_finally_shared_fun) \
V(PROMISE_CATCH_FINALLY_SHARED_FUN, SharedFunctionInfo, \
promise_catch_finally_shared_fun) \
V(PROMISE_VALUE_THUNK_FINALLY_SHARED_FUN, SharedFunctionInfo, \
promise_value_thunk_finally_shared_fun) \
V(PROMISE_THROWER_FINALLY_SHARED_FUN, SharedFunctionInfo, \
promise_thrower_finally_shared_fun) \
V(PROMISE_ALL_RESOLVE_ELEMENT_SHARED_FUN, SharedFunctionInfo, \
promise_all_resolve_element_shared_fun) \
V(PROMISE_PROTOTYPE_INDEX, JSObject, promise_prototype) \
V(REGEXP_EXEC_FUNCTION_INDEX, JSFunction, regexp_exec_function) \
V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \
V(REGEXP_LAST_MATCH_INFO_INDEX, RegExpMatchInfo, regexp_last_match_info) \
V(REGEXP_INTERNAL_MATCH_INFO_INDEX, RegExpMatchInfo, \
regexp_internal_match_info) \
V(REGEXP_PROTOTYPE_MAP_INDEX, Map, regexp_prototype_map) \
V(INITIAL_REGEXP_STRING_ITERATOR_PROTOTYPE_MAP_INDEX, Map, \
initial_regexp_string_iterator_prototype_map) \
V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
V(SCRIPT_CONTEXT_TABLE_INDEX, ScriptContextTable, script_context_table) \
V(SECURITY_TOKEN_INDEX, Object, security_token) \
V(SERIALIZED_OBJECTS, FixedArray, serialized_objects) \
V(SET_VALUE_ITERATOR_MAP_INDEX, Map, set_value_iterator_map) \
V(SET_KEY_VALUE_ITERATOR_MAP_INDEX, Map, set_key_value_iterator_map) \
V(SHARED_ARRAY_BUFFER_FUN_INDEX, JSFunction, shared_array_buffer_fun) \
V(SLOPPY_ARGUMENTS_MAP_INDEX, Map, sloppy_arguments_map) \
V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_map) \
V(STRICT_ARGUMENTS_MAP_INDEX, Map, strict_arguments_map) \
V(SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP, Map, \
slow_object_with_null_prototype_map) \
V(SLOW_OBJECT_WITH_OBJECT_PROTOTYPE_MAP, Map, \
slow_object_with_object_prototype_map) \
V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, SimpleNumberDictionary, \
slow_template_instantiations_cache) \
/* All *_FUNCTION_MAP_INDEX definitions used by Context::FunctionMapIndex */ \
/* must remain together. */ \
V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \
V(SLOPPY_FUNCTION_WITH_NAME_MAP_INDEX, Map, sloppy_function_with_name_map) \
V(SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_without_prototype_map) \
V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_with_readonly_prototype_map) \
V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \
V(STRICT_FUNCTION_WITH_NAME_MAP_INDEX, Map, strict_function_with_name_map) \
V(STRICT_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
strict_function_with_readonly_prototype_map) \
V(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \
strict_function_without_prototype_map) \
V(METHOD_WITH_NAME_MAP_INDEX, Map, method_with_name_map) \
V(METHOD_WITH_HOME_OBJECT_MAP_INDEX, Map, method_with_home_object_map) \
V(METHOD_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX, Map, \
method_with_name_and_home_object_map) \
V(ASYNC_FUNCTION_MAP_INDEX, Map, async_function_map) \
V(ASYNC_FUNCTION_WITH_NAME_MAP_INDEX, Map, async_function_with_name_map) \
V(ASYNC_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX, Map, \
async_function_with_home_object_map) \
V(ASYNC_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX, Map, \
async_function_with_name_and_home_object_map) \
V(GENERATOR_FUNCTION_MAP_INDEX, Map, generator_function_map) \
V(GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX, Map, \
generator_function_with_name_map) \
V(GENERATOR_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX, Map, \
generator_function_with_home_object_map) \
V(GENERATOR_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX, Map, \
generator_function_with_name_and_home_object_map) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
V(ASYNC_GENERATOR_FUNCTION_MAP_INDEX, Map, async_generator_function_map) \
V(ASYNC_GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX, Map, \
async_generator_function_with_name_map) \
V(ASYNC_GENERATOR_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX, Map, \
async_generator_function_with_home_object_map) \
V(ASYNC_GENERATOR_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX, Map, \
async_generator_function_with_name_and_home_object_map) \
V(CLASS_FUNCTION_MAP_INDEX, Map, class_function_map) \
V(STRING_FUNCTION_INDEX, JSFunction, string_function) \
V(STRING_FUNCTION_PROTOTYPE_MAP_INDEX, Map, string_function_prototype_map) \
V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
V(NATIVE_FUNCTION_MAP_INDEX, Map, native_function_map) \
V(WASM_EXCEPTION_CONSTRUCTOR_INDEX, JSFunction, wasm_exception_constructor) \
V(WASM_GLOBAL_CONSTRUCTOR_INDEX, JSFunction, wasm_global_constructor) \
V(WASM_INSTANCE_CONSTRUCTOR_INDEX, JSFunction, wasm_instance_constructor) \
V(WASM_MEMORY_CONSTRUCTOR_INDEX, JSFunction, wasm_memory_constructor) \
V(WASM_MODULE_CONSTRUCTOR_INDEX, JSFunction, wasm_module_constructor) \
V(WASM_TABLE_CONSTRUCTOR_INDEX, JSFunction, wasm_table_constructor) \
V(TYPED_ARRAY_FUN_INDEX, JSFunction, typed_array_function) \
V(TYPED_ARRAY_PROTOTYPE_INDEX, JSObject, typed_array_prototype) \
V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun) \
V(UINT32_ARRAY_FUN_INDEX, JSFunction, uint32_array_fun) \
V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \
V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun) \
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
[es2015] Refactor the JSArrayIterator. This changes the JSArrayIterator to always have only a single instance type, instead of the zoo of instance types that we had before, and which became less useful with the specification update to when "next" is loaded from the iterator now. This greatly simplifies the baseline implementation of the array iterator, which now only looks at the iterated object during %ArrayIteratorPrototype%.next invocations. In TurboFan we introduce a new JSCreateArrayIterator operator, that holds the IterationKind and get's the iterated object as input. When optimizing %ArrayIteratorPrototype%.next in the JSCallReducer, we check whether the receiver is a JSCreateArrayIterator, and if so, we try to infer maps for the iterated object from there. If we find any, we speculatively assume that these won't have changed during iteration (as we did before with the previous approach), and generate fast code for both JSArray and JSTypedArray iteration. Drive-by-fix: Drop the fast_array_iteration protector, it's not necessary anymore since we have the deoptimization guard bit in the JSCallReducer now. This addresses the performance cliff noticed in webpack 4. The minimal repro on the tracking bug goes from console.timeEnd: mono, 124.773000 console.timeEnd: poly, 670.353000 to console.timeEnd: mono, 118.709000 console.timeEnd: poly, 141.393000 so that's a 4.7x improvement. Also make presubmit happy by adding the missing #undef's. Bug: v8:7510, v7:7514 Change-Id: I79a46bfa2cd0f0710e09365ef72519b1bbb667b5 Reviewed-on: https://chromium-review.googlesource.com/946098 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#51725}
2018-03-02 19:31:01 +00:00
NATIVE_CONTEXT_IMPORTED_FIELDS(V)
// A table of all script contexts. Every loaded top-level script with top-level
// lexical declarations contributes its ScriptContext into this table.
//
// The table is a fixed array, its first slot is the current used count and
// the subsequent slots 1..used contain ScriptContexts.
class ScriptContextTable : public FixedArray {
public:
// Conversions.
static inline ScriptContextTable* cast(Object* context);
struct LookupResult {
int context_index;
int slot_index;
VariableMode mode;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
};
inline int used() const;
inline void set_used(int used);
static inline Handle<Context> GetContext(Isolate* isolate,
Handle<ScriptContextTable> table,
int i);
// Lookup a variable `name` in a ScriptContextTable.
// If it returns true, the variable is found and `result` contains
// valid information about its location.
// If it returns false, `result` is untouched.
V8_WARN_UNUSED_RESULT
static bool Lookup(Isolate* isolate, Handle<ScriptContextTable> table,
Handle<String> name, LookupResult* result);
V8_WARN_UNUSED_RESULT
static Handle<ScriptContextTable> Extend(Handle<ScriptContextTable> table,
Handle<Context> script_context);
static const int kUsedSlotIndex = 0;
static const int kFirstContextSlotIndex = 1;
static const int kMinLength = kFirstContextSlotIndex;
DISALLOW_IMPLICIT_CONSTRUCTORS(ScriptContextTable);
};
// JSFunctions are pairs (context, function code), sometimes also called
// closures. A Context object is used to represent function contexts and
// dynamically pushed 'with' contexts (or 'scopes' in ECMA-262 speak).
//
// At runtime, the contexts build a stack in parallel to the execution
// stack, with the top-most context being the current context. All contexts
// have the following slots:
//
// [ scope_info ] This is the scope info describing the current context. It
// contains the names of statically allocated context slots,
// and stack-allocated locals. The names are needed for
// dynamic lookups in the presence of 'with' or 'eval', and
// for the debugger.
//
// [ previous ] A pointer to the previous context.
//
// [ extension ] Additional data.
//
// For module contexts, it contains the module object.
//
// For block contexts, it may contain an "extension object"
// (see below).
//
// For with contexts, it contains an "extension object".
//
// An "extension object" is used to dynamically extend a
// context with additional variables, namely in the
// implementation of the 'with' construct and the 'eval'
// construct. For instance, Context::Lookup also searches
// the extension object for properties. (Storing the
// extension object is the original purpose of this context
// slot, hence the name.)
//
// [ native_context ] A pointer to the native context.
//
// In addition, function contexts may have statically allocated context slots
// to store local variables/functions that are accessed from inner functions
// (via static context addresses) or through 'eval' (dynamic context lookups).
// The native context contains additional slots for fast access to native
// properties.
//
// Finally, with Harmony scoping, the JSFunction representing a top level
// script will have the ScriptContext rather than a FunctionContext.
// Script contexts from all top-level scripts are gathered in
// ScriptContextTable.
class Context : public FixedArray, public NeverReadOnlySpaceObject {
public:
// Conversions.
static inline Context* cast(Object* context);
// The default context slot layout; indices are FixedArray slot indices.
enum Field {
// These slots are in all contexts.
SCOPE_INFO_INDEX,
PREVIOUS_INDEX,
// The extension slot is used for either the global object (in native
// contexts), eval extension object (function contexts), subject of with
2011-10-21 10:26:59 +00:00
// (with contexts), or the variable name (catch contexts), the serialized
2018-09-27 20:11:42 +00:00
// scope info (block contexts), the module instance (module contexts), or
// the generator object (await contexts).
EXTENSION_INDEX,
NATIVE_CONTEXT_INDEX,
// These slots are only in native contexts.
#define NATIVE_CONTEXT_SLOT(index, type, name) index,
NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_SLOT)
#undef NATIVE_CONTEXT_SLOT
// Properties from here are treated as weak references by the full GC.
// Scavenge treats them as strong references.
OPTIMIZED_CODE_LIST, // Weak.
DEOPTIMIZED_CODE_LIST, // Weak.
NEXT_CONTEXT_LINK, // Weak.
// Total number of slots.
NATIVE_CONTEXT_SLOTS,
FIRST_WEAK_SLOT = OPTIMIZED_CODE_LIST,
FIRST_JS_ARRAY_MAP_SLOT = JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX,
MIN_CONTEXT_SLOTS = GLOBAL_PROXY_INDEX,
// This slot holds the thrown value in catch contexts.
THROWN_OBJECT_INDEX = MIN_CONTEXT_SLOTS,
// These slots hold values in debug evaluate contexts.
WRAPPED_CONTEXT_INDEX = MIN_CONTEXT_SLOTS,
WHITE_LIST_INDEX = MIN_CONTEXT_SLOTS + 1
};
// A region of native context entries containing maps for functions created
// by Builtins::kFastNewClosure.
static const int FIRST_FUNCTION_MAP_INDEX = SLOPPY_FUNCTION_MAP_INDEX;
static const int LAST_FUNCTION_MAP_INDEX = CLASS_FUNCTION_MAP_INDEX;
static const int kNoContext = 0;
static const int kInvalidContext = 1;
void ResetErrorsThrown();
void IncrementErrorsThrown();
int GetErrorsThrown();
// Direct slot access.
inline void set_scope_info(ScopeInfo* scope_info);
inline Context* previous();
inline void set_previous(Context* context);
inline Object* next_context_link();
inline bool has_extension();
inline HeapObject* extension();
inline void set_extension(HeapObject* object);
[es6] Parameter scopes for sloppy eval This CL is a nightmare! For the utterly irrelevant edge case of a sloppy function with non-simple parameters and a call to direct eval, like here, let x = 1;   function f(g = () => x) {     var y     eval("var x = 2")     return g() + x // f() = 3   } we have to do all of the following, on top of the declaration block ("varblock") contexts we already introduce around the body: - Introduce the ability for varblock contexts to have both a ScopeInfo and an extension object (e.g., the body varblock in the example will contain both a static var y and a dynamic var x). No other scope needs that. Since there are no context slots left, a special new struct is introduced that pairs up scope info and extension object. - When declaring lookup slots in the runtime, this new struct is allocated in the case where an extension object has to be added to a block scope (at which point the block's extension slot still contains a plain ScopeInfo). - While at it, introduce some abstraction to access context extension slots in a more controlled manner, in order to keep special-casing to a minimum. - Make sure that even empty varblock contexts do not get optimised away when they contain a sloppy eval, so that they can host the potential extension object. - Extend dynamic search for declaration contexts (used by sloppy direct eval) to recognize varblock contexts. - In the parser, if a function has a sloppy direct eval, introduce an additional varblock scope around each non-simple (desugared) parameter, as required by the spec to contain possible dynamic var bindings. - In the pattern rewriter, add the ability to hoist the named variables the pattern declares to an outer scope. That is required because the actual destructuring has to be evaluated inside the protecting varblock scope, but the bindings that the desugaring introduces are in the outer scope. - ScopeInfos need to save the information whether a block is a varblock, to make sloppy eval calls work correctly that deserialise them as part of the scope chain. - Add the ability to materialize block scopes with extension objects in the debugger. Likewise, enable setting extension variables in block scopes via the debugger interface. - While at it, refactor and unify some respective code in the debugger. Sorry, this CL is large. I could try to split it up, but everything is rather entangled. @mstarzinger: Please review the changes to contexts. @yangguo: Please have a look at the debugger stuff. R=littledan@chromium.org, mstarzinger@chromium.org, yangguo@chromium.org BUG=v8:811,v8:2160 LOG=N Review URL: https://codereview.chromium.org/1292753007 Cr-Commit-Position: refs/heads/master@{#30295}
2015-08-21 10:58:35 +00:00
JSObject* extension_object();
JSReceiver* extension_receiver();
ScopeInfo* scope_info();
// Find the module context (assuming there is one) and return the associated
// module object.
Module* module();
// Get the context where var declarations will be hoisted to, which
// may be the context itself.
Context* declaration_context();
[es6] Parameter scopes for sloppy eval This CL is a nightmare! For the utterly irrelevant edge case of a sloppy function with non-simple parameters and a call to direct eval, like here, let x = 1;   function f(g = () => x) {     var y     eval("var x = 2")     return g() + x // f() = 3   } we have to do all of the following, on top of the declaration block ("varblock") contexts we already introduce around the body: - Introduce the ability for varblock contexts to have both a ScopeInfo and an extension object (e.g., the body varblock in the example will contain both a static var y and a dynamic var x). No other scope needs that. Since there are no context slots left, a special new struct is introduced that pairs up scope info and extension object. - When declaring lookup slots in the runtime, this new struct is allocated in the case where an extension object has to be added to a block scope (at which point the block's extension slot still contains a plain ScopeInfo). - While at it, introduce some abstraction to access context extension slots in a more controlled manner, in order to keep special-casing to a minimum. - Make sure that even empty varblock contexts do not get optimised away when they contain a sloppy eval, so that they can host the potential extension object. - Extend dynamic search for declaration contexts (used by sloppy direct eval) to recognize varblock contexts. - In the parser, if a function has a sloppy direct eval, introduce an additional varblock scope around each non-simple (desugared) parameter, as required by the spec to contain possible dynamic var bindings. - In the pattern rewriter, add the ability to hoist the named variables the pattern declares to an outer scope. That is required because the actual destructuring has to be evaluated inside the protecting varblock scope, but the bindings that the desugaring introduces are in the outer scope. - ScopeInfos need to save the information whether a block is a varblock, to make sloppy eval calls work correctly that deserialise them as part of the scope chain. - Add the ability to materialize block scopes with extension objects in the debugger. Likewise, enable setting extension variables in block scopes via the debugger interface. - While at it, refactor and unify some respective code in the debugger. Sorry, this CL is large. I could try to split it up, but everything is rather entangled. @mstarzinger: Please review the changes to contexts. @yangguo: Please have a look at the debugger stuff. R=littledan@chromium.org, mstarzinger@chromium.org, yangguo@chromium.org BUG=v8:811,v8:2160 LOG=N Review URL: https://codereview.chromium.org/1292753007 Cr-Commit-Position: refs/heads/master@{#30295}
2015-08-21 10:58:35 +00:00
bool is_declaration_context();
// Get the next closure's context on the context chain.
Context* closure_context();
Split window support from V8. Here is a description of the background and design of split window in Chrome and V8: https://docs.google.com/a/google.com/Doc?id=chhjkpg_47fwddxbfr This change list splits the window object into two parts: 1) an inner window object used as the global object of contexts; 2) an outer window object exposed to JavaScript and accessible by the name 'window'. Firefox did it awhile ago, here are some discussions: https://wiki.mozilla.org/Gecko:SplitWindow. One additional benefit of splitting window in Chrome is that accessing global variables don't need security checks anymore, it can improve applications that use many global variables. V8 support of split window: There are a small number of changes on V8 api to support split window: Security context is removed from V8, so does related API functions; A global object can be detached from its context and reused by a new context; Access checks on an object template can be turned on/off by default; An object can turn on its access checks later; V8 has a new object type, ApiGlobalObject, which is the outer window object type. The existing JSGlobalObject becomes the inner window object type. Security checks are moved from JSGlobalObject to ApiGlobalObject. ApiGlobalObject is the one exposed to JavaScript, it is accessible through Context::Global(). ApiGlobalObject's prototype is set to JSGlobalObject so that property lookups are forwarded to JSGlobalObject. ApiGlobalObject forwards all other property access requests to JSGlobalObject, such as SetProperty, DeleteProperty, etc. Security token is moved to a global context, and ApiGlobalObject has a reference to its global context. JSGlobalObject has a reference to its global context as well. When accessing properties on a global object in JavaScript, the domain security check is performed by comparing the security token of the lexical context (Top::global_context()) to the token of global object's context. The check is only needed when the receiver is a window object, such as 'window.document'. Accessing global variables, such as 'var foo = 3; foo' does not need checks because the receiver is the inner window object. When an outer window is detached from its global context (when a frame navigates away from a page), it is completely detached from the inner window. A new context is created for the new page, and the outer global object is reused. At this point, the access check on the DOMWindow wrapper of the old context is turned on. The code in old context is still able to access DOMWindow properties, but it has to go through domain security checks. It is debatable on how to implement the outer window object. Currently each property access function has to check if the receiver is ApiGlobalObject type. This approach might be error-prone that one may forget to check the receiver when adding new functions. It is unlikely a performance issue because accessing global variables are more common than 'window.foo' style coding. I am still working on the ARM port, and I'd like to hear comments and suggestions on the best way to support it in V8. Review URL: http://codereview.chromium.org/7366 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2008-10-21 19:07:58 +00:00
// Returns a JSGlobalProxy object or null.
JSGlobalProxy* global_proxy();
void set_global_proxy(JSGlobalProxy* global);
Split window support from V8. Here is a description of the background and design of split window in Chrome and V8: https://docs.google.com/a/google.com/Doc?id=chhjkpg_47fwddxbfr This change list splits the window object into two parts: 1) an inner window object used as the global object of contexts; 2) an outer window object exposed to JavaScript and accessible by the name 'window'. Firefox did it awhile ago, here are some discussions: https://wiki.mozilla.org/Gecko:SplitWindow. One additional benefit of splitting window in Chrome is that accessing global variables don't need security checks anymore, it can improve applications that use many global variables. V8 support of split window: There are a small number of changes on V8 api to support split window: Security context is removed from V8, so does related API functions; A global object can be detached from its context and reused by a new context; Access checks on an object template can be turned on/off by default; An object can turn on its access checks later; V8 has a new object type, ApiGlobalObject, which is the outer window object type. The existing JSGlobalObject becomes the inner window object type. Security checks are moved from JSGlobalObject to ApiGlobalObject. ApiGlobalObject is the one exposed to JavaScript, it is accessible through Context::Global(). ApiGlobalObject's prototype is set to JSGlobalObject so that property lookups are forwarded to JSGlobalObject. ApiGlobalObject forwards all other property access requests to JSGlobalObject, such as SetProperty, DeleteProperty, etc. Security token is moved to a global context, and ApiGlobalObject has a reference to its global context. JSGlobalObject has a reference to its global context as well. When accessing properties on a global object in JavaScript, the domain security check is performed by comparing the security token of the lexical context (Top::global_context()) to the token of global object's context. The check is only needed when the receiver is a window object, such as 'window.document'. Accessing global variables, such as 'var foo = 3; foo' does not need checks because the receiver is the inner window object. When an outer window is detached from its global context (when a frame navigates away from a page), it is completely detached from the inner window. A new context is created for the new page, and the outer global object is reused. At this point, the access check on the DOMWindow wrapper of the old context is turned on. The code in old context is still able to access DOMWindow properties, but it has to go through domain security checks. It is debatable on how to implement the outer window object. Currently each property access function has to check if the receiver is ApiGlobalObject type. This approach might be error-prone that one may forget to check the receiver when adding new functions. It is unlikely a performance issue because accessing global variables are more common than 'window.foo' style coding. I am still working on the ARM port, and I'd like to hear comments and suggestions on the best way to support it in V8. Review URL: http://codereview.chromium.org/7366 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2008-10-21 19:07:58 +00:00
// Get the JSGlobalObject object.
V8_EXPORT_PRIVATE JSGlobalObject* global_object();
// Get the script context by traversing the context chain.
Context* script_context();
Get rid of static module allocation, do it in code. Modules now have their own local scope, represented by their own context. Module instance objects have an accessor for every export that forwards access to the respective slot from the module's context. (Exports that are modules themselves, however, are simple data properties.) All modules have a _hosting_ scope/context, which (currently) is the (innermost) enclosing global scope. To deal with recursion, nested modules are hosted by the same scope as global ones. For every (global or nested) module literal, the hosting context has an internal slot that points directly to the respective module context. This enables quick access to (statically resolved) module members by 2-dimensional access through the hosting context. For example, module A { let x; module B { let y; } } module C { let z; } allocates contexts as follows: [header| .A | .B | .C | A | C ] (global) | | | | | +-- [header| z ] (module) | | | +------- [header| y ] (module) | +------------ [header| x | B ] (module) Here, .A, .B, .C are the internal slots pointing to the hosted module contexts, whereas A, B, C hold the actual instance objects (note that every module context also points to the respective instance object through its extension slot in the header). To deal with arbitrary recursion and aliases between modules, they are created and initialized in several stages. Each stage applies to all modules in the hosting global scope, including nested ones. 1. Allocate: for each module _literal_, allocate the module contexts and respective instance object and wire them up. This happens in the PushModuleContext runtime function, as generated by AllocateModules (invoked by VisitDeclarations in the hosting scope). 2. Bind: for each module _declaration_ (i.e. literals as well as aliases), assign the respective instance object to respective local variables. This happens in VisitModuleDeclaration, and uses the instance objects created in the previous stage. For each module _literal_, this phase also constructs a module descriptor for the next stage. This happens in VisitModuleLiteral. 3. Populate: invoke the DeclareModules runtime function to populate each _instance_ object with accessors for it exports. This is generated by DeclareModules (invoked by VisitDeclarations in the hosting scope again), and uses the descriptors generated in the previous stage. 4. Initialize: execute the module bodies (and other code) in sequence. This happens by the separate statements generated for module bodies. To reenter the module scopes properly, the parser inserted ModuleStatements. R=mstarzinger@chromium.org,svenpanne@chromium.org BUG= Review URL: https://codereview.chromium.org/11093074 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13033 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2012-11-22 10:25:22 +00:00
// Compute the native context.
inline NativeContext* native_context() const;
inline void set_native_context(NativeContext* context);
// Predicates for context types. IsNativeContext is already defined on
// Object.
inline bool IsFunctionContext() const;
inline bool IsCatchContext() const;
inline bool IsWithContext() const;
inline bool IsDebugEvaluateContext() const;
2018-09-27 20:11:42 +00:00
inline bool IsAwaitContext() const;
inline bool IsBlockContext() const;
inline bool IsModuleContext() const;
inline bool IsEvalContext() const;
inline bool IsScriptContext() const;
inline bool HasSameSecurityTokenAs(Context* that) const;
// The native context also stores a list of all optimized code and a
// list of all deoptimized code, which are needed by the deoptimizer.
void AddOptimizedCode(Code* code);
void SetOptimizedCodeListHead(Object* head);
Object* OptimizedCodeListHead();
void SetDeoptimizedCodeListHead(Object* head);
Object* DeoptimizedCodeListHead();
Handle<Object> ErrorMessageForCodeGenerationFromStrings();
static int ImportedFieldIndexForName(Handle<String> name);
static int IntrinsicIndexForName(Handle<String> name);
static int IntrinsicIndexForName(const unsigned char* name, int length);
#define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
inline void set_##name(type* value); \
inline bool is_##name(type* value) const; \
inline type* name() const;
NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSORS)
#undef NATIVE_CONTEXT_FIELD_ACCESSORS
// Lookup the slot called name, starting with the current context.
// There are three possibilities:
//
// 1) result->IsContext():
// The binding was found in a context. *index is always the
// non-negative slot index. *attributes is NONE for var and let
// declarations, READ_ONLY for const declarations (never ABSENT).
//
// 2) result->IsJSObject():
// The binding was found as a named property in a context extension
// object (i.e., was introduced via eval), as a property on the subject
// of with, or as a property of the global object. *index is -1 and
// *attributes is not ABSENT.
//
// 3) result->IsModule():
// The binding was found in module imports or exports.
// *attributes is never ABSENT. imports are READ_ONLY.
//
// 4) result.is_null():
// There was no binding found, *index is always -1 and *attributes is
// always ABSENT.
Handle<Object> Lookup(Handle<String> name, ContextLookupFlags flags,
int* index, PropertyAttributes* attributes,
InitializationFlag* init_flag,
VariableMode* variable_mode,
bool* is_sloppy_function_name = nullptr);
// Code generation support.
static int SlotOffset(int index) {
return kHeaderSize + index * kPointerSize - kHeapObjectTag;
}
static inline int FunctionMapIndex(LanguageMode language_mode,
FunctionKind kind, bool has_prototype_slot,
bool has_shared_name,
bool needs_home_object);
static int ArrayMapIndex(ElementsKind elements_kind) {
DCHECK(IsFastElementsKind(elements_kind));
return elements_kind + FIRST_JS_ARRAY_MAP_SLOT;
}
inline Map* GetInitialJSArrayMap(ElementsKind kind) const;
static const int kSize = kHeaderSize + NATIVE_CONTEXT_SLOTS * kPointerSize;
static const int kNotFound = -1;
class BodyDescriptor;
private:
#ifdef DEBUG
// Bootstrapping-aware type checks.
V8_EXPORT_PRIVATE static bool IsBootstrappingOrNativeContext(Isolate* isolate,
Object* object);
static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
#endif
STATIC_ASSERT(kHeaderSize == Internals::kContextHeaderSize);
STATIC_ASSERT(EMBEDDER_DATA_INDEX == Internals::kContextEmbedderDataIndex);
};
class NativeContext : public Context {
public:
static inline NativeContext* cast(Object* context);
// TODO(neis): Move some stuff from Context here.
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(NativeContext);
};
typedef Context::Field ContextField;
} // namespace internal
} // namespace v8
#endif // V8_CONTEXTS_H_