[torque] check TNode return types of CSA macros
This disallows using CSA macros from Torque that have a Node* return type instead of TNode<>. By enforcing CSA types at the boundary between CSA and Torque, we can ensure that the Torque types and the CSA types match. As a drive-by, this CL adds a bit more of CSA typing where it made sense. Bug: v8:7793, v8:6949 Change-Id: I12ea0337c628105ea3c420be747ae50d3a172547 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1660481 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#62293}
This commit is contained in:
parent
31a951d875
commit
20d29a3617
@ -56,7 +56,7 @@ namespace array_join {
|
||||
assert(!IsDetachedBuffer(typedArray.buffer));
|
||||
return typed_array::LoadFixedTypedArrayElementAsTagged(
|
||||
typedArray.data_ptr, UnsafeCast<Smi>(k),
|
||||
typed_array::KindForArrayType<T>(), SMI_PARAMETERS);
|
||||
typed_array::KindForArrayType<T>());
|
||||
}
|
||||
|
||||
transitioning builtin ConvertToLocaleString(
|
||||
|
@ -189,9 +189,7 @@ type LayoutDescriptor extends ByteArray
|
||||
type TransitionArray extends WeakFixedArray
|
||||
generates 'TNode<TransitionArray>';
|
||||
|
||||
// InstanceType actually extends uint16, but a bunch of methods in
|
||||
// CodeStubAssembler expect a TNode<Int32T>, so keeping it signed for now.
|
||||
type InstanceType extends int16 constexpr 'InstanceType';
|
||||
type InstanceType extends uint16 constexpr 'InstanceType';
|
||||
|
||||
extern class Map extends HeapObject {
|
||||
instance_size_in_words: uint8;
|
||||
@ -342,8 +340,8 @@ extern class JSFunction extends JSObject {
|
||||
}
|
||||
|
||||
extern class JSProxy extends JSReceiver {
|
||||
target: Object;
|
||||
handler: Object;
|
||||
target: JSReceiver | Null;
|
||||
handler: JSReceiver | Null;
|
||||
}
|
||||
|
||||
// Just a starting shape for JSObject; properties can move after initialization.
|
||||
@ -763,8 +761,6 @@ type LanguageMode extends Smi constexpr 'LanguageMode';
|
||||
type ExtractFixedArrayFlags
|
||||
generates 'TNode<Smi>'
|
||||
constexpr 'CodeStubAssembler::ExtractFixedArrayFlags';
|
||||
type ParameterMode
|
||||
generates 'TNode<Int32T>' constexpr 'ParameterMode';
|
||||
type WriteBarrierMode
|
||||
generates 'TNode<Int32T>' constexpr 'WriteBarrierMode';
|
||||
|
||||
@ -1128,11 +1124,6 @@ const false: constexpr bool generates 'false';
|
||||
const kStrict: constexpr LanguageMode generates 'LanguageMode::kStrict';
|
||||
const kSloppy: constexpr LanguageMode generates 'LanguageMode::kSloppy';
|
||||
|
||||
const SMI_PARAMETERS: constexpr ParameterMode
|
||||
generates 'CodeStubAssembler::SMI_PARAMETERS';
|
||||
const INTPTR_PARAMETERS: constexpr ParameterMode
|
||||
generates 'CodeStubAssembler::INTPTR_PARAMETERS';
|
||||
|
||||
const SKIP_WRITE_BARRIER:
|
||||
constexpr WriteBarrierMode generates 'SKIP_WRITE_BARRIER';
|
||||
const UNSAFE_SKIP_WRITE_BARRIER:
|
||||
@ -2059,7 +2050,7 @@ extern macro ChangeInt32ToIntPtr(int32): intptr; // Sign-extends.
|
||||
extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend.
|
||||
extern macro LoadNativeContext(Context): NativeContext;
|
||||
extern macro TruncateFloat64ToFloat32(float64): float32;
|
||||
extern macro TruncateHeapNumberValueToWord32(Number): int32;
|
||||
extern macro TruncateHeapNumberValueToWord32(HeapNumber): int32;
|
||||
extern macro LoadJSArrayElementsMap(constexpr ElementsKind, Context): Map;
|
||||
extern macro LoadJSArrayElementsMap(ElementsKind, Context): Map;
|
||||
extern macro ChangeNonnegativeNumberToUintPtr(Number): uintptr;
|
||||
@ -2487,7 +2478,7 @@ extern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray;
|
||||
extern macro AllocateJSArray(Map, FixedArrayBase, Smi): JSArray;
|
||||
extern macro AllocateJSObjectFromMap(Map): JSObject;
|
||||
extern macro AllocateJSObjectFromMap(
|
||||
Map, FixedArray, FixedArray, constexpr AllocationFlags,
|
||||
Map, FixedArray | PropertyArray, FixedArray, constexpr AllocationFlags,
|
||||
constexpr SlackTrackingMode): JSObject;
|
||||
|
||||
extern macro LoadDoubleWithHoleCheck(FixedDoubleArray, Smi): float64
|
||||
|
@ -266,7 +266,8 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context,
|
||||
var_list1, argument_offset, mapped_offset,
|
||||
[this, elements, ¤t_argument](Node* offset) {
|
||||
Increment(¤t_argument, kSystemPointerSize);
|
||||
Node* arg = LoadBufferObject(current_argument.value(), 0);
|
||||
Node* arg = LoadBufferObject(
|
||||
UncheckedCast<RawPtrT>(current_argument.value()), 0);
|
||||
StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset,
|
||||
arg);
|
||||
},
|
||||
|
@ -227,7 +227,7 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler(
|
||||
VariableList list({&a_, &k_, &to_}, zone());
|
||||
|
||||
FastLoopBody body = [&](Node* index) {
|
||||
GotoIf(IsDetachedBuffer(array_buffer), detached);
|
||||
GotoIf(IsDetachedBuffer(CAST(array_buffer)), detached);
|
||||
TNode<RawPtrT> data_ptr = LoadJSTypedArrayBackingStore(typed_array);
|
||||
Node* value = LoadFixedTypedArrayElementAsTagged(
|
||||
data_ptr, index, source_elements_kind_, SMI_PARAMETERS);
|
||||
@ -402,7 +402,7 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
|
||||
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
|
||||
TNode<Object> receiver = args.GetReceiver();
|
||||
TNode<JSArray> array_receiver;
|
||||
Node* kind = nullptr;
|
||||
TNode<Int32T> kind;
|
||||
|
||||
Label fast(this);
|
||||
BranchIfFastJSArray(receiver, context, &fast, &runtime);
|
||||
@ -709,19 +709,19 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
|
||||
iterator_assembler.GetIterator(context, items, iterator_method);
|
||||
|
||||
TNode<Context> native_context = LoadNativeContext(context);
|
||||
TNode<Object> fast_iterator_result_map =
|
||||
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
|
||||
TNode<Map> fast_iterator_result_map = CAST(
|
||||
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX));
|
||||
|
||||
Goto(&loop);
|
||||
|
||||
BIND(&loop);
|
||||
{
|
||||
// Loop while iterator is not done.
|
||||
TNode<Object> next = iterator_assembler.IteratorStep(
|
||||
TNode<JSReceiver> next = iterator_assembler.IteratorStep(
|
||||
context, iterator_record, &loop_done, fast_iterator_result_map);
|
||||
TVARIABLE(Object, value,
|
||||
CAST(iterator_assembler.IteratorValue(
|
||||
context, next, fast_iterator_result_map)));
|
||||
iterator_assembler.IteratorValue(context, next,
|
||||
fast_iterator_result_map));
|
||||
|
||||
// If a map_function is supplied then call it (using this_arg as
|
||||
// receiver), on the value returned from the iterator. Exceptions are
|
||||
@ -2035,8 +2035,7 @@ void ArrayBuiltinsAssembler::CreateArrayDispatchSingleArgument(
|
||||
&normal_sequence);
|
||||
{
|
||||
// Make elements kind holey and update elements kind in the type info.
|
||||
var_elements_kind =
|
||||
Signed(Word32Or(var_elements_kind.value(), Int32Constant(1)));
|
||||
var_elements_kind = Word32Or(var_elements_kind.value(), Int32Constant(1));
|
||||
StoreObjectFieldNoWriteBarrier(
|
||||
allocation_site, AllocationSite::kTransitionInfoOrBoilerplateOffset,
|
||||
SmiOr(transition_info, SmiConstant(fast_elements_kind_holey_mask)));
|
||||
|
@ -15,22 +15,23 @@ namespace internal {
|
||||
|
||||
// ES6 #sec-boolean.prototype.tostring
|
||||
TF_BUILTIN(BooleanPrototypeToString, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* value = ToThisValue(context, receiver, PrimitiveType::kBoolean,
|
||||
"Boolean.prototype.toString");
|
||||
Node* result = LoadObjectField(value, Oddball::kToStringOffset);
|
||||
TNode<Oddball> value =
|
||||
CAST(ToThisValue(context, receiver, PrimitiveType::kBoolean,
|
||||
"Boolean.prototype.toString"));
|
||||
TNode<String> result = CAST(LoadObjectField(value, Oddball::kToStringOffset));
|
||||
Return(result);
|
||||
}
|
||||
|
||||
// ES6 #sec-boolean.prototype.valueof
|
||||
TF_BUILTIN(BooleanPrototypeValueOf, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* result = ToThisValue(context, receiver, PrimitiveType::kBoolean,
|
||||
"Boolean.prototype.valueOf");
|
||||
TNode<Oddball> result = CAST(ToThisValue(
|
||||
context, receiver, PrimitiveType::kBoolean, "Boolean.prototype.valueOf"));
|
||||
Return(result);
|
||||
}
|
||||
|
||||
|
@ -66,19 +66,19 @@ class BaseCollectionsAssembler : public CodeStubAssembler {
|
||||
TNode<Object> iterable);
|
||||
|
||||
// Constructs a collection instance. Choosing a fast path when possible.
|
||||
TNode<Object> AllocateJSCollection(TNode<Context> context,
|
||||
TNode<JSFunction> constructor,
|
||||
TNode<Object> new_target);
|
||||
TNode<JSObject> AllocateJSCollection(TNode<Context> context,
|
||||
TNode<JSFunction> constructor,
|
||||
TNode<JSReceiver> new_target);
|
||||
|
||||
// Fast path for constructing a collection instance if the constructor
|
||||
// function has not been modified.
|
||||
TNode<Object> AllocateJSCollectionFast(TNode<HeapObject> constructor);
|
||||
TNode<JSObject> AllocateJSCollectionFast(TNode<JSFunction> constructor);
|
||||
|
||||
// Fallback for constructing a collection instance if the constructor function
|
||||
// has been modified.
|
||||
TNode<Object> AllocateJSCollectionSlow(TNode<Context> context,
|
||||
TNode<JSFunction> constructor,
|
||||
TNode<Object> new_target);
|
||||
TNode<JSObject> AllocateJSCollectionSlow(TNode<Context> context,
|
||||
TNode<JSFunction> constructor,
|
||||
TNode<JSReceiver> new_target);
|
||||
|
||||
// Allocates the backing store for a collection.
|
||||
virtual TNode<Object> AllocateTable(Variant variant, TNode<Context> context,
|
||||
@ -320,17 +320,17 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromIterable(
|
||||
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsUndefined(iterator.object)));
|
||||
|
||||
TNode<Object> fast_iterator_result_map =
|
||||
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
|
||||
TNode<Map> fast_iterator_result_map = CAST(
|
||||
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX));
|
||||
TVARIABLE(Object, var_exception);
|
||||
|
||||
Goto(&loop);
|
||||
BIND(&loop);
|
||||
{
|
||||
TNode<Object> next = iterator_assembler.IteratorStep(
|
||||
TNode<JSReceiver> next = iterator_assembler.IteratorStep(
|
||||
context, iterator, &exit, fast_iterator_result_map);
|
||||
TNode<Object> next_value = CAST(iterator_assembler.IteratorValue(
|
||||
context, next, fast_iterator_result_map));
|
||||
TNode<Object> next_value = iterator_assembler.IteratorValue(
|
||||
context, next, fast_iterator_result_map);
|
||||
AddConstructorEntry(variant, context, collection, add_func, next_value,
|
||||
nullptr, &if_exception, &var_exception);
|
||||
Goto(&loop);
|
||||
@ -367,33 +367,33 @@ void BaseCollectionsAssembler::GotoIfInitialAddFunctionModified(
|
||||
GetAddFunctionNameIndex(variant), if_modified);
|
||||
}
|
||||
|
||||
TNode<Object> BaseCollectionsAssembler::AllocateJSCollection(
|
||||
TNode<JSObject> BaseCollectionsAssembler::AllocateJSCollection(
|
||||
TNode<Context> context, TNode<JSFunction> constructor,
|
||||
TNode<Object> new_target) {
|
||||
TNode<JSReceiver> new_target) {
|
||||
TNode<BoolT> is_target_unmodified = WordEqual(constructor, new_target);
|
||||
|
||||
return Select<Object>(is_target_unmodified,
|
||||
[=] { return AllocateJSCollectionFast(constructor); },
|
||||
[=] {
|
||||
return AllocateJSCollectionSlow(context, constructor,
|
||||
new_target);
|
||||
});
|
||||
return Select<JSObject>(
|
||||
is_target_unmodified,
|
||||
[=] { return AllocateJSCollectionFast(constructor); },
|
||||
[=] {
|
||||
return AllocateJSCollectionSlow(context, constructor, new_target);
|
||||
});
|
||||
}
|
||||
|
||||
TNode<Object> BaseCollectionsAssembler::AllocateJSCollectionFast(
|
||||
TNode<HeapObject> constructor) {
|
||||
TNode<JSObject> BaseCollectionsAssembler::AllocateJSCollectionFast(
|
||||
TNode<JSFunction> constructor) {
|
||||
CSA_ASSERT(this, IsConstructorMap(LoadMap(constructor)));
|
||||
TNode<Object> initial_map =
|
||||
LoadObjectField(constructor, JSFunction::kPrototypeOrInitialMapOffset);
|
||||
return CAST(AllocateJSObjectFromMap(initial_map));
|
||||
TNode<Map> initial_map =
|
||||
CAST(LoadJSFunctionPrototypeOrInitialMap(constructor));
|
||||
return AllocateJSObjectFromMap(initial_map);
|
||||
}
|
||||
|
||||
TNode<Object> BaseCollectionsAssembler::AllocateJSCollectionSlow(
|
||||
TNode<JSObject> BaseCollectionsAssembler::AllocateJSCollectionSlow(
|
||||
TNode<Context> context, TNode<JSFunction> constructor,
|
||||
TNode<Object> new_target) {
|
||||
TNode<JSReceiver> new_target) {
|
||||
ConstructorBuiltinsAssembler constructor_assembler(this->state());
|
||||
return CAST(constructor_assembler.EmitFastNewObject(context, constructor,
|
||||
new_target));
|
||||
return constructor_assembler.EmitFastNewObject(context, constructor,
|
||||
new_target);
|
||||
}
|
||||
|
||||
void BaseCollectionsAssembler::GenerateConstructor(
|
||||
@ -408,7 +408,7 @@ void BaseCollectionsAssembler::GenerateConstructor(
|
||||
|
||||
TNode<Context> native_context = LoadNativeContext(context);
|
||||
TNode<Object> collection = AllocateJSCollection(
|
||||
context, GetConstructor(variant, native_context), new_target);
|
||||
context, GetConstructor(variant, native_context), CAST(new_target));
|
||||
|
||||
AddConstructorEntries(variant, context, native_context, collection, iterable);
|
||||
Return(collection);
|
||||
|
@ -147,44 +147,40 @@ TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* target = Parameter(Descriptor::kTarget);
|
||||
Node* new_target = Parameter(Descriptor::kNewTarget);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<JSFunction> target = CAST(Parameter(Descriptor::kTarget));
|
||||
TNode<JSReceiver> new_target = CAST(Parameter(Descriptor::kNewTarget));
|
||||
|
||||
Label call_runtime(this);
|
||||
|
||||
Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
|
||||
TNode<JSObject> result =
|
||||
EmitFastNewObject(context, target, new_target, &call_runtime);
|
||||
Return(result);
|
||||
|
||||
BIND(&call_runtime);
|
||||
TailCallRuntime(Runtime::kNewObject, context, target, new_target);
|
||||
}
|
||||
|
||||
Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
|
||||
Node* target,
|
||||
Node* new_target) {
|
||||
VARIABLE(var_obj, MachineRepresentation::kTagged);
|
||||
compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
|
||||
SloppyTNode<Context> context, SloppyTNode<JSFunction> target,
|
||||
SloppyTNode<JSReceiver> new_target) {
|
||||
TVARIABLE(JSObject, var_obj);
|
||||
Label call_runtime(this), end(this);
|
||||
|
||||
Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
|
||||
var_obj.Bind(result);
|
||||
var_obj = EmitFastNewObject(context, target, new_target, &call_runtime);
|
||||
Goto(&end);
|
||||
|
||||
BIND(&call_runtime);
|
||||
var_obj.Bind(CallRuntime(Runtime::kNewObject, context, target, new_target));
|
||||
var_obj = CAST(CallRuntime(Runtime::kNewObject, context, target, new_target));
|
||||
Goto(&end);
|
||||
|
||||
BIND(&end);
|
||||
return var_obj.value();
|
||||
}
|
||||
|
||||
Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
|
||||
Node* target,
|
||||
Node* new_target,
|
||||
Label* call_runtime) {
|
||||
CSA_ASSERT(this, HasInstanceType(target, JS_FUNCTION_TYPE));
|
||||
CSA_ASSERT(this, IsJSReceiver(new_target));
|
||||
|
||||
compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
|
||||
SloppyTNode<Context> context, SloppyTNode<JSFunction> target,
|
||||
SloppyTNode<JSReceiver> new_target, Label* call_runtime) {
|
||||
// Verify that the new target is a JSFunction.
|
||||
Label fast(this), end(this);
|
||||
GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast);
|
||||
|
@ -31,10 +31,14 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler {
|
||||
Label* call_runtime);
|
||||
Node* EmitCreateEmptyObjectLiteral(Node* context);
|
||||
|
||||
Node* EmitFastNewObject(Node* context, Node* target, Node* new_target);
|
||||
TNode<JSObject> EmitFastNewObject(SloppyTNode<Context> context,
|
||||
SloppyTNode<JSFunction> target,
|
||||
SloppyTNode<JSReceiver> new_target);
|
||||
|
||||
Node* EmitFastNewObject(Node* context, Node* target, Node* new_target,
|
||||
Label* call_runtime);
|
||||
TNode<JSObject> EmitFastNewObject(SloppyTNode<Context> context,
|
||||
SloppyTNode<JSFunction> target,
|
||||
SloppyTNode<JSReceiver> new_target,
|
||||
Label* call_runtime);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -17,13 +17,13 @@ class DataViewBuiltinsAssembler : public CodeStubAssembler {
|
||||
explicit DataViewBuiltinsAssembler(compiler::CodeAssemblerState* state)
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
TNode<Int32T> LoadUint8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) {
|
||||
return UncheckedCast<Int32T>(
|
||||
TNode<Uint8T> LoadUint8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) {
|
||||
return UncheckedCast<Uint8T>(
|
||||
Load(MachineType::Uint8(), data_pointer, offset));
|
||||
}
|
||||
|
||||
TNode<Int32T> LoadInt8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) {
|
||||
return UncheckedCast<Int32T>(
|
||||
TNode<Int8T> LoadInt8(TNode<RawPtrT> data_pointer, TNode<UintPtrT> offset) {
|
||||
return UncheckedCast<Int8T>(
|
||||
Load(MachineType::Int8(), data_pointer, offset));
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context,
|
||||
}
|
||||
}
|
||||
|
||||
TNode<Object> IteratorBuiltinsAssembler::IteratorStep(
|
||||
TNode<JSReceiver> IteratorBuiltinsAssembler::IteratorStep(
|
||||
Node* context, const IteratorRecord& iterator, Label* if_done,
|
||||
Node* fast_iterator_result_map, Label* if_exception, Variable* exception) {
|
||||
DCHECK_NOT_NULL(if_done);
|
||||
@ -125,23 +125,21 @@ TNode<Object> IteratorBuiltinsAssembler::IteratorStep(
|
||||
}
|
||||
|
||||
BIND(&return_result);
|
||||
return UncheckedCast<Object>(result);
|
||||
return CAST(result);
|
||||
}
|
||||
|
||||
Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result,
|
||||
Node* fast_iterator_result_map,
|
||||
Label* if_exception,
|
||||
Variable* exception) {
|
||||
CSA_ASSERT(this, IsJSReceiver(result));
|
||||
|
||||
TNode<Object> IteratorBuiltinsAssembler::IteratorValue(
|
||||
TNode<Context> context, TNode<JSReceiver> result,
|
||||
base::Optional<TNode<Map>> fast_iterator_result_map, Label* if_exception,
|
||||
Variable* exception) {
|
||||
Label exit(this);
|
||||
VARIABLE(var_value, MachineRepresentation::kTagged);
|
||||
if (fast_iterator_result_map != nullptr) {
|
||||
TVARIABLE(Object, var_value);
|
||||
if (fast_iterator_result_map) {
|
||||
// Fast iterator result case:
|
||||
Label if_generic(this);
|
||||
Node* map = LoadMap(result);
|
||||
GotoIfNot(WordEqual(map, fast_iterator_result_map), &if_generic);
|
||||
var_value.Bind(LoadObjectField(result, JSIteratorResult::kValueOffset));
|
||||
GotoIfNot(WordEqual(map, *fast_iterator_result_map), &if_generic);
|
||||
var_value = LoadObjectField(result, JSIteratorResult::kValueOffset);
|
||||
Goto(&exit);
|
||||
|
||||
BIND(&if_generic);
|
||||
@ -149,9 +147,10 @@ Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result,
|
||||
|
||||
// Generic iterator result case:
|
||||
{
|
||||
Node* value = GetProperty(context, result, factory()->value_string());
|
||||
TNode<Object> value =
|
||||
GetProperty(context, result, factory()->value_string());
|
||||
GotoIfException(value, if_exception, exception);
|
||||
var_value.Bind(value);
|
||||
var_value = value;
|
||||
Goto(&exit);
|
||||
}
|
||||
|
||||
@ -217,10 +216,10 @@ TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
|
||||
BIND(&loop_start);
|
||||
{
|
||||
// a. Set next to ? IteratorStep(iteratorRecord).
|
||||
TNode<Object> next = IteratorStep(context, iterator_record, &done);
|
||||
TNode<JSReceiver> next = IteratorStep(context, iterator_record, &done);
|
||||
// b. If next is not false, then
|
||||
// i. Let nextValue be ? IteratorValue(next).
|
||||
TNode<Object> next_value = CAST(IteratorValue(context, next));
|
||||
TNode<Object> next_value = IteratorValue(context, next);
|
||||
// ii. Append nextValue to the end of the List values.
|
||||
values.Push(next_value);
|
||||
Goto(&loop_start);
|
||||
|
@ -32,18 +32,19 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
|
||||
Variable* exception = nullptr);
|
||||
|
||||
// https://tc39.github.io/ecma262/#sec-iteratorstep
|
||||
// Returns `false` if the iterator is done, otherwise returns an
|
||||
// iterator result.
|
||||
// If the iterator is done, goto {if_done}, otherwise returns an iterator
|
||||
// result.
|
||||
// `fast_iterator_result_map` refers to the map for the JSIteratorResult
|
||||
// object, loaded from the native context.
|
||||
TNode<Object> IteratorStep(Node* context, const IteratorRecord& iterator,
|
||||
Label* if_done,
|
||||
Node* fast_iterator_result_map = nullptr,
|
||||
Label* if_exception = nullptr,
|
||||
Variable* exception = nullptr);
|
||||
TNode<JSReceiver> IteratorStep(Node* context, const IteratorRecord& iterator,
|
||||
Label* if_done,
|
||||
Node* fast_iterator_result_map = nullptr,
|
||||
Label* if_exception = nullptr,
|
||||
Variable* exception = nullptr);
|
||||
|
||||
TNode<Object> IteratorStep(Node* context, const IteratorRecord& iterator,
|
||||
Node* fast_iterator_result_map, Label* if_done) {
|
||||
TNode<JSReceiver> IteratorStep(Node* context, const IteratorRecord& iterator,
|
||||
Node* fast_iterator_result_map,
|
||||
Label* if_done) {
|
||||
return IteratorStep(context, iterator, if_done, fast_iterator_result_map);
|
||||
}
|
||||
|
||||
@ -51,10 +52,10 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
|
||||
// Return the `value` field from an iterator.
|
||||
// `fast_iterator_result_map` refers to the map for the JSIteratorResult
|
||||
// object, loaded from the native context.
|
||||
Node* IteratorValue(Node* context, Node* result,
|
||||
Node* fast_iterator_result_map = nullptr,
|
||||
Label* if_exception = nullptr,
|
||||
Variable* exception = nullptr);
|
||||
TNode<Object> IteratorValue(
|
||||
TNode<Context> context, TNode<JSReceiver> result,
|
||||
base::Optional<TNode<Map>> fast_iterator_result_map = base::nullopt,
|
||||
Label* if_exception = nullptr, Variable* exception = nullptr);
|
||||
|
||||
// https://tc39.github.io/ecma262/#sec-iteratorclose
|
||||
void IteratorCloseOnException(Node* context, const IteratorRecord& iterator,
|
||||
|
@ -315,8 +315,8 @@ TF_BUILTIN(NumberParseInt, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-number.prototype.valueof
|
||||
TF_BUILTIN(NumberPrototypeValueOf, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* result = ToThisValue(context, receiver, PrimitiveType::kNumber,
|
||||
"Number.prototype.valueOf");
|
||||
@ -996,8 +996,8 @@ TF_BUILTIN(Equal, CodeStubAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(StrictEqual, CodeStubAssembler) {
|
||||
Node* lhs = Parameter(Descriptor::kLeft);
|
||||
Node* rhs = Parameter(Descriptor::kRight);
|
||||
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
|
||||
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
|
||||
|
||||
Return(StrictEqual(lhs, rhs));
|
||||
}
|
||||
|
@ -2077,9 +2077,9 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll(
|
||||
// Let next be IteratorStep(iteratorRecord.[[Iterator]]).
|
||||
// If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||
// ReturnIfAbrupt(next).
|
||||
Node* const fast_iterator_result_map =
|
||||
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
|
||||
Node* const next = iter_assembler.IteratorStep(
|
||||
TNode<Map> const fast_iterator_result_map = CAST(
|
||||
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX));
|
||||
TNode<JSReceiver> const next = iter_assembler.IteratorStep(
|
||||
native_context, iterator, &done_loop, fast_iterator_result_map,
|
||||
if_exception, var_exception);
|
||||
|
||||
@ -2087,7 +2087,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll(
|
||||
// If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to
|
||||
// true.
|
||||
// ReturnIfAbrupt(nextValue).
|
||||
Node* const next_value = iter_assembler.IteratorValue(
|
||||
TNode<Object> const next_value = iter_assembler.IteratorValue(
|
||||
native_context, next, fast_iterator_result_map, if_exception,
|
||||
var_exception);
|
||||
|
||||
@ -2148,7 +2148,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll(
|
||||
&if_slow);
|
||||
GotoIf(IsPromiseSpeciesProtectorCellInvalid(), &if_slow);
|
||||
GotoIf(TaggedIsSmi(next_value), &if_slow);
|
||||
Node* const next_value_map = LoadMap(next_value);
|
||||
Node* const next_value_map = LoadMap(CAST(next_value));
|
||||
BranchIfPromiseThenLookupChainIntact(native_context, next_value_map,
|
||||
&if_fast, &if_slow);
|
||||
|
||||
@ -2526,8 +2526,7 @@ TF_BUILTIN(PromiseAllSettledResolveElementClosure, PromiseBuiltinsAssembler) {
|
||||
LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX));
|
||||
TNode<Map> object_function_map = Cast(LoadObjectField(
|
||||
object_function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
TNode<JSObject> obj =
|
||||
Cast(AllocateJSObjectFromMap(object_function_map));
|
||||
TNode<JSObject> obj = AllocateJSObjectFromMap(object_function_map);
|
||||
|
||||
// 10. Perform ! CreateDataProperty(obj, "status", "fulfilled").
|
||||
CallBuiltin(Builtins::kFastCreateDataProperty, context, obj,
|
||||
@ -2557,8 +2556,7 @@ TF_BUILTIN(PromiseAllSettledRejectElementClosure, PromiseBuiltinsAssembler) {
|
||||
LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX));
|
||||
TNode<Map> object_function_map = Cast(LoadObjectField(
|
||||
object_function, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
TNode<JSObject> obj =
|
||||
Cast(AllocateJSObjectFromMap(object_function_map));
|
||||
TNode<JSObject> obj = AllocateJSObjectFromMap(object_function_map);
|
||||
|
||||
// 10. Perform ! CreateDataProperty(obj, "status", "rejected").
|
||||
CallBuiltin(Builtins::kFastCreateDataProperty, context, obj,
|
||||
@ -2579,7 +2577,7 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
|
||||
VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());
|
||||
|
||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* const context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> const context = CAST(Parameter(Descriptor::kContext));
|
||||
ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
|
||||
"Promise.race");
|
||||
|
||||
@ -2630,7 +2628,7 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
|
||||
|
||||
// 4. If IsCallable(_promiseResolve_) is *false*, throw a *TypeError*
|
||||
// exception.
|
||||
ThrowIfNotCallable(CAST(context), resolve, "resolve");
|
||||
ThrowIfNotCallable(context, resolve, "resolve");
|
||||
|
||||
var_promise_resolve_function = resolve;
|
||||
Goto(&loop);
|
||||
@ -2638,13 +2636,13 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
|
||||
|
||||
BIND(&loop);
|
||||
{
|
||||
Node* const fast_iterator_result_map = LoadContextElement(
|
||||
native_context, Context::ITERATOR_RESULT_MAP_INDEX);
|
||||
TNode<Map> const fast_iterator_result_map = CAST(LoadContextElement(
|
||||
native_context, Context::ITERATOR_RESULT_MAP_INDEX));
|
||||
|
||||
// Let next be IteratorStep(iteratorRecord.[[Iterator]]).
|
||||
// If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
||||
// ReturnIfAbrupt(next).
|
||||
Node* const next = iter_assembler.IteratorStep(
|
||||
TNode<JSReceiver> const next = iter_assembler.IteratorStep(
|
||||
context, iterator, &break_loop, fast_iterator_result_map,
|
||||
&reject_promise, &var_exception);
|
||||
|
||||
@ -2652,7 +2650,7 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
|
||||
// If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to
|
||||
// true.
|
||||
// ReturnIfAbrupt(nextValue).
|
||||
Node* const next_value =
|
||||
TNode<Object> const next_value =
|
||||
iter_assembler.IteratorValue(context, next, fast_iterator_result_map,
|
||||
&reject_promise, &var_exception);
|
||||
|
||||
|
@ -13,8 +13,9 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
Node* ProxiesCodeStubAssembler::AllocateProxy(Node* target, Node* handler,
|
||||
Node* context) {
|
||||
compiler::TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
|
||||
TNode<Context> context, TNode<JSReceiver> target,
|
||||
TNode<JSReceiver> handler) {
|
||||
VARIABLE(map, MachineRepresentation::kTagged);
|
||||
|
||||
Label callable_target(this), constructor_target(this), none_target(this),
|
||||
@ -53,7 +54,7 @@ Node* ProxiesCodeStubAssembler::AllocateProxy(Node* target, Node* handler,
|
||||
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target);
|
||||
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler);
|
||||
|
||||
return proxy;
|
||||
return CAST(proxy);
|
||||
}
|
||||
|
||||
Node* ProxiesCodeStubAssembler::AllocateJSArrayForCodeStubArguments(
|
||||
@ -121,8 +122,9 @@ Node* ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext(
|
||||
return context;
|
||||
}
|
||||
|
||||
Node* ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(Node* proxy,
|
||||
Node* context) {
|
||||
compiler::TNode<JSFunction>
|
||||
ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(TNode<Context> context,
|
||||
TNode<JSProxy> proxy) {
|
||||
Node* const native_context = LoadNativeContext(context);
|
||||
|
||||
Node* const proxy_context =
|
||||
@ -132,8 +134,8 @@ Node* ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(Node* proxy,
|
||||
Node* const revoke_info =
|
||||
LoadContextElement(native_context, Context::PROXY_REVOKE_SHARED_FUN);
|
||||
|
||||
return AllocateFunctionWithMapAndContext(revoke_map, revoke_info,
|
||||
proxy_context);
|
||||
return CAST(AllocateFunctionWithMapAndContext(revoke_map, revoke_info,
|
||||
proxy_context));
|
||||
}
|
||||
|
||||
TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) {
|
||||
@ -257,8 +259,9 @@ TF_BUILTIN(ConstructProxy, ProxiesCodeStubAssembler) {
|
||||
{ ThrowTypeError(context, MessageTemplate::kProxyRevoked, "construct"); }
|
||||
}
|
||||
|
||||
Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
Node* context, Node* target, Node* proxy, Node* name, Node* trap_result,
|
||||
void ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
TNode<Context> context, TNode<JSReceiver> target, TNode<JSProxy> proxy,
|
||||
TNode<Name> name, TNode<Object> trap_result,
|
||||
JSProxy::AccessKind access_kind) {
|
||||
// TODO(mslekova): Think of a better name for the trap_result param.
|
||||
Node* map = LoadMap(target);
|
||||
@ -269,7 +272,7 @@ Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
Label if_found_value(this), check_in_runtime(this, Label::kDeferred),
|
||||
check_passed(this);
|
||||
|
||||
GotoIfNot(IsUniqueNameNoIndex(CAST(name)), &check_in_runtime);
|
||||
GotoIfNot(IsUniqueNameNoIndex(name), &check_in_runtime);
|
||||
Node* instance_type = LoadInstanceType(target);
|
||||
TryGetOwnProperty(context, target, target, map, instance_type, name,
|
||||
&if_found_value, &var_value, &var_details, &var_raw_value,
|
||||
@ -362,12 +365,13 @@ Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
}
|
||||
|
||||
BIND(&check_passed);
|
||||
return trap_result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
|
||||
Node* proxy, Node* name) {
|
||||
void ProxiesCodeStubAssembler::CheckHasTrapResult(TNode<Context> context,
|
||||
TNode<JSReceiver> target,
|
||||
TNode<JSProxy> proxy,
|
||||
TNode<Name> name) {
|
||||
Node* target_map = LoadMap(target);
|
||||
VARIABLE(var_value, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_details, MachineRepresentation::kWord32);
|
||||
@ -379,7 +383,7 @@ Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
|
||||
check_in_runtime(this, Label::kDeferred);
|
||||
|
||||
// 9.a. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
||||
GotoIfNot(IsUniqueNameNoIndex(CAST(name)), &check_in_runtime);
|
||||
GotoIfNot(IsUniqueNameNoIndex(name), &check_in_runtime);
|
||||
Node* instance_type = LoadInstanceType(target);
|
||||
TryGetOwnProperty(context, target, target, target_map, instance_type, name,
|
||||
&if_found_value, &var_value, &var_details, &var_raw_value,
|
||||
@ -415,7 +419,6 @@ Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
|
||||
}
|
||||
|
||||
BIND(&check_passed);
|
||||
return FalseConstant();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -17,15 +17,18 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
|
||||
explicit ProxiesCodeStubAssembler(compiler::CodeAssemblerState* state)
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
Node* AllocateProxy(Node* target, Node* handler, Node* context);
|
||||
Node* AllocateProxyRevokeFunction(Node* proxy, Node* context);
|
||||
TNode<JSProxy> AllocateProxy(TNode<Context> context, TNode<JSReceiver> target,
|
||||
TNode<JSReceiver> handler);
|
||||
TNode<JSFunction> AllocateProxyRevokeFunction(TNode<Context> context,
|
||||
TNode<JSProxy> proxy);
|
||||
|
||||
Node* CheckGetSetTrapResult(Node* context, Node* target, Node* proxy,
|
||||
Node* name, Node* trap_result,
|
||||
JSProxy::AccessKind access_kind);
|
||||
void CheckGetSetTrapResult(TNode<Context> context, TNode<JSReceiver> target,
|
||||
TNode<JSProxy> proxy, TNode<Name> name,
|
||||
TNode<Object> trap_result,
|
||||
JSProxy::AccessKind access_kind);
|
||||
|
||||
Node* CheckHasTrapResult(Node* context, Node* target, Node* proxy,
|
||||
Node* name);
|
||||
void CheckHasTrapResult(TNode<Context> context, TNode<JSReceiver> target,
|
||||
TNode<JSProxy> proxy, TNode<Name> name);
|
||||
|
||||
protected:
|
||||
enum ProxyRevokeFunctionContextSlot {
|
||||
|
@ -110,12 +110,12 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpCreate(TNode<Context> context,
|
||||
TNode<String> pattern = Select<String>(
|
||||
IsUndefined(maybe_string), [=] { return EmptyStringConstant(); },
|
||||
[=] { return ToString_Inline(context, maybe_string); });
|
||||
TNode<Object> regexp = CAST(AllocateJSObjectFromMap(initial_map));
|
||||
TNode<JSObject> regexp = AllocateJSObjectFromMap(initial_map);
|
||||
return CallRuntime(Runtime::kRegExpInitializeAndCompile, context, regexp,
|
||||
pattern, flags);
|
||||
}
|
||||
|
||||
TNode<Object> RegExpBuiltinsAssembler::FastLoadLastIndex(
|
||||
TNode<Object> RegExpBuiltinsAssembler::FastLoadLastIndexBeforeSmiCheck(
|
||||
TNode<JSRegExp> regexp) {
|
||||
// Load the in-object field.
|
||||
static const int field_offset =
|
||||
@ -137,23 +137,27 @@ TNode<Object> RegExpBuiltinsAssembler::LoadLastIndex(TNode<Context> context,
|
||||
|
||||
// The fast-path of StoreLastIndex when regexp is guaranteed to be an unmodified
|
||||
// JSRegExp instance.
|
||||
void RegExpBuiltinsAssembler::FastStoreLastIndex(Node* regexp, Node* value) {
|
||||
void RegExpBuiltinsAssembler::FastStoreLastIndex(TNode<JSRegExp> regexp,
|
||||
TNode<Smi> value) {
|
||||
// Store the in-object field.
|
||||
static const int field_offset =
|
||||
JSRegExp::kSize + JSRegExp::kLastIndexFieldIndex * kTaggedSize;
|
||||
StoreObjectField(regexp, field_offset, value);
|
||||
}
|
||||
|
||||
void RegExpBuiltinsAssembler::SlowStoreLastIndex(Node* context, Node* regexp,
|
||||
Node* value) {
|
||||
Node* const name = HeapConstant(isolate()->factory()->lastIndex_string());
|
||||
SetPropertyStrict(CAST(context), CAST(regexp), CAST(name), CAST(value));
|
||||
void RegExpBuiltinsAssembler::SlowStoreLastIndex(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> regexp,
|
||||
SloppyTNode<Number> value) {
|
||||
TNode<Name> name = HeapConstant(isolate()->factory()->lastIndex_string());
|
||||
SetPropertyStrict(context, regexp, name, value);
|
||||
}
|
||||
|
||||
void RegExpBuiltinsAssembler::StoreLastIndex(Node* context, Node* regexp,
|
||||
Node* value, bool is_fastpath) {
|
||||
void RegExpBuiltinsAssembler::StoreLastIndex(TNode<Context> context,
|
||||
TNode<Object> regexp,
|
||||
TNode<Number> value,
|
||||
bool is_fastpath) {
|
||||
if (is_fastpath) {
|
||||
FastStoreLastIndex(regexp, value);
|
||||
FastStoreLastIndex(CAST(regexp), CAST(value));
|
||||
} else {
|
||||
SlowStoreLastIndex(context, regexp, value);
|
||||
}
|
||||
@ -266,8 +270,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
|
||||
native_context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP));
|
||||
TNode<NameDictionary> properties = AllocateNameDictionary(num_properties);
|
||||
|
||||
TNode<JSObject> group_object =
|
||||
CAST(AllocateJSObjectFromMap(map, properties));
|
||||
TNode<JSObject> group_object = AllocateJSObjectFromMap(map, properties);
|
||||
StoreObjectField(result, JSRegExpResult::kGroupsOffset, group_object);
|
||||
|
||||
TVARIABLE(IntPtrT, var_i, IntPtrZero());
|
||||
@ -770,7 +773,7 @@ RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
|
||||
GotoIfNot(should_update_last_index, &out);
|
||||
|
||||
// Update the new last index from {match_indices}.
|
||||
TNode<Number> new_lastindex = CAST(UnsafeLoadFixedArrayElement(
|
||||
TNode<Smi> new_lastindex = CAST(UnsafeLoadFixedArrayElement(
|
||||
CAST(match_indices), RegExpMatchInfo::kFirstCaptureIndex + 1));
|
||||
|
||||
StoreLastIndex(context, regexp, new_lastindex, is_fastpath);
|
||||
@ -867,7 +870,7 @@ Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(Node* const context,
|
||||
|
||||
// The smi check is required to omit ToLength(lastIndex) calls with possible
|
||||
// user-code execution on the fast path.
|
||||
Node* const last_index = FastLoadLastIndex(CAST(object));
|
||||
TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object));
|
||||
var_result.Bind(TaggedIsPositiveSmi(last_index));
|
||||
Goto(&out);
|
||||
|
||||
@ -912,7 +915,7 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpWithOriginalExec(
|
||||
BIND(&check_last_index);
|
||||
// The smi check is required to omit ToLength(lastIndex) calls with possible
|
||||
// user-code execution on the fast path.
|
||||
TNode<Object> last_index = FastLoadLastIndex(object);
|
||||
TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(object);
|
||||
var_result = TaggedIsPositiveSmi(last_index);
|
||||
Goto(&out);
|
||||
|
||||
@ -969,7 +972,7 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp(
|
||||
|
||||
// The smi check is required to omit ToLength(lastIndex) calls with possible
|
||||
// user-code execution on the fast path.
|
||||
Node* const last_index = FastLoadLastIndex(CAST(object));
|
||||
TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object));
|
||||
Branch(TaggedIsPositiveSmi(last_index), if_isunmodified, if_ismodified);
|
||||
}
|
||||
|
||||
@ -1822,10 +1825,9 @@ TF_BUILTIN(RegExpPrototypeTestFast, RegExpBuiltinsAssembler) {
|
||||
Return(FalseConstant());
|
||||
}
|
||||
|
||||
Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
|
||||
Node* const index,
|
||||
Node* const is_unicode,
|
||||
bool is_fastpath) {
|
||||
TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex(
|
||||
SloppyTNode<String> string, SloppyTNode<Number> index,
|
||||
SloppyTNode<BoolT> is_unicode, bool is_fastpath) {
|
||||
CSA_ASSERT(this, IsString(string));
|
||||
CSA_ASSERT(this, IsNumberNormalized(index));
|
||||
if (is_fastpath) CSA_ASSERT(this, TaggedIsPositiveSmi(index));
|
||||
@ -1833,8 +1835,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
|
||||
// Default to last_index + 1.
|
||||
// TODO(pwong): Consider using TrySmiAdd for the fast path to reduce generated
|
||||
// code.
|
||||
Node* const index_plus_one = NumberInc(index);
|
||||
VARIABLE(var_result, MachineRepresentation::kTagged, index_plus_one);
|
||||
TNode<Number> index_plus_one = NumberInc(index);
|
||||
TVARIABLE(Number, var_result, index_plus_one);
|
||||
|
||||
// Advancing the index has some subtle issues involving the distinction
|
||||
// between Smis and HeapNumbers. There's three cases:
|
||||
@ -1861,10 +1863,10 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
|
||||
BIND(&if_isunicode);
|
||||
{
|
||||
TNode<IntPtrT> const string_length = LoadStringLengthAsWord(string);
|
||||
TNode<IntPtrT> untagged_plus_one = SmiUntag(index_plus_one);
|
||||
TNode<IntPtrT> untagged_plus_one = SmiUntag(CAST(index_plus_one));
|
||||
GotoIfNot(IntPtrLessThan(untagged_plus_one, string_length), &out);
|
||||
|
||||
Node* const lead = StringCharCodeAt(string, SmiUntag(index));
|
||||
Node* const lead = StringCharCodeAt(string, SmiUntag(CAST(index)));
|
||||
GotoIfNot(Word32Equal(Word32And(lead, Int32Constant(0xFC00)),
|
||||
Int32Constant(0xD800)),
|
||||
&out);
|
||||
@ -1875,8 +1877,8 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
|
||||
&out);
|
||||
|
||||
// At a surrogate pair, return index + 2.
|
||||
Node* const index_plus_two = NumberInc(index_plus_one);
|
||||
var_result.Bind(index_plus_two);
|
||||
TNode<Number> index_plus_two = NumberInc(index_plus_one);
|
||||
var_result = index_plus_two;
|
||||
|
||||
Goto(&out);
|
||||
}
|
||||
@ -1885,31 +1887,30 @@ Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string,
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
|
||||
Node* const regexp,
|
||||
void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(TNode<Context> context,
|
||||
TNode<Object> regexp,
|
||||
TNode<String> string,
|
||||
const bool is_fastpath) {
|
||||
if (is_fastpath) CSA_ASSERT(this, IsFastRegExp(context, regexp));
|
||||
|
||||
Node* const is_global =
|
||||
FlagGetter(CAST(context), CAST(regexp), JSRegExp::kGlobal, is_fastpath);
|
||||
FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath);
|
||||
|
||||
Label if_isglobal(this), if_isnotglobal(this);
|
||||
Branch(is_global, &if_isglobal, &if_isnotglobal);
|
||||
|
||||
BIND(&if_isnotglobal);
|
||||
{
|
||||
Node* const result =
|
||||
is_fastpath
|
||||
? RegExpPrototypeExecBody(CAST(context), CAST(regexp), string, true)
|
||||
: RegExpExec(context, regexp, string);
|
||||
Node* const result = is_fastpath ? RegExpPrototypeExecBody(
|
||||
context, CAST(regexp), string, true)
|
||||
: RegExpExec(context, regexp, string);
|
||||
Return(result);
|
||||
}
|
||||
|
||||
BIND(&if_isglobal);
|
||||
{
|
||||
Node* const is_unicode = FlagGetter(CAST(context), CAST(regexp),
|
||||
JSRegExp::kUnicode, is_fastpath);
|
||||
Node* const is_unicode =
|
||||
FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath);
|
||||
|
||||
StoreLastIndex(context, regexp, SmiZero(), is_fastpath);
|
||||
|
||||
@ -1950,8 +1951,8 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
|
||||
// On the fast path, grab the matching string from the raw match index
|
||||
// array.
|
||||
TNode<RegExpMatchInfo> match_indices =
|
||||
RegExpPrototypeExecBodyWithoutResult(CAST(context), CAST(regexp),
|
||||
string, &if_didnotmatch, true);
|
||||
RegExpPrototypeExecBodyWithoutResult(context, CAST(regexp), string,
|
||||
&if_didnotmatch, true);
|
||||
|
||||
Label dosubstring(this), donotsubstring(this);
|
||||
Branch(var_atom.value(), &donotsubstring, &dosubstring);
|
||||
@ -2003,15 +2004,14 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
|
||||
TNode<Smi> const match_length = LoadStringLengthAsSmi(match);
|
||||
GotoIfNot(SmiEqual(match_length, SmiZero()), &loop);
|
||||
|
||||
Node* last_index =
|
||||
LoadLastIndex(CAST(context), CAST(regexp), is_fastpath);
|
||||
Node* last_index = LoadLastIndex(context, regexp, is_fastpath);
|
||||
if (is_fastpath) {
|
||||
CSA_ASSERT(this, TaggedIsPositiveSmi(last_index));
|
||||
} else {
|
||||
last_index = ToLength_Inline(context, last_index);
|
||||
}
|
||||
|
||||
Node* const new_last_index =
|
||||
TNode<Number> new_last_index =
|
||||
AdvanceStringIndex(string, last_index, is_unicode, is_fastpath);
|
||||
|
||||
if (is_fastpath) {
|
||||
@ -2032,7 +2032,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(Node* const context,
|
||||
{
|
||||
// Wrap the match in a JSArray.
|
||||
|
||||
Node* const result = array.ToJSArray(CAST(context));
|
||||
Node* const result = array.ToJSArray(context);
|
||||
Return(result);
|
||||
}
|
||||
}
|
||||
@ -2049,7 +2049,7 @@ TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) {
|
||||
ThrowIfNotJSReceiver(context, maybe_receiver,
|
||||
MessageTemplate::kIncompatibleMethodReceiver,
|
||||
"RegExp.prototype.@@match");
|
||||
Node* const receiver = maybe_receiver;
|
||||
TNode<JSReceiver> receiver = CAST(maybe_receiver);
|
||||
|
||||
// Convert {maybe_string} to a String.
|
||||
TNode<String> const string = ToString_Inline(context, maybe_string);
|
||||
@ -2101,7 +2101,8 @@ void RegExpMatchAllAssembler::Generate(TNode<Context> context,
|
||||
|
||||
// 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
|
||||
// 8. Perform ? Set(matcher, "lastIndex", lastIndex, true).
|
||||
FastStoreLastIndex(var_matcher.value(), FastLoadLastIndex(fast_regexp));
|
||||
FastStoreLastIndex(CAST(var_matcher.value()),
|
||||
FastLoadLastIndex(fast_regexp));
|
||||
|
||||
// 9. If flags contains "g", let global be true.
|
||||
// 10. Else, let global be false.
|
||||
@ -2241,12 +2242,11 @@ TF_BUILTIN(RegExpMatchFast, RegExpBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
|
||||
Node* const context, Node* const regexp, Node* const string) {
|
||||
TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string) {
|
||||
CSA_ASSERT(this, IsFastRegExp(context, regexp));
|
||||
CSA_ASSERT(this, IsString(string));
|
||||
|
||||
// Grab the initial value of last index.
|
||||
Node* const previous_last_index = FastLoadLastIndex(CAST(regexp));
|
||||
TNode<Smi> previous_last_index = FastLoadLastIndex(regexp);
|
||||
|
||||
// Ensure last index is 0.
|
||||
FastStoreLastIndex(regexp, SmiZero());
|
||||
@ -2254,7 +2254,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
|
||||
// Call exec.
|
||||
Label if_didnotmatch(this);
|
||||
TNode<RegExpMatchInfo> match_indices = RegExpPrototypeExecBodyWithoutResult(
|
||||
CAST(context), CAST(regexp), CAST(string), &if_didnotmatch, true);
|
||||
context, regexp, string, &if_didnotmatch, true);
|
||||
|
||||
// Successful match.
|
||||
{
|
||||
@ -2854,16 +2854,14 @@ TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) {
|
||||
GotoIfNot(IsEmptyString(match_str), &return_result);
|
||||
|
||||
// 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")).
|
||||
TNode<Smi> this_index = CAST(FastLoadLastIndex(CAST(iterating_regexp)));
|
||||
CSA_ASSERT(this, TaggedIsSmi(this_index));
|
||||
TNode<Smi> this_index = FastLoadLastIndex(CAST(iterating_regexp));
|
||||
|
||||
// 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode).
|
||||
TNode<Smi> next_index = CAST(AdvanceStringIndex(
|
||||
iterating_string, this_index, HasUnicodeFlag(flags), true));
|
||||
CSA_ASSERT(this, TaggedIsSmi(next_index));
|
||||
TNode<Smi> next_index = AdvanceStringIndexFast(
|
||||
iterating_string, this_index, HasUnicodeFlag(flags));
|
||||
|
||||
// 3. Perform ? Set(R, "lastIndex", nextIndex, true).
|
||||
FastStoreLastIndex(iterating_regexp, next_index);
|
||||
FastStoreLastIndex(CAST(iterating_regexp), next_index);
|
||||
|
||||
// iii. Return ! CreateIterResultObject(match, false).
|
||||
Goto(&return_result);
|
||||
@ -2881,8 +2879,8 @@ TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) {
|
||||
TNode<Number> this_index = ToLength_Inline(context, last_index);
|
||||
|
||||
// 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode).
|
||||
TNode<Object> next_index = CAST(AdvanceStringIndex(
|
||||
iterating_string, this_index, HasUnicodeFlag(flags), false));
|
||||
TNode<Number> next_index = AdvanceStringIndex(
|
||||
iterating_string, this_index, HasUnicodeFlag(flags), false);
|
||||
|
||||
// 3. Perform ? Set(R, "lastIndex", nextIndex, true).
|
||||
SlowStoreLastIndex(context, iterating_regexp, next_index);
|
||||
|
@ -42,15 +42,20 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<Context> context, TNode<Smi> length, TNode<Smi> index,
|
||||
TNode<String> input, TNode<FixedArray>* elements_out = nullptr);
|
||||
|
||||
TNode<Object> FastLoadLastIndex(TNode<JSRegExp> regexp);
|
||||
TNode<Object> FastLoadLastIndexBeforeSmiCheck(TNode<JSRegExp> regexp);
|
||||
TNode<Smi> FastLoadLastIndex(TNode<JSRegExp> regexp) {
|
||||
return CAST(FastLoadLastIndexBeforeSmiCheck(regexp));
|
||||
}
|
||||
TNode<Object> SlowLoadLastIndex(TNode<Context> context, TNode<Object> regexp);
|
||||
TNode<Object> LoadLastIndex(TNode<Context> context, TNode<Object> regexp,
|
||||
bool is_fastpath);
|
||||
|
||||
void FastStoreLastIndex(Node* regexp, Node* value);
|
||||
void SlowStoreLastIndex(Node* context, Node* regexp, Node* value);
|
||||
void StoreLastIndex(Node* context, Node* regexp, Node* value,
|
||||
bool is_fastpath);
|
||||
void FastStoreLastIndex(TNode<JSRegExp> regexp, TNode<Smi> value);
|
||||
void SlowStoreLastIndex(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> regexp,
|
||||
SloppyTNode<Number> value);
|
||||
void StoreLastIndex(TNode<Context> context, TNode<Object> regexp,
|
||||
TNode<Number> value, bool is_fastpath);
|
||||
|
||||
// Loads {var_string_start} and {var_string_end} with the corresponding
|
||||
// offsets into the given {string_data}.
|
||||
@ -127,20 +132,23 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
||||
|
||||
Node* RegExpExec(Node* context, Node* regexp, Node* string);
|
||||
|
||||
Node* AdvanceStringIndex(Node* const string, Node* const index,
|
||||
Node* const is_unicode, bool is_fastpath);
|
||||
TNode<Number> AdvanceStringIndex(SloppyTNode<String> string,
|
||||
SloppyTNode<Number> index,
|
||||
SloppyTNode<BoolT> is_unicode,
|
||||
bool is_fastpath);
|
||||
|
||||
Node* AdvanceStringIndexFast(Node* const string, Node* const index,
|
||||
Node* const is_unicode) {
|
||||
return AdvanceStringIndex(string, index, is_unicode, true);
|
||||
TNode<Smi> AdvanceStringIndexFast(TNode<String> string, TNode<Smi> index,
|
||||
TNode<BoolT> is_unicode) {
|
||||
return CAST(AdvanceStringIndex(string, index, is_unicode, true));
|
||||
}
|
||||
|
||||
void RegExpPrototypeMatchBody(Node* const context, Node* const regexp,
|
||||
void RegExpPrototypeMatchBody(TNode<Context> context, TNode<Object> regexp,
|
||||
TNode<String> const string,
|
||||
const bool is_fastpath);
|
||||
|
||||
void RegExpPrototypeSearchBodyFast(Node* const context, Node* const regexp,
|
||||
Node* const string);
|
||||
void RegExpPrototypeSearchBodyFast(TNode<Context> context,
|
||||
TNode<JSRegExp> regexp,
|
||||
TNode<String> string);
|
||||
void RegExpPrototypeSearchBodySlow(Node* const context, Node* const regexp,
|
||||
Node* const string);
|
||||
|
||||
|
@ -1986,12 +1986,12 @@ TNode<Int32T> StringBuiltinsAssembler::LoadSurrogatePairAt(
|
||||
|
||||
switch (encoding) {
|
||||
case UnicodeEncoding::UTF16:
|
||||
var_result = Signed(Word32Or(
|
||||
var_result = Word32Or(
|
||||
// Need to swap the order for big-endian platforms
|
||||
#if V8_TARGET_BIG_ENDIAN
|
||||
Word32Shl(lead, Int32Constant(16)), trail));
|
||||
Word32Shl(lead, Int32Constant(16)), trail);
|
||||
#else
|
||||
Word32Shl(trail, Int32Constant(16)), lead));
|
||||
Word32Shl(trail, Int32Constant(16)), lead);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -2002,8 +2002,8 @@ TNode<Int32T> StringBuiltinsAssembler::LoadSurrogatePairAt(
|
||||
Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00);
|
||||
|
||||
// (lead << 10) + trail + SURROGATE_OFFSET
|
||||
var_result = Signed(Int32Add(Word32Shl(lead, Int32Constant(10)),
|
||||
Int32Add(trail, surrogate_offset)));
|
||||
var_result = Int32Add(Word32Shl(lead, Int32Constant(10)),
|
||||
Int32Add(trail, surrogate_offset));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ namespace internal {
|
||||
// ES #sec-symbol-objects
|
||||
// ES #sec-symbol.prototype.description
|
||||
TF_BUILTIN(SymbolPrototypeDescriptionGetter, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* value = ToThisValue(context, receiver, PrimitiveType::kSymbol,
|
||||
"Symbol.prototype.description");
|
||||
@ -24,8 +24,8 @@ TF_BUILTIN(SymbolPrototypeDescriptionGetter, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-symbol.prototype-@@toprimitive
|
||||
TF_BUILTIN(SymbolPrototypeToPrimitive, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* result = ToThisValue(context, receiver, PrimitiveType::kSymbol,
|
||||
"Symbol.prototype [ @@toPrimitive ]");
|
||||
@ -34,8 +34,8 @@ TF_BUILTIN(SymbolPrototypeToPrimitive, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-symbol.prototype.tostring
|
||||
TF_BUILTIN(SymbolPrototypeToString, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* value = ToThisValue(context, receiver, PrimitiveType::kSymbol,
|
||||
"Symbol.prototype.toString");
|
||||
@ -45,8 +45,8 @@ TF_BUILTIN(SymbolPrototypeToString, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-symbol.prototype.valueof
|
||||
TF_BUILTIN(SymbolPrototypeValueOf, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
|
||||
|
||||
Node* result = ToThisValue(context, receiver, PrimitiveType::kSymbol,
|
||||
"Symbol.prototype.valueOf");
|
||||
|
@ -169,13 +169,13 @@ TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) {
|
||||
Return(ChangeUintPtrToTagged(length));
|
||||
}
|
||||
|
||||
TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
|
||||
TNode<BoolT> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
|
||||
TNode<Word32T> kind) {
|
||||
return Word32Or(Word32Equal(kind, Int32Constant(UINT8_ELEMENTS)),
|
||||
Word32Equal(kind, Int32Constant(UINT8_CLAMPED_ELEMENTS)));
|
||||
}
|
||||
|
||||
TNode<Word32T> TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
|
||||
TNode<BoolT> TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
|
||||
TNode<Word32T> kind) {
|
||||
return Word32Or(Word32Equal(kind, Int32Constant(BIGINT64_ELEMENTS)),
|
||||
Word32Equal(kind, Int32Constant(BIGUINT64_ELEMENTS)));
|
||||
@ -268,10 +268,9 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::GetBuffer(
|
||||
Label call_runtime(this), done(this);
|
||||
TVARIABLE(Object, var_result);
|
||||
|
||||
TNode<Object> buffer = LoadObjectField(array, JSTypedArray::kBufferOffset);
|
||||
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(array);
|
||||
GotoIf(IsDetachedBuffer(buffer), &call_runtime);
|
||||
TNode<UintPtrT> backing_store = LoadObjectField<UintPtrT>(
|
||||
CAST(buffer), JSArrayBuffer::kBackingStoreOffset);
|
||||
TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStore(buffer);
|
||||
GotoIf(WordEqual(backing_store, IntPtrConstant(0)), &call_runtime);
|
||||
var_result = buffer;
|
||||
Goto(&done);
|
||||
@ -301,10 +300,10 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource(
|
||||
TNode<Context> context, TNode<JSTypedArray> source,
|
||||
TNode<JSTypedArray> target, TNode<IntPtrT> offset, Label* call_runtime,
|
||||
Label* if_source_too_large) {
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(
|
||||
LoadObjectField(source, JSTypedArray::kBufferOffset))));
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(
|
||||
LoadObjectField(target, JSTypedArray::kBufferOffset))));
|
||||
CSA_ASSERT(this, Word32BinaryNot(
|
||||
IsDetachedBuffer(LoadJSArrayBufferViewBuffer(source))));
|
||||
CSA_ASSERT(this, Word32BinaryNot(
|
||||
IsDetachedBuffer(LoadJSArrayBufferViewBuffer(target))));
|
||||
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(offset, IntPtrConstant(0)));
|
||||
CSA_ASSERT(this,
|
||||
IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));
|
||||
@ -748,8 +747,8 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
|
||||
|
||||
// ToNumber/ToBigInt may execute JavaScript code, which could
|
||||
// detach the array's buffer.
|
||||
Node* buffer =
|
||||
LoadObjectField(new_typed_array, JSTypedArray::kBufferOffset);
|
||||
TNode<JSArrayBuffer> buffer =
|
||||
LoadJSArrayBufferViewBuffer(new_typed_array);
|
||||
GotoIf(IsDetachedBuffer(buffer), &if_detached);
|
||||
|
||||
// GC may move backing store in ToNumber, thus load backing
|
||||
@ -971,8 +970,8 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
|
||||
|
||||
// ToNumber/ToBigInt may execute JavaScript code, which could
|
||||
// detach the array's buffer.
|
||||
Node* buffer = LoadObjectField(target_obj.value(),
|
||||
JSTypedArray::kBufferOffset);
|
||||
TNode<JSArrayBuffer> buffer =
|
||||
LoadJSArrayBufferViewBuffer(target_obj.value());
|
||||
GotoIf(IsDetachedBuffer(buffer), &if_detached);
|
||||
|
||||
// GC may move backing store in map_fn, thus load backing
|
||||
|
@ -41,10 +41,10 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
|
||||
TNode<UintPtrT> byte_offset);
|
||||
|
||||
// Returns true if kind is either UINT8_ELEMENTS or UINT8_CLAMPED_ELEMENTS.
|
||||
TNode<Word32T> IsUint8ElementsKind(TNode<Word32T> kind);
|
||||
TNode<BoolT> IsUint8ElementsKind(TNode<Word32T> kind);
|
||||
|
||||
// Returns true if kind is either BIGINT64_ELEMENTS or BIGUINT64_ELEMENTS.
|
||||
TNode<Word32T> IsBigInt64ElementsKind(TNode<Word32T> kind);
|
||||
TNode<BoolT> IsBigInt64ElementsKind(TNode<Word32T> kind);
|
||||
|
||||
// Returns the byte size of an element for a TypedArray elements kind.
|
||||
TNode<IntPtrT> GetTypedArrayElementSize(TNode<Word32T> elements_kind);
|
||||
|
@ -20,16 +20,16 @@ namespace iterator {
|
||||
implicit context: Context)(Object): IteratorRecord;
|
||||
|
||||
extern macro IteratorBuiltinsAssembler::IteratorStep(
|
||||
implicit context: Context)(IteratorRecord): Object
|
||||
implicit context: Context)(IteratorRecord): JSReceiver
|
||||
labels Done;
|
||||
extern macro IteratorBuiltinsAssembler::IteratorStep(
|
||||
implicit context: Context)(IteratorRecord, Map): Object
|
||||
implicit context: Context)(IteratorRecord, Map): JSReceiver
|
||||
labels Done;
|
||||
|
||||
extern macro IteratorBuiltinsAssembler::IteratorValue(
|
||||
implicit context: Context)(Object): Object;
|
||||
implicit context: Context)(JSReceiver): Object;
|
||||
extern macro IteratorBuiltinsAssembler::IteratorValue(
|
||||
implicit context: Context)(Object, Map): Object;
|
||||
implicit context: Context)(JSReceiver, Map): Object;
|
||||
|
||||
extern macro IteratorBuiltinsAssembler::IteratorCloseOnException(
|
||||
implicit context: Context)(IteratorRecord, Object): never;
|
||||
|
@ -47,7 +47,8 @@ namespace object {
|
||||
try {
|
||||
assert(!IsNullOrUndefined(i.object));
|
||||
while (true) {
|
||||
const step: Object = iterator::IteratorStep(i, fastIteratorResultMap)
|
||||
const step: JSReceiver =
|
||||
iterator::IteratorStep(i, fastIteratorResultMap)
|
||||
otherwise return result;
|
||||
const iteratorValue: Object =
|
||||
iterator::IteratorValue(step, fastIteratorResultMap);
|
||||
|
@ -22,30 +22,32 @@ namespace proxy {
|
||||
assert(!IsPrivateSymbol(name));
|
||||
|
||||
// 2. Let handler be O.[[ProxyHandler]].
|
||||
const handler: Object = proxy.handler;
|
||||
|
||||
// 3. If handler is null, throw a TypeError exception.
|
||||
if (handler == Null) {
|
||||
ThrowTypeError(kProxyRevoked, 'get');
|
||||
// 4. Assert: Type(handler) is Object.
|
||||
let handler: JSReceiver;
|
||||
typeswitch (proxy.handler) {
|
||||
case (Null): {
|
||||
ThrowTypeError(kProxyRevoked, 'get');
|
||||
}
|
||||
case (h: JSReceiver): {
|
||||
handler = h;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Assert: Type(handler) is Object.
|
||||
const handlerJSReceiver = UnsafeCast<JSReceiver>(handler);
|
||||
|
||||
// 5. Let target be O.[[ProxyTarget]].
|
||||
const target = proxy.target;
|
||||
const target = Cast<JSReceiver>(proxy.target) otherwise unreachable;
|
||||
|
||||
// 6. Let trap be ? GetMethod(handler, "get").
|
||||
// 7. If trap is undefined, then (see 7.a below).
|
||||
// 7.a. Return ? target.[[Get]](P, Receiver).
|
||||
// TODO(mslekova): Introduce GetPropertyWithReceiver stub
|
||||
const trap: Callable = GetMethod(handlerJSReceiver, 'get')
|
||||
const trap: Callable = GetMethod(handler, 'get')
|
||||
otherwise return GetPropertyWithReceiver(
|
||||
target, name, receiverValue, onNonExistent);
|
||||
|
||||
// 8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
|
||||
const trapResult =
|
||||
Call(context, trap, handlerJSReceiver, target, name, receiverValue);
|
||||
Call(context, trap, handler, target, name, receiverValue);
|
||||
|
||||
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
||||
// 10. If targetDesc is not undefined and targetDesc.[[Configurable]] is
|
||||
@ -58,6 +60,7 @@ namespace proxy {
|
||||
// is undefined, then
|
||||
// i. If trapResult is not undefined, throw a TypeError exception.
|
||||
// 11. Return trapResult.
|
||||
return CheckGetSetTrapResult(target, proxy, name, trapResult, kProxyGet);
|
||||
CheckGetSetTrapResult(target, proxy, name, trapResult, kProxyGet);
|
||||
return trapResult;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace proxy {
|
||||
Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked;
|
||||
|
||||
// 5. Let target be O.[[ProxyTarget]].
|
||||
const target = proxy.target;
|
||||
const target = Cast<JSReceiver>(proxy.target) otherwise unreachable;
|
||||
|
||||
// 6. Let trap be ? GetMethod(handler, "has").
|
||||
// 7. If trap is undefined, then (see 7.a below).
|
||||
@ -42,7 +42,8 @@ namespace proxy {
|
||||
if (BranchIfToBooleanIsTrue(trapResult)) {
|
||||
return True;
|
||||
}
|
||||
return CheckHasTrapResult(target, proxy, name);
|
||||
CheckHasTrapResult(target, proxy, name);
|
||||
return False;
|
||||
}
|
||||
label TrapUndefined(target: Object) {
|
||||
// 7.a. Return ? target.[[HasProperty]](P).
|
||||
|
@ -7,11 +7,7 @@
|
||||
namespace proxy {
|
||||
|
||||
extern macro ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(
|
||||
Object, Object): JSFunction;
|
||||
macro AllocateProxyRevokeFunction(implicit context: Context)(proxy: JSProxy):
|
||||
JSFunction {
|
||||
return AllocateProxyRevokeFunction(proxy, context);
|
||||
}
|
||||
implicit context: Context)(JSProxy): JSFunction;
|
||||
|
||||
// Proxy.revocable(target, handler)
|
||||
// https://tc39.github.io/ecma262/#sec-proxy.revocable
|
||||
|
@ -40,7 +40,7 @@ namespace proxy {
|
||||
Cast<JSReceiver>(handler) otherwise ThrowProxyHandlerRevoked;
|
||||
|
||||
// 5. Let target be O.[[ProxyTarget]].
|
||||
const target = proxy.target;
|
||||
const target = UnsafeCast<JSReceiver>(proxy.target);
|
||||
|
||||
// 6. Let trap be ? GetMethod(handler, "set").
|
||||
// 7. If trap is undefined, then (see 7.a below).
|
||||
@ -64,7 +64,8 @@ namespace proxy {
|
||||
const trapResult = Call(
|
||||
context, trap, handlerJSReceiver, target, name, value, receiverValue);
|
||||
if (BranchIfToBooleanIsTrue(trapResult)) {
|
||||
return CheckGetSetTrapResult(target, proxy, name, value, kProxySet);
|
||||
CheckGetSetTrapResult(target, proxy, name, value, kProxySet);
|
||||
return value;
|
||||
}
|
||||
ThrowTypeErrorIfStrict(
|
||||
SmiConstant(kProxyTrapReturnedFalsishFor), 'set', name);
|
||||
|
@ -7,11 +7,7 @@
|
||||
namespace proxy {
|
||||
|
||||
extern macro ProxiesCodeStubAssembler::AllocateProxy(
|
||||
JSReceiver, JSReceiver, Context): JSProxy;
|
||||
macro AllocateProxy(implicit context: Context)(
|
||||
target: JSReceiver, handler: JSReceiver): JSProxy {
|
||||
return AllocateProxy(target, handler, context);
|
||||
}
|
||||
implicit context: Context)(JSReceiver, JSReceiver): JSProxy;
|
||||
|
||||
macro IsRevokedProxy(implicit context: Context)(o: JSReceiver): bool {
|
||||
const proxy: JSProxy = Cast<JSProxy>(o) otherwise return false;
|
||||
@ -21,10 +17,10 @@ namespace proxy {
|
||||
|
||||
extern transitioning macro ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
implicit context:
|
||||
Context)(Object, JSProxy, Name, Object, constexpr int31): Object;
|
||||
Context)(JSReceiver, JSProxy, Name, Object, constexpr int31);
|
||||
|
||||
extern transitioning macro ProxiesCodeStubAssembler::CheckHasTrapResult(
|
||||
implicit context: Context)(Object, JSProxy, Name): Object;
|
||||
implicit context: Context)(JSReceiver, JSProxy, Name);
|
||||
|
||||
const kProxyNonObject: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyNonObject';
|
||||
|
@ -22,7 +22,7 @@ namespace regexp_replace {
|
||||
String, JSRegExp, Callable): String;
|
||||
|
||||
extern macro
|
||||
RegExpBuiltinsAssembler::AdvanceStringIndexFast(String, Number, bool): Smi;
|
||||
RegExpBuiltinsAssembler::AdvanceStringIndexFast(String, Smi, bool): Smi;
|
||||
extern macro
|
||||
RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResultFast(
|
||||
implicit context: Context)(JSReceiver, String):
|
||||
|
@ -70,10 +70,9 @@ namespace typed_array {
|
||||
extern macro TypedArrayBuiltinsAssembler::IsBigInt64ElementsKind(
|
||||
ElementsKind): bool;
|
||||
extern macro LoadFixedTypedArrayElementAsTagged(
|
||||
RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object;
|
||||
RawPtr, Smi, constexpr ElementsKind): Numeric;
|
||||
extern macro StoreJSTypedArrayElementFromTagged(
|
||||
Context, JSTypedArray, Smi, Object, constexpr ElementsKind,
|
||||
constexpr ParameterMode);
|
||||
Context, JSTypedArray, Smi, Object, constexpr ElementsKind);
|
||||
|
||||
type LoadFn = builtin(Context, JSTypedArray, Smi) => Object;
|
||||
type StoreFn = builtin(Context, JSTypedArray, Smi, Object) => Object;
|
||||
@ -193,15 +192,14 @@ namespace typed_array {
|
||||
builtin LoadFixedElement<T: type>(
|
||||
_context: Context, array: JSTypedArray, index: Smi): Object {
|
||||
return LoadFixedTypedArrayElementAsTagged(
|
||||
array.data_ptr, index, KindForArrayType<T>(), SMI_PARAMETERS);
|
||||
array.data_ptr, index, KindForArrayType<T>());
|
||||
}
|
||||
|
||||
builtin StoreFixedElement<T: type>(
|
||||
context: Context, typedArray: JSTypedArray, index: Smi,
|
||||
value: Object): Object {
|
||||
StoreJSTypedArrayElementFromTagged(
|
||||
context, typedArray, index, value, KindForArrayType<T>(),
|
||||
SMI_PARAMETERS);
|
||||
context, typedArray, index, value, KindForArrayType<T>());
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
|
@ -935,7 +935,7 @@ TNode<Smi> CodeStubAssembler::TrySmiDiv(TNode<Smi> dividend, TNode<Smi> divisor,
|
||||
BIND(&divisor_is_not_minus_one);
|
||||
|
||||
TNode<Int32T> untagged_result = Int32Div(untagged_dividend, untagged_divisor);
|
||||
TNode<Int32T> truncated = Signed(Int32Mul(untagged_result, untagged_divisor));
|
||||
TNode<Int32T> truncated = Int32Mul(untagged_result, untagged_divisor);
|
||||
|
||||
// Do floating point division if the remainder is not 0.
|
||||
GotoIf(Word32NotEqual(untagged_dividend, truncated), bailout);
|
||||
@ -1478,7 +1478,7 @@ TNode<Map> CodeStubAssembler::LoadMap(SloppyTNode<HeapObject> object) {
|
||||
MachineType::TaggedPointer()));
|
||||
}
|
||||
|
||||
TNode<Int32T> CodeStubAssembler::LoadInstanceType(
|
||||
TNode<Uint16T> CodeStubAssembler::LoadInstanceType(
|
||||
SloppyTNode<HeapObject> object) {
|
||||
return LoadMapInstanceType(LoadMap(object));
|
||||
}
|
||||
@ -1595,8 +1595,8 @@ TNode<Uint32T> CodeStubAssembler::LoadMapBitField3(SloppyTNode<Map> map) {
|
||||
LoadObjectField(map, Map::kBitField3Offset, MachineType::Uint32()));
|
||||
}
|
||||
|
||||
TNode<Int32T> CodeStubAssembler::LoadMapInstanceType(SloppyTNode<Map> map) {
|
||||
return UncheckedCast<Int32T>(
|
||||
TNode<Uint16T> CodeStubAssembler::LoadMapInstanceType(SloppyTNode<Map> map) {
|
||||
return UncheckedCast<Uint16T>(
|
||||
LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint16()));
|
||||
}
|
||||
|
||||
@ -2054,8 +2054,8 @@ TNode<RawPtrT> CodeStubAssembler::LoadJSTypedArrayBackingStore(
|
||||
IntPtrAdd(external_pointer, BitcastTaggedToWord(base_pointer)));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadFixedBigInt64ArrayElementAsTagged(
|
||||
Node* data_pointer, Node* offset) {
|
||||
TNode<BigInt> CodeStubAssembler::LoadFixedBigInt64ArrayElementAsTagged(
|
||||
SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset) {
|
||||
if (Is64()) {
|
||||
TNode<IntPtrT> value = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::IntPtr(), data_pointer, offset));
|
||||
@ -2073,7 +2073,8 @@ Node* CodeStubAssembler::LoadFixedBigInt64ArrayElementAsTagged(
|
||||
Load(MachineType::UintPtr(), data_pointer, offset));
|
||||
TNode<IntPtrT> high = UncheckedCast<IntPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer,
|
||||
Int32Add(offset, Int32Constant(kSystemPointerSize))));
|
||||
Int32Add(TruncateIntPtrToInt32(offset),
|
||||
Int32Constant(kSystemPointerSize))));
|
||||
#endif
|
||||
return BigIntFromInt32Pair(low, high);
|
||||
}
|
||||
@ -2184,8 +2185,9 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt64(TNode<IntPtrT> value) {
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged(
|
||||
Node* data_pointer, Node* offset) {
|
||||
compiler::TNode<BigInt>
|
||||
CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged(
|
||||
SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset) {
|
||||
Label if_zero(this), done(this);
|
||||
if (Is64()) {
|
||||
TNode<UintPtrT> value = UncheckedCast<UintPtrT>(
|
||||
@ -2204,7 +2206,8 @@ Node* CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged(
|
||||
Load(MachineType::UintPtr(), data_pointer, offset));
|
||||
TNode<UintPtrT> high = UncheckedCast<UintPtrT>(
|
||||
Load(MachineType::UintPtr(), data_pointer,
|
||||
Int32Add(offset, Int32Constant(kSystemPointerSize))));
|
||||
Int32Add(TruncateIntPtrToInt32(offset),
|
||||
Int32Constant(kSystemPointerSize))));
|
||||
#endif
|
||||
return BigIntFromUint32Pair(low, high);
|
||||
}
|
||||
@ -2252,10 +2255,10 @@ TNode<BigInt> CodeStubAssembler::BigIntFromUint64(TNode<UintPtrT> value) {
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
Node* data_pointer, Node* index_node, ElementsKind elements_kind,
|
||||
TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
TNode<RawPtrT> data_pointer, Node* index_node, ElementsKind elements_kind,
|
||||
ParameterMode parameter_mode) {
|
||||
Node* offset =
|
||||
TNode<IntPtrT> offset =
|
||||
ElementOffsetFromIndex(index_node, elements_kind, parameter_mode, 0);
|
||||
switch (elements_kind) {
|
||||
case UINT8_ELEMENTS: /* fall through */
|
||||
@ -2289,7 +2292,8 @@ Node* CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
}
|
||||
|
||||
TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
TNode<WordT> data_pointer, TNode<Smi> index, TNode<Int32T> elements_kind) {
|
||||
TNode<RawPtrT> data_pointer, TNode<Smi> index,
|
||||
TNode<Int32T> elements_kind) {
|
||||
TVARIABLE(Numeric, var_result);
|
||||
Label done(this), if_unknown_type(this, Label::kDeferred);
|
||||
int32_t elements_kinds[] = {
|
||||
@ -2315,12 +2319,12 @@ TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
BIND(&if_unknown_type);
|
||||
Unreachable();
|
||||
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
|
||||
BIND(&if_##type##array); \
|
||||
{ \
|
||||
var_result = CAST(LoadFixedTypedArrayElementAsTagged( \
|
||||
data_pointer, index, TYPE##_ELEMENTS, SMI_PARAMETERS)); \
|
||||
Goto(&done); \
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
|
||||
BIND(&if_##type##array); \
|
||||
{ \
|
||||
var_result = LoadFixedTypedArrayElementAsTagged( \
|
||||
data_pointer, index, TYPE##_ELEMENTS, SMI_PARAMETERS); \
|
||||
Goto(&done); \
|
||||
}
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
@ -2331,8 +2335,7 @@ TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
|
||||
|
||||
void CodeStubAssembler::StoreJSTypedArrayElementFromTagged(
|
||||
TNode<Context> context, TNode<JSTypedArray> typed_array,
|
||||
TNode<Object> index_node, TNode<Object> value, ElementsKind elements_kind,
|
||||
ParameterMode parameter_mode) {
|
||||
TNode<Smi> index_node, TNode<Object> value, ElementsKind elements_kind) {
|
||||
TNode<RawPtrT> data_pointer = LoadJSTypedArrayBackingStore(typed_array);
|
||||
switch (elements_kind) {
|
||||
case UINT8_ELEMENTS:
|
||||
@ -2341,26 +2344,26 @@ void CodeStubAssembler::StoreJSTypedArrayElementFromTagged(
|
||||
case UINT16_ELEMENTS:
|
||||
case INT16_ELEMENTS:
|
||||
StoreElement(data_pointer, elements_kind, index_node,
|
||||
SmiToInt32(CAST(value)), parameter_mode);
|
||||
SmiToInt32(CAST(value)), SMI_PARAMETERS);
|
||||
break;
|
||||
case UINT32_ELEMENTS:
|
||||
case INT32_ELEMENTS:
|
||||
StoreElement(data_pointer, elements_kind, index_node,
|
||||
TruncateTaggedToWord32(context, value), parameter_mode);
|
||||
TruncateTaggedToWord32(context, value), SMI_PARAMETERS);
|
||||
break;
|
||||
case FLOAT32_ELEMENTS:
|
||||
StoreElement(data_pointer, elements_kind, index_node,
|
||||
TruncateFloat64ToFloat32(LoadHeapNumberValue(CAST(value))),
|
||||
parameter_mode);
|
||||
SMI_PARAMETERS);
|
||||
break;
|
||||
case FLOAT64_ELEMENTS:
|
||||
StoreElement(data_pointer, elements_kind, index_node,
|
||||
LoadHeapNumberValue(CAST(value)), parameter_mode);
|
||||
LoadHeapNumberValue(CAST(value)), SMI_PARAMETERS);
|
||||
break;
|
||||
case BIGUINT64_ELEMENTS:
|
||||
case BIGINT64_ELEMENTS:
|
||||
StoreElement(data_pointer, elements_kind, index_node,
|
||||
UncheckedCast<BigInt>(value), parameter_mode);
|
||||
UncheckedCast<BigInt>(value), SMI_PARAMETERS);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -3777,8 +3780,9 @@ void CodeStubAssembler::InitializeStructBody(Node* object, Node* map,
|
||||
StoreFieldsNoWriteBarrier(start_address, end_address, filler);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::AllocateJSObjectFromMap(
|
||||
Node* map, Node* properties, Node* elements, AllocationFlags flags,
|
||||
TNode<JSObject> CodeStubAssembler::AllocateJSObjectFromMap(
|
||||
SloppyTNode<Map> map, SloppyTNode<HeapObject> properties,
|
||||
SloppyTNode<FixedArray> elements, AllocationFlags flags,
|
||||
SlackTrackingMode slack_tracking_mode) {
|
||||
CSA_ASSERT(this, IsMap(map));
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsJSFunctionMap(map)));
|
||||
@ -3790,7 +3794,7 @@ Node* CodeStubAssembler::AllocateJSObjectFromMap(
|
||||
StoreMapNoWriteBarrier(object, map);
|
||||
InitializeJSObjectFromMap(object, map, instance_size, properties, elements,
|
||||
slack_tracking_mode);
|
||||
return object;
|
||||
return CAST(object);
|
||||
}
|
||||
|
||||
void CodeStubAssembler::InitializeJSObjectFromMap(
|
||||
@ -5535,7 +5539,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
}
|
||||
|
||||
BIND(&is_heap_number);
|
||||
var_word32->Bind(TruncateHeapNumberValueToWord32(value));
|
||||
var_word32->Bind(TruncateHeapNumberValueToWord32(CAST(value)));
|
||||
CombineFeedback(var_feedback, BinaryOperationFeedback::kNumber);
|
||||
Goto(if_number);
|
||||
|
||||
@ -5548,9 +5552,10 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
}
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::TruncateHeapNumberValueToWord32(Node* object) {
|
||||
TNode<Int32T> CodeStubAssembler::TruncateHeapNumberValueToWord32(
|
||||
TNode<HeapNumber> object) {
|
||||
Node* value = LoadHeapNumberValue(object);
|
||||
return TruncateFloat64ToWord32(value);
|
||||
return Signed(TruncateFloat64ToWord32(value));
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TryHeapNumberToSmi(TNode<HeapNumber> number,
|
||||
@ -5819,29 +5824,29 @@ TNode<WordT> CodeStubAssembler::TimesDoubleSize(SloppyTNode<WordT> value) {
|
||||
return WordShl(value, kDoubleSizeLog2);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
|
||||
PrimitiveType primitive_type,
|
||||
char const* method_name) {
|
||||
TNode<Object> CodeStubAssembler::ToThisValue(TNode<Context> context,
|
||||
TNode<Object> value,
|
||||
PrimitiveType primitive_type,
|
||||
char const* method_name) {
|
||||
// We might need to loop once due to JSValue unboxing.
|
||||
VARIABLE(var_value, MachineRepresentation::kTagged, value);
|
||||
TVARIABLE(Object, var_value, value);
|
||||
Label loop(this, &var_value), done_loop(this),
|
||||
done_throw(this, Label::kDeferred);
|
||||
Goto(&loop);
|
||||
BIND(&loop);
|
||||
{
|
||||
// Load the current {value}.
|
||||
value = var_value.value();
|
||||
|
||||
// Check if the {value} is a Smi or a HeapObject.
|
||||
GotoIf(TaggedIsSmi(value), (primitive_type == PrimitiveType::kNumber)
|
||||
? &done_loop
|
||||
: &done_throw);
|
||||
GotoIf(
|
||||
TaggedIsSmi(var_value.value()),
|
||||
(primitive_type == PrimitiveType::kNumber) ? &done_loop : &done_throw);
|
||||
|
||||
TNode<HeapObject> value = CAST(var_value.value());
|
||||
|
||||
// Load the map of the {value}.
|
||||
Node* value_map = LoadMap(value);
|
||||
TNode<Map> value_map = LoadMap(value);
|
||||
|
||||
// Load the instance type of the {value}.
|
||||
Node* value_instance_type = LoadMapInstanceType(value_map);
|
||||
TNode<Uint16T> value_instance_type = LoadMapInstanceType(value_map);
|
||||
|
||||
// Check if {value} is a JSValue.
|
||||
Label if_valueisvalue(this, Label::kDeferred), if_valueisnotvalue(this);
|
||||
@ -5851,7 +5856,7 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
|
||||
BIND(&if_valueisvalue);
|
||||
{
|
||||
// Load the actual value from the {value}.
|
||||
var_value.Bind(LoadObjectField(value, JSValue::kValueOffset));
|
||||
var_value = LoadObjectField(value, JSValue::kValueOffset);
|
||||
Goto(&loop);
|
||||
}
|
||||
|
||||
@ -6796,7 +6801,7 @@ TNode<BoolT> CodeStubAssembler::IsHeapNumberUint32(TNode<HeapNumber> number) {
|
||||
IsHeapNumberPositive(number),
|
||||
[=] {
|
||||
TNode<Float64T> value = LoadHeapNumberValue(number);
|
||||
TNode<Uint32T> int_value = Unsigned(TruncateFloat64ToWord32(value));
|
||||
TNode<Uint32T> int_value = TruncateFloat64ToWord32(value);
|
||||
return Float64Equal(value, ChangeUint32ToFloat64(int_value));
|
||||
},
|
||||
[=] { return Int32FalseConstant(); });
|
||||
@ -9779,7 +9784,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
|
||||
}
|
||||
BIND(&if_typedarray);
|
||||
{
|
||||
Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
|
||||
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(CAST(object));
|
||||
GotoIf(IsDetachedBuffer(buffer), if_absent);
|
||||
|
||||
TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
|
||||
@ -10653,7 +10658,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
|
||||
// TODO(ishell): introduce DisallowHeapAllocationCode scope here.
|
||||
|
||||
// Check if buffer has been detached.
|
||||
Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
|
||||
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(CAST(object));
|
||||
GotoIf(IsDetachedBuffer(buffer), bailout);
|
||||
|
||||
// Bounds check.
|
||||
@ -10960,7 +10965,8 @@ TNode<AllocationSite> CodeStubAssembler::CreateAllocationSiteInFeedbackVector(
|
||||
// Link the object to the allocation site list
|
||||
TNode<ExternalReference> site_list = ExternalConstant(
|
||||
ExternalReference::allocation_sites_list_address(isolate()));
|
||||
TNode<Object> next_site = CAST(LoadBufferObject(site_list, 0));
|
||||
TNode<Object> next_site =
|
||||
LoadBufferObject(ReinterpretCast<RawPtrT>(site_list), 0);
|
||||
|
||||
// TODO(mvstanton): This is a store to a weak pointer, which we may want to
|
||||
// mark as such in order to skip the write barrier, once we have a unified
|
||||
@ -12190,8 +12196,9 @@ Node* CodeStubAssembler::Equal(Node* left, Node* right, Node* context,
|
||||
return result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
Variable* var_type_feedback) {
|
||||
TNode<Oddball> CodeStubAssembler::StrictEqual(SloppyTNode<Object> lhs,
|
||||
SloppyTNode<Object> rhs,
|
||||
Variable* var_type_feedback) {
|
||||
// Pseudo-code for the algorithm below:
|
||||
//
|
||||
// if (lhs == rhs) {
|
||||
@ -12243,7 +12250,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
|
||||
Label if_equal(this), if_notequal(this), if_not_equivalent_types(this),
|
||||
end(this);
|
||||
VARIABLE(result, MachineRepresentation::kTagged);
|
||||
TVARIABLE(Oddball, result);
|
||||
|
||||
OverwriteFeedback(var_type_feedback, CompareOperationFeedback::kNone);
|
||||
|
||||
@ -12270,7 +12277,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_lhsisnotsmi);
|
||||
{
|
||||
// Load the map of {lhs}.
|
||||
Node* lhs_map = LoadMap(lhs);
|
||||
TNode<Map> lhs_map = LoadMap(CAST(lhs));
|
||||
|
||||
// Check if {lhs} is a HeapNumber.
|
||||
Label if_lhsisnumber(this), if_lhsisnotnumber(this);
|
||||
@ -12285,8 +12292,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_rhsissmi);
|
||||
{
|
||||
// Convert {lhs} and {rhs} to floating point values.
|
||||
Node* lhs_value = LoadHeapNumberValue(lhs);
|
||||
Node* rhs_value = SmiToFloat64(rhs);
|
||||
Node* lhs_value = LoadHeapNumberValue(CAST(lhs));
|
||||
Node* rhs_value = SmiToFloat64(CAST(rhs));
|
||||
|
||||
CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
|
||||
|
||||
@ -12296,8 +12303,9 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
|
||||
BIND(&if_rhsisnotsmi);
|
||||
{
|
||||
TNode<HeapObject> rhs_ho = CAST(rhs);
|
||||
// Load the map of {rhs}.
|
||||
Node* rhs_map = LoadMap(rhs);
|
||||
TNode<Map> rhs_map = LoadMap(rhs_ho);
|
||||
|
||||
// Check if {rhs} is also a HeapNumber.
|
||||
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
|
||||
@ -12306,8 +12314,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_rhsisnumber);
|
||||
{
|
||||
// Convert {lhs} and {rhs} to floating point values.
|
||||
Node* lhs_value = LoadHeapNumberValue(lhs);
|
||||
Node* rhs_value = LoadHeapNumberValue(rhs);
|
||||
Node* lhs_value = LoadHeapNumberValue(CAST(lhs));
|
||||
Node* rhs_value = LoadHeapNumberValue(CAST(rhs));
|
||||
|
||||
CombineFeedback(var_type_feedback,
|
||||
CompareOperationFeedback::kNumber);
|
||||
@ -12343,7 +12351,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_lhsisstring);
|
||||
{
|
||||
// Load the instance type of {rhs}.
|
||||
Node* rhs_instance_type = LoadInstanceType(rhs);
|
||||
Node* rhs_instance_type = LoadInstanceType(CAST(rhs));
|
||||
|
||||
// Check if {rhs} is also a String.
|
||||
Label if_rhsisstring(this, Label::kDeferred),
|
||||
@ -12360,8 +12368,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
CollectFeedbackForString(rhs_instance_type);
|
||||
var_type_feedback->Bind(SmiOr(lhs_feedback, rhs_feedback));
|
||||
}
|
||||
result.Bind(CallBuiltin(Builtins::kStringEqual,
|
||||
NoContextConstant(), lhs, rhs));
|
||||
result = CAST(CallBuiltin(Builtins::kStringEqual,
|
||||
NoContextConstant(), lhs, rhs));
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
@ -12379,7 +12387,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_lhsisbigint);
|
||||
{
|
||||
// Load the instance type of {rhs}.
|
||||
Node* rhs_instance_type = LoadInstanceType(rhs);
|
||||
TNode<Uint16T> rhs_instance_type = LoadInstanceType(CAST(rhs));
|
||||
|
||||
// Check if {rhs} is also a BigInt.
|
||||
Label if_rhsisbigint(this, Label::kDeferred),
|
||||
@ -12391,8 +12399,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
{
|
||||
CombineFeedback(var_type_feedback,
|
||||
CompareOperationFeedback::kBigInt);
|
||||
result.Bind(CallRuntime(Runtime::kBigIntEqualToBigInt,
|
||||
NoContextConstant(), lhs, rhs));
|
||||
result = CAST(CallRuntime(Runtime::kBigIntEqualToBigInt,
|
||||
NoContextConstant(), lhs, rhs));
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
@ -12403,8 +12411,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_lhsisnotbigint);
|
||||
if (var_type_feedback != nullptr) {
|
||||
// Load the instance type of {rhs}.
|
||||
Node* rhs_map = LoadMap(rhs);
|
||||
Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
|
||||
TNode<Map> rhs_map = LoadMap(CAST(rhs));
|
||||
TNode<Uint16T> rhs_instance_type = LoadMapInstanceType(rhs_map);
|
||||
|
||||
Label if_lhsissymbol(this), if_lhsisreceiver(this),
|
||||
if_lhsisoddball(this);
|
||||
@ -12477,7 +12485,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_rhsisnotsmi);
|
||||
{
|
||||
// Load the map of the {rhs}.
|
||||
Node* rhs_map = LoadMap(rhs);
|
||||
TNode<Map> rhs_map = LoadMap(CAST(rhs));
|
||||
|
||||
// The {rhs} could be a HeapNumber with the same value as {lhs}.
|
||||
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
|
||||
@ -12486,8 +12494,8 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
BIND(&if_rhsisnumber);
|
||||
{
|
||||
// Convert {lhs} and {rhs} to floating point values.
|
||||
Node* lhs_value = SmiToFloat64(lhs);
|
||||
Node* rhs_value = LoadHeapNumberValue(rhs);
|
||||
TNode<Float64T> lhs_value = SmiToFloat64(CAST(lhs));
|
||||
TNode<Float64T> rhs_value = LoadHeapNumberValue(CAST(rhs));
|
||||
|
||||
CombineFeedback(var_type_feedback, CompareOperationFeedback::kNumber);
|
||||
|
||||
@ -12503,7 +12511,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
|
||||
BIND(&if_equal);
|
||||
{
|
||||
result.Bind(TrueConstant());
|
||||
result = TrueConstant();
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
@ -12515,7 +12523,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
|
||||
|
||||
BIND(&if_notequal);
|
||||
{
|
||||
result.Bind(FalseConstant());
|
||||
result = FalseConstant();
|
||||
Goto(&end);
|
||||
}
|
||||
|
||||
@ -13149,8 +13157,9 @@ TNode<JSArrayIterator> CodeStubAssembler::CreateArrayIterator(
|
||||
return CAST(iterator);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::AllocateJSIteratorResult(Node* context, Node* value,
|
||||
Node* done) {
|
||||
TNode<JSObject> CodeStubAssembler::AllocateJSIteratorResult(
|
||||
SloppyTNode<Context> context, SloppyTNode<Object> value,
|
||||
SloppyTNode<Oddball> done) {
|
||||
CSA_ASSERT(this, IsBoolean(done));
|
||||
Node* native_context = LoadNativeContext(context);
|
||||
Node* map =
|
||||
@ -13163,7 +13172,7 @@ Node* CodeStubAssembler::AllocateJSIteratorResult(Node* context, Node* value,
|
||||
RootIndex::kEmptyFixedArray);
|
||||
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, value);
|
||||
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset, done);
|
||||
return result;
|
||||
return CAST(result);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::AllocateJSIteratorResultForEntry(Node* context,
|
||||
@ -13209,9 +13218,8 @@ TNode<JSReceiver> CodeStubAssembler::ArraySpeciesCreate(TNode<Context> context,
|
||||
return Construct(context, constructor, len);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) {
|
||||
CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE));
|
||||
TNode<Uint32T> buffer_bit_field = LoadJSArrayBufferBitField(CAST(buffer));
|
||||
TNode<BoolT> CodeStubAssembler::IsDetachedBuffer(TNode<JSArrayBuffer> buffer) {
|
||||
TNode<Uint32T> buffer_bit_field = LoadJSArrayBufferBitField(buffer);
|
||||
return IsSetWord32<JSArrayBuffer::WasDetachedBit>(buffer_bit_field);
|
||||
}
|
||||
|
||||
@ -13402,7 +13410,8 @@ void CodeStubArguments::PopAndReturn(Node* value) {
|
||||
value);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsFastElementsKind(Node* elements_kind) {
|
||||
TNode<BoolT> CodeStubAssembler::IsFastElementsKind(
|
||||
TNode<Int32T> elements_kind) {
|
||||
STATIC_ASSERT(FIRST_ELEMENTS_KIND == FIRST_FAST_ELEMENTS_KIND);
|
||||
return Uint32LessThanOrEqual(elements_kind,
|
||||
Int32Constant(LAST_FAST_ELEMENTS_KIND));
|
||||
@ -13417,7 +13426,8 @@ TNode<BoolT> CodeStubAssembler::IsDoubleElementsKind(
|
||||
Int32Constant(PACKED_DOUBLE_ELEMENTS / 2));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsFastSmiOrTaggedElementsKind(Node* elements_kind) {
|
||||
TNode<BoolT> CodeStubAssembler::IsFastSmiOrTaggedElementsKind(
|
||||
TNode<Int32T> elements_kind) {
|
||||
STATIC_ASSERT(FIRST_ELEMENTS_KIND == FIRST_FAST_ELEMENTS_KIND);
|
||||
STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS > TERMINAL_FAST_ELEMENTS_KIND);
|
||||
STATIC_ASSERT(HOLEY_DOUBLE_ELEMENTS > TERMINAL_FAST_ELEMENTS_KIND);
|
||||
@ -13425,12 +13435,14 @@ Node* CodeStubAssembler::IsFastSmiOrTaggedElementsKind(Node* elements_kind) {
|
||||
Int32Constant(TERMINAL_FAST_ELEMENTS_KIND));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsFastSmiElementsKind(Node* elements_kind) {
|
||||
TNode<BoolT> CodeStubAssembler::IsFastSmiElementsKind(
|
||||
SloppyTNode<Int32T> elements_kind) {
|
||||
return Uint32LessThanOrEqual(elements_kind,
|
||||
Int32Constant(HOLEY_SMI_ELEMENTS));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsHoleyFastElementsKind(Node* elements_kind) {
|
||||
TNode<BoolT> CodeStubAssembler::IsHoleyFastElementsKind(
|
||||
TNode<Int32T> elements_kind) {
|
||||
CSA_ASSERT(this, IsFastElementsKind(elements_kind));
|
||||
|
||||
STATIC_ASSERT(HOLEY_SMI_ELEMENTS == (PACKED_SMI_ELEMENTS | 1));
|
||||
@ -13439,7 +13451,8 @@ Node* CodeStubAssembler::IsHoleyFastElementsKind(Node* elements_kind) {
|
||||
return IsSetWord32(elements_kind, 1);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsHoleyFastElementsKindForRead(Node* elements_kind) {
|
||||
TNode<BoolT> CodeStubAssembler::IsHoleyFastElementsKindForRead(
|
||||
TNode<Int32T> elements_kind) {
|
||||
CSA_ASSERT(this,
|
||||
Uint32LessThanOrEqual(elements_kind,
|
||||
Int32Constant(LAST_FROZEN_ELEMENTS_KIND)));
|
||||
@ -13452,8 +13465,8 @@ Node* CodeStubAssembler::IsHoleyFastElementsKindForRead(Node* elements_kind) {
|
||||
return IsSetWord32(elements_kind, 1);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsElementsKindGreaterThan(
|
||||
Node* target_kind, ElementsKind reference_kind) {
|
||||
TNode<BoolT> CodeStubAssembler::IsElementsKindGreaterThan(
|
||||
TNode<Int32T> target_kind, ElementsKind reference_kind) {
|
||||
return Int32GreaterThan(target_kind, Int32Constant(reference_kind));
|
||||
}
|
||||
|
||||
@ -13951,7 +13964,7 @@ void CodeStubAssembler::GotoIfInitialPrototypePropertiesModified(
|
||||
if (i == 0) {
|
||||
combined_details = details;
|
||||
} else {
|
||||
combined_details = Unsigned(Word32And(combined_details, details));
|
||||
combined_details = Word32And(combined_details, details);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,8 +813,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
MachineType type = MachineType::AnyTagged());
|
||||
|
||||
// Load an object pointer from a buffer that isn't in the heap.
|
||||
Node* LoadBufferObject(Node* buffer, int offset,
|
||||
MachineType type = MachineType::AnyTagged());
|
||||
Node* LoadBufferObject(Node* buffer, int offset, MachineType type);
|
||||
TNode<Object> LoadBufferObject(TNode<RawPtrT> buffer, int offset) {
|
||||
return CAST(LoadBufferObject(buffer, offset, MachineType::AnyTagged()));
|
||||
}
|
||||
TNode<RawPtrT> LoadBufferPointer(TNode<RawPtrT> buffer, int offset) {
|
||||
return UncheckedCast<RawPtrT>(
|
||||
LoadBufferObject(buffer, offset, MachineType::Pointer()));
|
||||
@ -936,7 +938,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Load the Map of an HeapObject.
|
||||
TNode<Map> LoadMap(SloppyTNode<HeapObject> object);
|
||||
// Load the instance type of an HeapObject.
|
||||
TNode<Int32T> LoadInstanceType(SloppyTNode<HeapObject> object);
|
||||
TNode<Uint16T> LoadInstanceType(SloppyTNode<HeapObject> object);
|
||||
// Compare the instance the type of the object against the provided one.
|
||||
TNode<BoolT> HasInstanceType(SloppyTNode<HeapObject> object,
|
||||
InstanceType type);
|
||||
@ -976,7 +978,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Load bit field 3 of a map.
|
||||
TNode<Uint32T> LoadMapBitField3(SloppyTNode<Map> map);
|
||||
// Load the instance type of a map.
|
||||
TNode<Int32T> LoadMapInstanceType(SloppyTNode<Map> map);
|
||||
TNode<Uint16T> LoadMapInstanceType(SloppyTNode<Map> map);
|
||||
// Load the ElementsKind of a map.
|
||||
TNode<Int32T> LoadMapElementsKind(SloppyTNode<Map> map);
|
||||
TNode<Int32T> LoadElementsKind(SloppyTNode<HeapObject> object);
|
||||
@ -1241,15 +1243,23 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Float64T> LoadDoubleWithHoleCheck(
|
||||
SloppyTNode<Object> base, SloppyTNode<IntPtrT> offset, Label* if_hole,
|
||||
MachineType machine_type = MachineType::Float64());
|
||||
Node* LoadFixedTypedArrayElementAsTagged(
|
||||
Node* data_pointer, Node* index_node, ElementsKind elements_kind,
|
||||
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
|
||||
TNode<RawPtrT> data_pointer, Node* index_node, ElementsKind elements_kind,
|
||||
ParameterMode parameter_mode = INTPTR_PARAMETERS);
|
||||
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
|
||||
TNode<WordT> data_pointer, TNode<Smi> index, TNode<Int32T> elements_kind);
|
||||
TNode<RawPtrT> data_pointer, TNode<Smi> index_node,
|
||||
ElementsKind elements_kind) {
|
||||
return LoadFixedTypedArrayElementAsTagged(data_pointer, index_node,
|
||||
elements_kind, SMI_PARAMETERS);
|
||||
}
|
||||
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
|
||||
TNode<RawPtrT> data_pointer, TNode<Smi> index,
|
||||
TNode<Int32T> elements_kind);
|
||||
// Parts of the above, factored out for readability:
|
||||
Node* LoadFixedBigInt64ArrayElementAsTagged(Node* data_pointer, Node* offset);
|
||||
Node* LoadFixedBigUint64ArrayElementAsTagged(Node* data_pointer,
|
||||
Node* offset);
|
||||
TNode<BigInt> LoadFixedBigInt64ArrayElementAsTagged(
|
||||
SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset);
|
||||
TNode<BigInt> LoadFixedBigUint64ArrayElementAsTagged(
|
||||
SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset);
|
||||
// 64-bit platforms only:
|
||||
TNode<BigInt> BigIntFromInt64(TNode<IntPtrT> value);
|
||||
TNode<BigInt> BigIntFromUint64(TNode<UintPtrT> value);
|
||||
@ -1259,10 +1269,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
void StoreJSTypedArrayElementFromTagged(TNode<Context> context,
|
||||
TNode<JSTypedArray> typed_array,
|
||||
TNode<Object> index_node,
|
||||
TNode<Smi> index_node,
|
||||
TNode<Object> value,
|
||||
ElementsKind elements_kind,
|
||||
ParameterMode parameter_mode);
|
||||
ElementsKind elements_kind);
|
||||
|
||||
// Context manipulation
|
||||
TNode<Object> LoadContextElement(SloppyTNode<Context> context,
|
||||
@ -1618,9 +1627,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
void InitializeStructBody(Node* object, Node* map, Node* size,
|
||||
int start_offset = Struct::kHeaderSize);
|
||||
|
||||
Node* AllocateJSObjectFromMap(
|
||||
Node* map, Node* properties = nullptr, Node* elements = nullptr,
|
||||
AllocationFlags flags = kNone,
|
||||
TNode<JSObject> AllocateJSObjectFromMap(
|
||||
SloppyTNode<Map> map, SloppyTNode<HeapObject> properties = nullptr,
|
||||
SloppyTNode<FixedArray> elements = nullptr, AllocationFlags flags = kNone,
|
||||
SlackTrackingMode slack_tracking_mode = kNoSlackTracking);
|
||||
|
||||
void InitializeJSObjectFromMap(
|
||||
@ -1757,7 +1766,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Object> object,
|
||||
IterationKind mode);
|
||||
|
||||
Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done);
|
||||
TNode<JSObject> AllocateJSIteratorResult(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> value,
|
||||
SloppyTNode<Oddball> done);
|
||||
Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value);
|
||||
|
||||
TNode<JSReceiver> ArraySpeciesCreate(TNode<Context> context,
|
||||
@ -1946,6 +1957,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
SMI_PARAMETERS);
|
||||
}
|
||||
|
||||
TNode<FixedArray> ExtractFixedArray(
|
||||
TNode<FixedArray> source, TNode<IntPtrT> first, TNode<IntPtrT> count,
|
||||
TNode<IntPtrT> capacity,
|
||||
ExtractFixedArrayFlags extract_flags =
|
||||
ExtractFixedArrayFlag::kAllFixedArrays) {
|
||||
return CAST(ExtractFixedArray(source, first, count, capacity, extract_flags,
|
||||
INTPTR_PARAMETERS));
|
||||
}
|
||||
|
||||
// Copy a portion of an existing FixedArray or FixedDoubleArray into a new
|
||||
// FixedArray, including special appropriate handling for COW arrays.
|
||||
// * |source| is either a FixedArray or FixedDoubleArray from which to copy
|
||||
@ -2055,6 +2075,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Smi> CalculateNewElementsCapacity(TNode<Smi> old_capacity) {
|
||||
return CAST(CalculateNewElementsCapacity(old_capacity, SMI_PARAMETERS));
|
||||
}
|
||||
TNode<IntPtrT> CalculateNewElementsCapacity(TNode<IntPtrT> old_capacity) {
|
||||
return UncheckedCast<IntPtrT>(
|
||||
CalculateNewElementsCapacity(old_capacity, INTPTR_PARAMETERS));
|
||||
}
|
||||
|
||||
// Tries to grow the |elements| array of given |object| to store the |key|
|
||||
// or bails out if the growing gap is too big. Returns new elements.
|
||||
@ -2098,7 +2122,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
Label* if_bigint, Variable* var_bigint, Variable* var_feedback);
|
||||
|
||||
// Truncate the floating point value of a HeapNumber to an Int32.
|
||||
Node* TruncateHeapNumberValueToWord32(Node* object);
|
||||
TNode<Int32T> TruncateHeapNumberValueToWord32(TNode<HeapNumber> object);
|
||||
|
||||
// Conversions.
|
||||
void TryHeapNumberToSmi(TNode<HeapNumber> number, TVariable<Smi>& output,
|
||||
@ -2159,8 +2183,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Throws a TypeError for {method_name} if {value} is neither of the given
|
||||
// {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or
|
||||
// returns the {value} (or wrapped value) otherwise.
|
||||
Node* ToThisValue(Node* context, Node* value, PrimitiveType primitive_type,
|
||||
char const* method_name);
|
||||
TNode<Object> ToThisValue(TNode<Context> context, TNode<Object> value,
|
||||
PrimitiveType primitive_type,
|
||||
char const* method_name);
|
||||
|
||||
// Throws a TypeError for {method_name} if {value} is not of the given
|
||||
// instance type. Returns {value}'s map.
|
||||
@ -2368,7 +2393,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
return Word32Equal(a, b);
|
||||
}
|
||||
bool ElementsKindEqual(ElementsKind a, ElementsKind b) { return a == b; }
|
||||
Node* IsFastElementsKind(Node* elements_kind);
|
||||
TNode<BoolT> IsFastElementsKind(TNode<Int32T> elements_kind);
|
||||
bool IsFastElementsKind(ElementsKind kind) {
|
||||
return v8::internal::IsFastElementsKind(kind);
|
||||
}
|
||||
@ -2379,12 +2404,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
bool IsDoubleElementsKind(ElementsKind kind) {
|
||||
return v8::internal::IsDoubleElementsKind(kind);
|
||||
}
|
||||
Node* IsFastSmiOrTaggedElementsKind(Node* elements_kind);
|
||||
Node* IsFastSmiElementsKind(Node* elements_kind);
|
||||
Node* IsHoleyFastElementsKind(Node* elements_kind);
|
||||
Node* IsHoleyFastElementsKindForRead(Node* elements_kind);
|
||||
Node* IsElementsKindGreaterThan(Node* target_kind,
|
||||
ElementsKind reference_kind);
|
||||
TNode<BoolT> IsFastSmiOrTaggedElementsKind(TNode<Int32T> elements_kind);
|
||||
TNode<BoolT> IsFastSmiElementsKind(SloppyTNode<Int32T> elements_kind);
|
||||
TNode<BoolT> IsHoleyFastElementsKind(TNode<Int32T> elements_kind);
|
||||
TNode<BoolT> IsHoleyFastElementsKindForRead(TNode<Int32T> elements_kind);
|
||||
TNode<BoolT> IsElementsKindGreaterThan(TNode<Int32T> target_kind,
|
||||
ElementsKind reference_kind);
|
||||
TNode<BoolT> IsElementsKindLessThanOrEqual(TNode<Int32T> target_kind,
|
||||
ElementsKind reference_kind);
|
||||
// Check if reference_kind_a <= target_kind <= reference_kind_b
|
||||
@ -3217,8 +3242,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
Node* Equal(Node* lhs, Node* rhs, Node* context,
|
||||
Variable* var_type_feedback = nullptr);
|
||||
|
||||
Node* StrictEqual(Node* lhs, Node* rhs,
|
||||
Variable* var_type_feedback = nullptr);
|
||||
TNode<Oddball> StrictEqual(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs,
|
||||
Variable* var_type_feedback = nullptr);
|
||||
|
||||
// ECMA#sec-samevalue
|
||||
// Similar to StrictEqual except that NaNs are treated as equal and minus zero
|
||||
@ -3265,7 +3290,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<Uint32T> LoadJSArrayBufferBitField(TNode<JSArrayBuffer> array_buffer);
|
||||
TNode<RawPtrT> LoadJSArrayBufferBackingStore(
|
||||
TNode<JSArrayBuffer> array_buffer);
|
||||
Node* IsDetachedBuffer(Node* buffer);
|
||||
TNode<BoolT> IsDetachedBuffer(TNode<JSArrayBuffer> buffer);
|
||||
void ThrowIfArrayBufferIsDetached(SloppyTNode<Context> context,
|
||||
TNode<JSArrayBuffer> array_buffer,
|
||||
const char* method_name);
|
||||
|
@ -441,16 +441,16 @@ void CodeAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) {
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
Node* CodeAssembler::LoadFramePointer() {
|
||||
return raw_assembler()->LoadFramePointer();
|
||||
TNode<RawPtrT> CodeAssembler::LoadFramePointer() {
|
||||
return UncheckedCast<RawPtrT>(raw_assembler()->LoadFramePointer());
|
||||
}
|
||||
|
||||
Node* CodeAssembler::LoadParentFramePointer() {
|
||||
return raw_assembler()->LoadParentFramePointer();
|
||||
TNode<RawPtrT> CodeAssembler::LoadParentFramePointer() {
|
||||
return UncheckedCast<RawPtrT>(raw_assembler()->LoadParentFramePointer());
|
||||
}
|
||||
|
||||
Node* CodeAssembler::LoadStackPointer() {
|
||||
return raw_assembler()->LoadStackPointer();
|
||||
TNode<RawPtrT> CodeAssembler::LoadStackPointer() {
|
||||
return UncheckedCast<RawPtrT>(raw_assembler()->LoadStackPointer());
|
||||
}
|
||||
|
||||
TNode<Object> CodeAssembler::TaggedPoisonOnSpeculation(
|
||||
|
@ -107,13 +107,13 @@ struct Uint32T : Word32T {
|
||||
struct Int16T : Int32T {
|
||||
static constexpr MachineType kMachineType = MachineType::Int16();
|
||||
};
|
||||
struct Uint16T : Uint32T {
|
||||
struct Uint16T : Uint32T, Int32T {
|
||||
static constexpr MachineType kMachineType = MachineType::Uint16();
|
||||
};
|
||||
struct Int8T : Int16T {
|
||||
static constexpr MachineType kMachineType = MachineType::Int8();
|
||||
};
|
||||
struct Uint8T : Uint16T {
|
||||
struct Uint8T : Uint16T, Int16T {
|
||||
static constexpr MachineType kMachineType = MachineType::Uint8();
|
||||
};
|
||||
|
||||
@ -419,6 +419,10 @@ struct types_have_common_values {
|
||||
static const bool value = is_subtype<T, U>::value || is_subtype<U, T>::value;
|
||||
};
|
||||
template <class U>
|
||||
struct types_have_common_values<BoolT, U> {
|
||||
static const bool value = types_have_common_values<Word32T, U>::value;
|
||||
};
|
||||
template <class U>
|
||||
struct types_have_common_values<Uint32T, U> {
|
||||
static const bool value = types_have_common_values<Word32T, U>::value;
|
||||
};
|
||||
@ -617,15 +621,15 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
|
||||
V(Float64Sqrt, Float64T, Float64T) \
|
||||
V(Float64Tan, Float64T, Float64T) \
|
||||
V(Float64Tanh, Float64T, Float64T) \
|
||||
V(Float64ExtractLowWord32, Word32T, Float64T) \
|
||||
V(Float64ExtractHighWord32, Word32T, Float64T) \
|
||||
V(Float64ExtractLowWord32, Uint32T, Float64T) \
|
||||
V(Float64ExtractHighWord32, Uint32T, Float64T) \
|
||||
V(BitcastTaggedToWord, IntPtrT, Object) \
|
||||
V(BitcastTaggedSignedToWord, IntPtrT, Smi) \
|
||||
V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \
|
||||
V(BitcastWordToTagged, Object, WordT) \
|
||||
V(BitcastWordToTaggedSigned, Smi, WordT) \
|
||||
V(TruncateFloat64ToFloat32, Float32T, Float64T) \
|
||||
V(TruncateFloat64ToWord32, Word32T, Float64T) \
|
||||
V(TruncateFloat64ToWord32, Uint32T, Float64T) \
|
||||
V(TruncateInt64ToInt32, Int32T, Int64T) \
|
||||
V(ChangeFloat32ToFloat64, Float64T, Float32T) \
|
||||
V(ChangeFloat64ToUint32, Uint32T, Float64T) \
|
||||
@ -635,7 +639,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
|
||||
V(ChangeUint32ToFloat64, Float64T, Word32T) \
|
||||
V(ChangeUint32ToUint64, Uint64T, Word32T) \
|
||||
V(BitcastInt32ToFloat32, Float32T, Word32T) \
|
||||
V(BitcastFloat32ToInt32, Word32T, Float32T) \
|
||||
V(BitcastFloat32ToInt32, Uint32T, Float32T) \
|
||||
V(RoundFloat64ToInt32, Int32T, Float64T) \
|
||||
V(RoundInt32ToFloat32, Int32T, Float32T) \
|
||||
V(Float64SilenceNaN, Float64T, Float64T) \
|
||||
@ -948,11 +952,11 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
Label** case_labels, size_t case_count);
|
||||
|
||||
// Access to the frame pointer
|
||||
Node* LoadFramePointer();
|
||||
Node* LoadParentFramePointer();
|
||||
TNode<RawPtrT> LoadFramePointer();
|
||||
TNode<RawPtrT> LoadParentFramePointer();
|
||||
|
||||
// Access to the stack pointer
|
||||
Node* LoadStackPointer();
|
||||
TNode<RawPtrT> LoadStackPointer();
|
||||
|
||||
// Poison |value| on speculative paths.
|
||||
TNode<Object> TaggedPoisonOnSpeculation(SloppyTNode<Object> value);
|
||||
@ -1057,20 +1061,60 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
|
||||
#undef DECLARE_CODE_ASSEMBLER_BINARY_OP
|
||||
|
||||
TNode<IntPtrT> WordShr(TNode<IntPtrT> left, TNode<IntegralT> right) {
|
||||
return UncheckedCast<IntPtrT>(
|
||||
TNode<UintPtrT> WordShr(TNode<UintPtrT> left, TNode<IntegralT> right) {
|
||||
return Unsigned(
|
||||
WordShr(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<IntPtrT> WordSar(TNode<IntPtrT> left, TNode<IntegralT> right) {
|
||||
return UncheckedCast<IntPtrT>(
|
||||
WordSar(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
return Signed(WordSar(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<IntPtrT> WordShl(TNode<IntPtrT> left, TNode<IntegralT> right) {
|
||||
return Signed(WordShl(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<UintPtrT> WordShl(TNode<UintPtrT> left, TNode<IntegralT> right) {
|
||||
return Unsigned(
|
||||
WordShl(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Int32T> Word32Shl(TNode<Int32T> left, TNode<Int32T> right) {
|
||||
return Signed(
|
||||
Word32Shl(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<Uint32T> Word32Shl(TNode<Uint32T> left, TNode<Uint32T> right) {
|
||||
return Unsigned(
|
||||
Word32Shl(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<Uint32T> Word32Shr(TNode<Uint32T> left, TNode<Uint32T> right) {
|
||||
return Unsigned(
|
||||
Word32Shr(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<IntPtrT> WordAnd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
|
||||
return UncheckedCast<IntPtrT>(
|
||||
return Signed(WordAnd(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<UintPtrT> WordAnd(TNode<UintPtrT> left, TNode<UintPtrT> right) {
|
||||
return Unsigned(
|
||||
WordAnd(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Int32T> Word32And(TNode<Int32T> left, TNode<Int32T> right) {
|
||||
return Signed(
|
||||
Word32And(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<Uint32T> Word32And(TNode<Uint32T> left, TNode<Uint32T> right) {
|
||||
return Unsigned(
|
||||
Word32And(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Int32T> Word32Or(TNode<Int32T> left, TNode<Int32T> right) {
|
||||
return Signed(
|
||||
Word32Or(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<Uint32T> Word32Or(TNode<Uint32T> left, TNode<Uint32T> right) {
|
||||
return Unsigned(
|
||||
Word32Or(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
template <class Left, class Right,
|
||||
class = typename std::enable_if<
|
||||
std::is_base_of<Object, Left>::value &&
|
||||
@ -1116,6 +1160,15 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
TNode<BoolT> Word64NotEqual(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
|
||||
TNode<BoolT> Word32Or(TNode<BoolT> left, TNode<BoolT> right) {
|
||||
return UncheckedCast<BoolT>(
|
||||
Word32Or(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
TNode<BoolT> Word32And(TNode<BoolT> left, TNode<BoolT> right) {
|
||||
return UncheckedCast<BoolT>(
|
||||
Word32And(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Int32T> Int32Add(TNode<Int32T> left, TNode<Int32T> right) {
|
||||
return Signed(
|
||||
Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
@ -1126,6 +1179,16 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Int32T> Int32Sub(TNode<Int32T> left, TNode<Int32T> right) {
|
||||
return Signed(
|
||||
Int32Sub(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<Int32T> Int32Mul(TNode<Int32T> left, TNode<Int32T> right) {
|
||||
return Signed(
|
||||
Int32Mul(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<IntPtrT> IntPtrDiv(TNode<IntPtrT> left, TNode<IntPtrT> right);
|
||||
TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
|
@ -1964,7 +1964,7 @@ void AccessorAssembler::EmitElementLoad(
|
||||
{
|
||||
Comment("typed elements");
|
||||
// Check if buffer has been detached.
|
||||
Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
|
||||
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(CAST(object));
|
||||
GotoIf(IsDetachedBuffer(buffer), miss);
|
||||
|
||||
// Bounds check.
|
||||
@ -1973,7 +1973,8 @@ void AccessorAssembler::EmitElementLoad(
|
||||
if (access_mode == LoadAccessMode::kHas) {
|
||||
exit_point->Return(TrueConstant());
|
||||
} else {
|
||||
Node* backing_store = LoadJSTypedArrayBackingStore(CAST(object));
|
||||
TNode<RawPtrT> backing_store =
|
||||
LoadJSTypedArrayBackingStore(CAST(object));
|
||||
|
||||
Label uint8_elements(this), int8_elements(this), uint16_elements(this),
|
||||
int16_elements(this), uint32_elements(this), int32_elements(this),
|
||||
@ -3640,7 +3641,7 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() {
|
||||
LoadObjectField(object_fn, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
CSA_ASSERT(this, IsMap(initial_map));
|
||||
|
||||
TNode<JSObject> result = CAST(AllocateJSObjectFromMap(initial_map));
|
||||
TNode<JSObject> result = AllocateJSObjectFromMap(initial_map);
|
||||
|
||||
{
|
||||
Label did_set_proto_if_needed(this);
|
||||
@ -3708,8 +3709,8 @@ void AccessorAssembler::GenerateCloneObjectIC() {
|
||||
// Handlers for the CloneObjectIC stub are weak references to the Map of
|
||||
// a result object.
|
||||
TNode<Map> result_map = CAST(var_handler.value());
|
||||
TVARIABLE(Object, var_properties, EmptyFixedArrayConstant());
|
||||
TVARIABLE(FixedArrayBase, var_elements, EmptyFixedArrayConstant());
|
||||
TVARIABLE(HeapObject, var_properties, EmptyFixedArrayConstant());
|
||||
TVARIABLE(FixedArray, var_elements, EmptyFixedArrayConstant());
|
||||
|
||||
Label allocate_object(this);
|
||||
GotoIf(IsNullOrUndefined(source), &allocate_object);
|
||||
|
@ -185,7 +185,7 @@ void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements(
|
||||
TNode<Int32T> instance_type = LoadMapInstanceType(prototype_map);
|
||||
GotoIf(IsCustomElementsReceiverInstanceType(instance_type),
|
||||
non_fast_elements);
|
||||
Node* elements_kind = LoadMapElementsKind(prototype_map);
|
||||
TNode<Int32T> elements_kind = LoadMapElementsKind(prototype_map);
|
||||
GotoIf(IsFastElementsKind(elements_kind), &loop_body);
|
||||
GotoIf(Word32Equal(elements_kind, Int32Constant(NO_ELEMENTS)), &loop_body);
|
||||
Goto(non_fast_elements);
|
||||
@ -500,7 +500,7 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore(
|
||||
if_grow(this), if_nonfast(this), if_typed_array(this),
|
||||
if_dictionary(this);
|
||||
Node* elements = LoadElements(receiver);
|
||||
Node* elements_kind = LoadMapElementsKind(receiver_map);
|
||||
TNode<Int32T> elements_kind = LoadMapElementsKind(receiver_map);
|
||||
Branch(IsFastElementsKind(elements_kind), &if_fast, &if_nonfast);
|
||||
BIND(&if_fast);
|
||||
|
||||
|
@ -1265,7 +1265,7 @@ void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) {
|
||||
|
||||
// Make sure we include the current bytecode in the budget calculation.
|
||||
TNode<Int32T> budget_after_bytecode =
|
||||
Signed(Int32Sub(old_budget, Int32Constant(CurrentBytecodeSize())));
|
||||
Int32Sub(old_budget, Int32Constant(CurrentBytecodeSize()));
|
||||
|
||||
Label done(this);
|
||||
TVARIABLE(Int32T, new_budget);
|
||||
|
@ -314,8 +314,7 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
|
||||
out_ << ") = ";
|
||||
} else {
|
||||
if (results.size() == 1) {
|
||||
out_ << results[0] << " = ca_.UncheckedCast<"
|
||||
<< return_type->GetGeneratedTNodeTypeName() << ">(";
|
||||
out_ << results[0] << " = ";
|
||||
} else {
|
||||
DCHECK_EQ(0, results.size());
|
||||
}
|
||||
@ -330,7 +329,6 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
|
||||
if (needs_flattening) {
|
||||
out_ << ").Flatten();\n";
|
||||
} else {
|
||||
if (results.size() == 1) out_ << ")";
|
||||
out_ << ");\n";
|
||||
}
|
||||
PostCallableExceptionPreparation(catch_name, return_type,
|
||||
|
@ -744,16 +744,16 @@ namespace test {
|
||||
// IteratorBuiltinsAssembler match the signatures provided in
|
||||
// iterator.tq.
|
||||
@export
|
||||
macro TestIterator(implicit context: Context)(o: Object, map: Map) {
|
||||
macro TestIterator(implicit context: Context)(o: JSReceiver, map: Map) {
|
||||
try {
|
||||
const t1: Object = iterator::GetIteratorMethod(o);
|
||||
const t2: iterator::IteratorRecord = iterator::GetIterator(o);
|
||||
|
||||
const _t3: Object = iterator::IteratorStep(t2) otherwise Fail;
|
||||
const t4: Object = iterator::IteratorStep(t2, map) otherwise Fail;
|
||||
const _t4: Object = iterator::IteratorStep(t2, map) otherwise Fail;
|
||||
|
||||
const t5: Object = iterator::IteratorValue(t4);
|
||||
const _t6: Object = iterator::IteratorValue(t4, map);
|
||||
const t5: Object = iterator::IteratorValue(o);
|
||||
const _t6: Object = iterator::IteratorValue(o, map);
|
||||
|
||||
const _t7: JSArray = iterator::IterableToList(t1, t1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user