| Index: runtime/vm/simulator_dbc.cc
|
| diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
|
| index 1938950cebf21817fa52746ec83d614fc136e32f..4789edc6d93c188285f405d3c6787099dd1c698b 100644
|
| --- a/runtime/vm/simulator_dbc.cc
|
| +++ b/runtime/vm/simulator_dbc.cc
|
| @@ -1854,6 +1854,73 @@ RawObject* Simulator::Call(const Code& code,
|
| }
|
|
|
| {
|
| + BYTECODE(InstanceOf, A); // Stack: instance, type args, type, cache
|
| + RawInstance* instance = static_cast<RawInstance*>(SP[-3]);
|
| + RawTypeArguments* instantiator_type_arguments =
|
| + static_cast<RawTypeArguments*>(SP[-2]);
|
| + RawAbstractType* type = static_cast<RawAbstractType*>(SP[-1]);
|
| + RawSubtypeTestCache* cache = static_cast<RawSubtypeTestCache*>(SP[0]);
|
| +
|
| + if (cache != null_value) {
|
| + const intptr_t cid = SimulatorHelpers::GetClassId(instance);
|
| +
|
| + RawTypeArguments* instance_type_arguments =
|
| + static_cast<RawTypeArguments*>(null_value);
|
| + RawObject* instance_cid_or_function;
|
| + if (cid == kClosureCid) {
|
| + RawClosure* closure = static_cast<RawClosure*>(instance);
|
| + instance_type_arguments = closure->ptr()->type_arguments_;
|
| + instance_cid_or_function = closure->ptr()->function_;
|
| + } else {
|
| + instance_cid_or_function = Smi::New(cid);
|
| +
|
| + RawClass* instance_class =
|
| + thread->isolate()->class_table()->At(cid);
|
| + if (instance_class->ptr()->num_type_arguments_ < 0) {
|
| + goto InstanceOfCallRuntime;
|
| + } else if (instance_class->ptr()->num_type_arguments_ > 0) {
|
| + instance_type_arguments = reinterpret_cast<RawTypeArguments**>(
|
| + instance
|
| + ->ptr())[instance_class->ptr()
|
| + ->type_arguments_field_offset_in_words_];
|
| + }
|
| + }
|
| +
|
| + for (RawObject** entries = cache->ptr()->cache_->ptr()->data();
|
| + entries[0] != null_value;
|
| + entries += SubtypeTestCache::kTestEntryLength) {
|
| + if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] ==
|
| + instance_cid_or_function) &&
|
| + (entries[SubtypeTestCache::kInstanceTypeArguments] ==
|
| + instance_type_arguments) &&
|
| + (entries[SubtypeTestCache::kInstantiatorTypeArguments] ==
|
| + instantiator_type_arguments)) {
|
| + SP[-3] = entries[SubtypeTestCache::kTestResult];
|
| + goto InstanceOfOk;
|
| + }
|
| + }
|
| + }
|
| +
|
| + InstanceOfCallRuntime:
|
| + {
|
| + SP[1] = instance;
|
| + SP[2] = type;
|
| + SP[3] = instantiator_type_arguments;
|
| + SP[4] = cache;
|
| + Exit(thread, FP, SP + 5, pc);
|
| + NativeArguments native_args(thread, 4, SP + 1, SP - 3);
|
| + INVOKE_RUNTIME(DRT_Instanceof, native_args);
|
| + }
|
| +
|
| + InstanceOfOk:
|
| + SP -= 3;
|
| + if (rA) { // Negate result.
|
| + SP[0] = (SP[0] == true_value) ? false_value : true_value;
|
| + }
|
| + DISPATCH();
|
| + }
|
| +
|
| + {
|
| BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name
|
| RawObject** args = SP - 3;
|
| if (args[0] != null_value) {
|
|
|