Reapply "[vm, interpreter] Bytecode support for dynamic invocation forwarders."
Add missing entries to RAW_CLASSES_AND_FIELDS.
Change-Id: Ib90f4878d3eff81a6a059f7e38f1d6593cd85cfc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105820
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index f95d77f..4e23dea 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -36,6 +36,7 @@
V(ExceptionHandlers) \
V(Context) \
V(ContextScope) \
+ V(ParameterTypeCheck) \
V(SingleTargetCache) \
V(UnlinkedCall) \
V(ICData) \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index a71b9cb..39249519 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -2104,6 +2104,71 @@
};
#if !defined(DART_PRECOMPILED_RUNTIME)
+class ParameterTypeCheckSerializationCluster : public SerializationCluster {
+ public:
+ ParameterTypeCheckSerializationCluster()
+ : SerializationCluster("ParameterTypeCheck") {}
+ ~ParameterTypeCheckSerializationCluster() {}
+
+ void Trace(Serializer* s, RawObject* object) {
+ RawParameterTypeCheck* unlinked = ParameterTypeCheck::RawCast(object);
+ objects_.Add(unlinked);
+ PushFromTo(unlinked);
+ }
+
+ void WriteAlloc(Serializer* s) {
+ s->WriteCid(kParameterTypeCheckCid);
+ intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ RawParameterTypeCheck* check = objects_[i];
+ s->AssignRef(check);
+ }
+ }
+
+ void WriteFill(Serializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ RawParameterTypeCheck* check = objects_[i];
+ s->Write<intptr_t>(check->ptr()->index_);
+ WriteFromTo(check);
+ }
+ }
+
+ private:
+ GrowableArray<RawParameterTypeCheck*> objects_;
+};
+#endif // !DART_PRECOMPILED_RUNTIME
+
+class ParameterTypeCheckDeserializationCluster : public DeserializationCluster {
+ public:
+ ParameterTypeCheckDeserializationCluster() {}
+ ~ParameterTypeCheckDeserializationCluster() {}
+
+ void ReadAlloc(Deserializer* d) {
+ start_index_ = d->next_index();
+ PageSpace* old_space = d->heap()->old_space();
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(
+ AllocateUninitialized(old_space, ParameterTypeCheck::InstanceSize()));
+ }
+ stop_index_ = d->next_index();
+ }
+
+ void ReadFill(Deserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ RawParameterTypeCheck* check =
+ reinterpret_cast<RawParameterTypeCheck*>(d->Ref(id));
+ Deserializer::InitializeHeader(check, kParameterTypeCheckCid,
+ ParameterTypeCheck::InstanceSize());
+ check->ptr()->index_ = d->Read<intptr_t>();
+ ReadFromTo(check);
+ }
+ }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
class UnlinkedCallSerializationCluster : public SerializationCluster {
public:
UnlinkedCallSerializationCluster() : SerializationCluster("UnlinkedCall") {}
@@ -4275,6 +4340,8 @@
return new (Z) ContextSerializationCluster();
case kContextScopeCid:
return new (Z) ContextScopeSerializationCluster();
+ case kParameterTypeCheckCid:
+ return new (Z) ParameterTypeCheckSerializationCluster();
case kUnlinkedCallCid:
return new (Z) UnlinkedCallSerializationCluster();
case kICDataCid:
@@ -4712,6 +4779,8 @@
"<invoke field>");
AddBaseObject(Object::nsm_dispatcher_bytecode().raw(), "Bytecode",
"<nsm dispatcher>");
+ AddBaseObject(Object::dynamic_invocation_forwarder_bytecode().raw(),
+ "Bytecode", "<dyn forwarder>");
for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i],
@@ -4905,6 +4974,8 @@
return new (Z) ContextDeserializationCluster();
case kContextScopeCid:
return new (Z) ContextScopeDeserializationCluster();
+ case kParameterTypeCheckCid:
+ return new (Z) ParameterTypeCheckDeserializationCluster();
case kUnlinkedCallCid:
return new (Z) UnlinkedCallDeserializationCluster();
case kICDataCid:
@@ -5174,6 +5245,7 @@
AddBaseObject(Object::invoke_closure_bytecode().raw());
AddBaseObject(Object::invoke_field_bytecode().raw());
AddBaseObject(Object::nsm_dispatcher_bytecode().raw());
+ AddBaseObject(Object::dynamic_invocation_forwarder_bytecode().raw());
for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index c180689..c747fbd 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -53,6 +53,7 @@
(function.kind() != RawFunction::kImplicitStaticGetter) &&
(function.kind() != RawFunction::kMethodExtractor) &&
(function.kind() != RawFunction::kInvokeFieldDispatcher) &&
+ (function.kind() != RawFunction::kDynamicInvocationForwarder) &&
(function.kind() != RawFunction::kNoSuchMethodDispatcher)) {
return;
}
@@ -269,6 +270,142 @@
}
}
+static intptr_t IndexFor(Zone* zone,
+ const Function& function,
+ const String& name) {
+ const Bytecode& bc = Bytecode::Handle(zone, function.bytecode());
+ const ObjectPool& pool = ObjectPool::Handle(zone, bc.object_pool());
+ const KBCInstr* pc = reinterpret_cast<const KBCInstr*>(bc.PayloadStart());
+
+ ASSERT(KernelBytecode::IsEntryOptionalOpcode(pc));
+ ASSERT(KernelBytecode::DecodeB(pc) ==
+ function.NumOptionalPositionalParameters());
+ ASSERT(KernelBytecode::DecodeC(pc) == function.NumOptionalNamedParameters());
+ pc = KernelBytecode::Next(pc);
+
+ const intptr_t num_opt_params = function.NumOptionalParameters();
+ const intptr_t num_fixed_params = function.num_fixed_parameters();
+ for (intptr_t i = 0; i < num_opt_params; i++) {
+ const KBCInstr* load_name = pc;
+ const KBCInstr* load_value = KernelBytecode::Next(load_name);
+ pc = KernelBytecode::Next(load_value);
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
+ if (pool.ObjectAt(KernelBytecode::DecodeE(load_name)) == name.raw()) {
+ return num_fixed_params + i;
+ }
+ }
+
+ UNREACHABLE();
+ return -1;
+}
+
+RawArray* BytecodeReaderHelper::CreateForwarderChecks(
+ const Function& function) {
+ ASSERT(function.kind() != RawFunction::kDynamicInvocationForwarder);
+ ASSERT(function.is_declared_in_bytecode());
+
+ TypeArguments& default_args = TypeArguments::Handle(Z);
+ if (function.bytecode_offset() != 0) {
+ AlternativeReadingScope alt(&reader_, function.bytecode_offset());
+
+ const intptr_t flags = reader_.ReadUInt();
+ const bool has_parameters_flags =
+ (flags & Code::kHasParameterFlagsFlag) != 0;
+ const bool has_forwarding_stub_target =
+ (flags & Code::kHasForwardingStubTargetFlag) != 0;
+ const bool has_default_function_type_args =
+ (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0;
+
+ if (has_parameters_flags) {
+ intptr_t num_params = reader_.ReadUInt();
+ ASSERT(num_params ==
+ function.NumParameters() - function.NumImplicitParameters());
+ for (intptr_t i = 0; i < num_params; ++i) {
+ reader_.ReadUInt();
+ }
+ }
+
+ if (has_forwarding_stub_target) {
+ reader_.ReadUInt();
+ }
+
+ if (has_default_function_type_args) {
+ const intptr_t index = reader_.ReadUInt();
+ const Bytecode& code = Bytecode::Handle(Z, function.bytecode());
+ const ObjectPool& pool = ObjectPool::Handle(Z, code.object_pool());
+ default_args ^= pool.ObjectAt(index);
+ }
+ }
+
+ auto& name = String::Handle(Z);
+ auto& check = ParameterTypeCheck::Handle(Z);
+ auto& checks = GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+
+ checks.Add(function);
+ checks.Add(default_args);
+
+ const auto& type_params =
+ TypeArguments::Handle(Z, function.type_parameters());
+ if (!type_params.IsNull()) {
+ auto& type_param = TypeParameter::Handle(Z);
+ auto& bound = AbstractType::Handle(Z);
+ for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) {
+ type_param ^= type_params.TypeAt(i);
+ bound = type_param.bound();
+ if (!bound.IsTopType() && !type_param.IsGenericCovariantImpl()) {
+ name = type_param.name();
+ ASSERT(type_param.IsFinalized());
+ check = ParameterTypeCheck::New();
+ check.set_param(type_param);
+ check.set_type_or_bound(bound);
+ check.set_name(name);
+ checks.Add(check);
+ }
+ }
+ }
+
+ const intptr_t num_params = function.NumParameters();
+ const intptr_t num_pos_params = function.HasOptionalNamedParameters()
+ ? function.num_fixed_parameters()
+ : num_params;
+
+ BitVector is_covariant(Z, num_params);
+ BitVector is_generic_covariant_impl(Z, num_params);
+ ReadParameterCovariance(function, &is_covariant, &is_generic_covariant_impl);
+
+ auto& type = AbstractType::Handle(Z);
+ auto& cache = SubtypeTestCache::Handle(Z);
+ const bool has_optional_parameters = function.HasOptionalParameters();
+ for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
+ type = function.ParameterTypeAt(i);
+ if (!type.IsTopType() && !is_generic_covariant_impl.Contains(i) &&
+ !is_covariant.Contains(i)) {
+ name = function.ParameterNameAt(i);
+ intptr_t index;
+ if (i >= num_pos_params) {
+ // Named parameter.
+ index = IndexFor(Z, function, name);
+ } else if (has_optional_parameters) {
+ // Fixed or optional parameter.
+ index = i;
+ } else {
+ // Fixed parameter.
+ index = -kKBCParamEndSlotFromFp - num_params + i;
+ }
+ check = ParameterTypeCheck::New();
+ check.set_index(index);
+ check.set_type_or_bound(type);
+ check.set_name(name);
+ cache = SubtypeTestCache::New();
+ check.set_cache(cache);
+ checks.Add(check);
+ }
+ }
+
+ return Array::MakeFixedLength(checks);
+}
+
void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
intptr_t closureIndex) {
// Closure flags, must be in sync with ClosureDeclaration constants in
@@ -2096,7 +2233,7 @@
VMTagScope tagScope(thread, VMTag::kLoadBytecodeTagId);
#if defined(SUPPORT_TIMELINE)
- TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
+ TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
"BytecodeReader::ReadFunctionBytecode");
// This increases bytecode reading time by ~7%, so only keep it around for
// debugging.
@@ -2130,7 +2267,7 @@
bytecode = Object::method_extractor_bytecode().raw();
break;
case RawFunction::kInvokeFieldDispatcher:
- if (Class::Handle(function.Owner()).id() == kClosureCid) {
+ if (Class::Handle(zone, function.Owner()).id() == kClosureCid) {
bytecode = Object::invoke_closure_bytecode().raw();
} else {
bytecode = Object::invoke_field_bytecode().raw();
@@ -2139,6 +2276,36 @@
case RawFunction::kNoSuchMethodDispatcher:
bytecode = Object::nsm_dispatcher_bytecode().raw();
break;
+ case RawFunction::kDynamicInvocationForwarder: {
+ const Function& target =
+ Function::Handle(zone, function.ForwardingTarget());
+ if (!target.HasBytecode()) {
+ // The forwarder will use the target's bytecode to handle optional
+ // parameters.
+ const Error& error =
+ Error::Handle(zone, ReadFunctionBytecode(thread, target));
+ if (!error.IsNull()) {
+ return error.raw();
+ }
+ }
+ {
+ const Script& script = Script::Handle(zone, target.script());
+ TranslationHelper translation_helper(thread);
+ translation_helper.InitFromScript(script);
+
+ ActiveClass active_class;
+ BytecodeComponentData bytecode_component(
+ Array::Handle(zone, translation_helper.GetBytecodeComponent()));
+ ASSERT(!bytecode_component.IsNull());
+ BytecodeReaderHelper bytecode_reader(
+ &translation_helper, &active_class, &bytecode_component);
+
+ const Array& checks = Array::Handle(
+ zone, bytecode_reader.CreateForwarderChecks(target));
+ function.SetForwardingChecks(checks);
+ }
+ bytecode = Object::dynamic_invocation_forwarder_bytecode().raw();
+ } break;
default:
break;
}
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 753bff9..830bf95 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -54,6 +54,8 @@
void ReadCode(const Function& function, intptr_t code_offset);
+ RawArray* CreateForwarderChecks(const Function& function);
+
void ReadMembers(const Class& cls,
intptr_t members_offset,
bool discard_fields);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 2668c17..0306907 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2234,7 +2234,13 @@
function.IsImplicitSetterFunction();
const bool is_method = !function.IsStaticFunction();
- Field& field = Field::ZoneHandle(Z, function.accessor_field());
+ Field& field = Field::ZoneHandle(Z);
+ if (function.IsDynamicInvocationForwarder()) {
+ Function& target = Function::Handle(function.ForwardingTarget());
+ field = target.accessor_field();
+ } else {
+ field = function.accessor_field();
+ }
graph_entry_ =
new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index e188c08..2f823c5 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -1186,6 +1186,120 @@
}
#endif // PRODUCT
+bool Interpreter::CopyParameters(Thread* thread,
+ const KBCInstr** pc,
+ RawObject*** FP,
+ RawObject*** SP,
+ const intptr_t num_fixed_params,
+ const intptr_t num_opt_pos_params,
+ const intptr_t num_opt_named_params) {
+ const intptr_t min_num_pos_args = num_fixed_params;
+ const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params;
+
+ // Decode arguments descriptor.
+ const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
+ const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
+ const intptr_t named_count = (arg_count - pos_count);
+
+ // Check that got the right number of positional parameters.
+ if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) {
+ return false;
+ }
+
+ // Copy all passed position arguments.
+ RawObject** first_arg = FrameArguments(*FP, arg_count);
+ memmove(*FP, first_arg, pos_count * kWordSize);
+
+ if (num_opt_named_params != 0) {
+ // This is a function with named parameters.
+ // Walk the list of named parameters and their
+ // default values encoded as pairs of LoadConstant instructions that
+ // follows the entry point and find matching values via arguments
+ // descriptor.
+ RawObject** argdesc_data = argdesc_->ptr()->data();
+
+ intptr_t i = 0; // argument position
+ intptr_t j = 0; // parameter position
+ while ((j < num_opt_named_params) && (i < named_count)) {
+ // Fetch formal parameter information: name, default value, target slot.
+ const KBCInstr* load_name = *pc;
+ const KBCInstr* load_value = KernelBytecode::Next(load_name);
+ *pc = KernelBytecode::Next(load_value);
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
+ const uint8_t reg = KernelBytecode::DecodeA(load_name);
+ ASSERT(reg == KernelBytecode::DecodeA(load_value));
+
+ RawString* name = static_cast<RawString*>(
+ LOAD_CONSTANT(KernelBytecode::DecodeE(load_name)));
+ if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
+ // Parameter was passed. Fetch passed value.
+ const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
+ argdesc_data[ArgumentsDescriptor::position_index(i)]));
+ (*FP)[reg] = first_arg[arg_index];
+ ++i; // Consume passed argument.
+ } else {
+ // Parameter was not passed. Fetch default value.
+ (*FP)[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
+ }
+ ++j; // Next formal parameter.
+ }
+
+ // If we have unprocessed formal parameters then initialize them all
+ // using default values.
+ while (j < num_opt_named_params) {
+ const KBCInstr* load_name = *pc;
+ const KBCInstr* load_value = KernelBytecode::Next(load_name);
+ *pc = KernelBytecode::Next(load_value);
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
+ const uint8_t reg = KernelBytecode::DecodeA(load_name);
+ ASSERT(reg == KernelBytecode::DecodeA(load_value));
+
+ (*FP)[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
+ ++j;
+ }
+
+ // If we have unprocessed passed arguments that means we have mismatch
+ // between formal parameters and concrete arguments. This can only
+ // occur if the current function is a closure.
+ if (i < named_count) {
+ return false;
+ }
+
+ // SP points past copied arguments.
+ *SP = *FP + num_fixed_params + num_opt_named_params - 1;
+ } else {
+ ASSERT(num_opt_pos_params != 0);
+ if (named_count != 0) {
+ // Function can't have both named and optional positional parameters.
+ // This kind of mismatch can only occur if the current function
+ // is a closure.
+ return false;
+ }
+
+ // Process the list of default values encoded as a sequence of
+ // LoadConstant instructions after EntryOpt bytecode.
+ // Execute only those that correspond to parameters that were not passed.
+ for (intptr_t i = num_fixed_params; i < pos_count; ++i) {
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(*pc));
+ *pc = KernelBytecode::Next(*pc);
+ }
+ for (intptr_t i = pos_count; i < max_num_pos_args; ++i) {
+ const KBCInstr* load_value = *pc;
+ *pc = KernelBytecode::Next(load_value);
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
+ ASSERT(KernelBytecode::DecodeA(load_value) == i);
+ (*FP)[i] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
+ }
+
+ // SP points past the last copied parameter.
+ *SP = *FP + max_num_pos_args - 1;
+ }
+
+ return true;
+}
+
bool Interpreter::AssertAssignable(Thread* thread,
const KBCInstr* pc,
RawObject** FP,
@@ -1651,114 +1765,11 @@
{
BYTECODE(EntryOptional, A_B_C);
- const intptr_t num_fixed_params = rA;
- const intptr_t num_opt_pos_params = rB;
- const intptr_t num_opt_named_params = rC;
- const intptr_t min_num_pos_args = num_fixed_params;
- const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params;
-
- // Decode arguments descriptor.
- const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
- const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
- const intptr_t named_count = (arg_count - pos_count);
-
- // Check that got the right number of positional parameters.
- if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) {
+ if (CopyParameters(thread, &pc, &FP, &SP, rA, rB, rC)) {
+ DISPATCH();
+ } else {
goto NoSuchMethodFromPrologue;
}
-
- // Copy all passed position arguments.
- RawObject** first_arg = FrameArguments(FP, arg_count);
- memmove(FP, first_arg, pos_count * kWordSize);
-
- if (num_opt_named_params != 0) {
- // This is a function with named parameters.
- // Walk the list of named parameters and their
- // default values encoded as pairs of LoadConstant instructions that
- // follows the entry point and find matching values via arguments
- // descriptor.
- RawObject** argdesc_data = argdesc_->ptr()->data();
-
- intptr_t i = 0; // argument position
- intptr_t j = 0; // parameter position
- while ((j < num_opt_named_params) && (i < named_count)) {
- // Fetch formal parameter information: name, default value, target slot.
- const KBCInstr* load_name = pc;
- const KBCInstr* load_value = KernelBytecode::Next(load_name);
- pc = KernelBytecode::Next(load_value);
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
- const uint8_t reg = KernelBytecode::DecodeA(load_name);
- ASSERT(reg == KernelBytecode::DecodeA(load_value));
-
- RawString* name = static_cast<RawString*>(
- LOAD_CONSTANT(KernelBytecode::DecodeE(load_name)));
- if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
- // Parameter was passed. Fetch passed value.
- const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
- argdesc_data[ArgumentsDescriptor::position_index(i)]));
- FP[reg] = first_arg[arg_index];
- ++i; // Consume passed argument.
- } else {
- // Parameter was not passed. Fetch default value.
- FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
- }
- ++j; // Next formal parameter.
- }
-
- // If we have unprocessed formal parameters then initialize them all
- // using default values.
- while (j < num_opt_named_params) {
- const KBCInstr* load_name = pc;
- const KBCInstr* load_value = KernelBytecode::Next(load_name);
- pc = KernelBytecode::Next(load_value);
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
- const uint8_t reg = KernelBytecode::DecodeA(load_name);
- ASSERT(reg == KernelBytecode::DecodeA(load_value));
-
- FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
- ++j;
- }
-
- // If we have unprocessed passed arguments that means we have mismatch
- // between formal parameters and concrete arguments. This can only
- // occur if the current function is a closure.
- if (i < named_count) {
- goto NoSuchMethodFromPrologue;
- }
-
- // SP points past copied arguments.
- SP = FP + num_fixed_params + num_opt_named_params - 1;
- } else {
- ASSERT(num_opt_pos_params != 0);
- if (named_count != 0) {
- // Function can't have both named and optional positional parameters.
- // This kind of mismatch can only occur if the current function
- // is a closure.
- goto NoSuchMethodFromPrologue;
- }
-
- // Process the list of default values encoded as a sequence of
- // LoadConstant instructions after EntryOpt bytecode.
- // Execute only those that correspond to parameters that were not passed.
- for (intptr_t i = num_fixed_params; i < pos_count; ++i) {
- ASSERT(KernelBytecode::IsLoadConstantOpcode(pc));
- pc = KernelBytecode::Next(pc);
- }
- for (intptr_t i = pos_count; i < max_num_pos_args; ++i) {
- const KBCInstr* load_value = pc;
- pc = KernelBytecode::Next(load_value);
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
- ASSERT(KernelBytecode::DecodeA(load_value) == i);
- FP[i] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
- }
-
- // SP points past the last copied parameter.
- SP = FP + max_num_pos_args - 1;
- }
-
- DISPATCH();
}
{
@@ -3469,8 +3480,101 @@
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) ==
RawFunction::kDynamicInvocationForwarder);
- UNIMPLEMENTED();
- DISPATCH();
+
+ BUMP_USAGE_COUNTER_ON_ENTRY(function);
+
+ RawArray* checks = Array::RawCast(function->ptr()->data_);
+ RawFunction* target = Function::RawCast(checks->ptr()->data()[0]);
+ ASSERT(Function::kind(target) != RawFunction::kDynamicInvocationForwarder);
+ RawBytecode* target_bytecode = target->ptr()->bytecode_;
+ ASSERT(target_bytecode != Bytecode::null());
+ ASSERT(target_bytecode->IsBytecode());
+
+ const KBCInstr* pc2 = reinterpret_cast<const KBCInstr*>(
+ target_bytecode->ptr()->instructions_);
+ if (KernelBytecode::IsEntryOptionalOpcode(pc2)) {
+ pp_ = target_bytecode->ptr()->object_pool_;
+ uint32_t rA, rB, rC;
+ rA = KernelBytecode::DecodeA(pc2);
+ rB = KernelBytecode::DecodeB(pc2);
+ rC = KernelBytecode::DecodeC(pc2);
+ pc2 = KernelBytecode::Next(pc2);
+ if (!CopyParameters(thread, &pc2, &FP, &SP, rA, rB, rC)) {
+ goto NoSuchMethodFromPrologue;
+ }
+ }
+
+ intptr_t len = Smi::Value(checks->ptr()->length_);
+ SP[1] = checks;
+ SP[2] = argdesc_;
+
+ const intptr_t type_args_len =
+ InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
+ const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
+ const intptr_t argc =
+ InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
+
+ RawInstance* receiver =
+ Instance::RawCast(FrameArguments(FP, argc)[receiver_idx]);
+ SP[5] = InterpreterHelpers::GetTypeArguments(thread, receiver);
+
+ if (type_args_len > 0) {
+ SP[6] = FrameArguments(FP, argc)[0];
+ } else {
+ SP[6] = TypeArguments::RawCast(checks->ptr()->data()[1]);
+ if (SP[5] != null_value && SP[6] != null_value) {
+ SP[7] = SP[6]; // type_arguments
+ SP[8] = SP[5]; // instantiator_type_args
+ SP[9] = null_value; // function_type_args
+ Exit(thread, FP, SP + 10, pc);
+ NativeArguments args(thread, 3, SP + 7, SP + 7);
+ INVOKE_RUNTIME(DRT_InstantiateTypeArguments, args);
+ SP[6] = SP[7];
+ }
+ }
+
+ for (intptr_t i = 2; i < len; i++) {
+ RawParameterTypeCheck* check =
+ ParameterTypeCheck::RawCast(checks->ptr()->data()[i]);
+
+ if (LIKELY(check->ptr()->index_ != 0)) {
+ ASSERT(&FP[check->ptr()->index_] <= SP);
+ SP[3] = Instance::RawCast(FP[check->ptr()->index_]);
+ if (SP[3] == null_value) {
+ continue; // Not handled by AssertAssignable for some reason...
+ }
+ SP[4] = check->ptr()->type_or_bound_;
+ // SP[5]: Instantiator type args.
+ // SP[6]: Function type args.
+ SP[7] = check->ptr()->name_;
+ if (!AssertAssignable(thread, pc, FP, SP, SP + 3,
+ check->ptr()->cache_)) {
+ HANDLE_EXCEPTION;
+ }
+ } else {
+ SP[3] = 0;
+ SP[4] = 0;
+ // SP[5]: Instantiator type args.
+ // SP[6]: Function type args.
+ SP[7] = check->ptr()->param_;
+ SP[8] = check->ptr()->type_or_bound_;
+ SP[9] = check->ptr()->name_;
+ SP[10] = 0;
+ Exit(thread, FP, SP + 11, pc);
+ NativeArguments native_args(thread, 5, SP + 5, SP + 10);
+ INVOKE_RUNTIME(DRT_SubtypeCheck, native_args);
+ }
+
+ checks = Array::RawCast(SP[1]); // Reload after runtime call.
+ }
+
+ target = Function::RawCast(checks->ptr()->data()[0]);
+ argdesc_ = Array::RawCast(SP[2]);
+
+ SP = FP - 1; // Unmarshall optional parameters.
+
+ SP[1] = target;
+ goto TailCallSP1;
}
{
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index a47eecc..a8e393f 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -209,6 +209,14 @@
RawObject*** SP,
bool optimized);
+ bool CopyParameters(Thread* thread,
+ const KBCInstr** pc,
+ RawObject*** FP,
+ RawObject*** SP,
+ const intptr_t num_fixed_params,
+ const intptr_t num_opt_pos_params,
+ const intptr_t num_opt_named_params);
+
bool AssertAssignable(Thread* thread,
const KBCInstr* pc,
RawObject** FP,
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 946135e..b16d1b3 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -11,6 +11,7 @@
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/parser.h" // For Parser::kParameter* constants.
+#include "vm/stack_frame.h"
#if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 4e66b89..32f975f 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -208,6 +208,11 @@
// as such function already checks all of its parameters.
bool NeedsDynamicInvocationForwarder(const Function& function);
+// Returns a list of ParameterTypeChecks needed by a dynamic invocation
+// forwarder that targets [function]. Indices in these checks correspond to
+// bytecode frame indices.
+RawArray* CollectDynamicInvocationChecks(const Function& function);
+
ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
Zone* zone);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index f914e28..6066a17 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -153,6 +153,8 @@
reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
+RawClass* Object::dyncalltypecheck_class_ =
+ reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::singletargetcache_class_ =
reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -648,6 +650,9 @@
cls = Class::New<ContextScope>();
context_scope_class_ = cls.raw();
+ cls = Class::New<ParameterTypeCheck>();
+ dyncalltypecheck_class_ = cls.raw();
+
cls = Class::New<SingleTargetCache>();
singletargetcache_class_ = cls.raw();
@@ -907,6 +912,9 @@
*nsm_dispatcher_bytecode_ = CreateVMInternalBytecode(
KernelBytecode::kVMInternal_NoSuchMethodDispatcher);
+ *dynamic_invocation_forwarder_bytecode_ = CreateVMInternalBytecode(
+ KernelBytecode::kVMInternal_ForwardDynamicInvocation);
+
// Some thread fields need to be reinitialized as null constants have not been
// initialized until now.
Thread* thr = Thread::Current();
@@ -978,6 +986,8 @@
ASSERT(invoke_field_bytecode_->IsBytecode());
ASSERT(!nsm_dispatcher_bytecode_->IsSmi());
ASSERT(nsm_dispatcher_bytecode_->IsBytecode());
+ ASSERT(!dynamic_invocation_forwarder_bytecode_->IsSmi());
+ ASSERT(dynamic_invocation_forwarder_bytecode_->IsBytecode());
}
void Object::FinishInit(Isolate* isolate) {
@@ -1021,6 +1031,7 @@
exception_handlers_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
+ dyncalltypecheck_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
singletargetcache_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
@@ -1120,6 +1131,7 @@
SET_CLASS_NAME(exception_handlers, ExceptionHandlers);
SET_CLASS_NAME(context, Context);
SET_CLASS_NAME(context_scope, ContextScope);
+ SET_CLASS_NAME(dyncalltypecheck, ParameterTypeCheck);
SET_CLASS_NAME(singletargetcache, SingleTargetCache);
SET_CLASS_NAME(unlinkedcall, UnlinkedCall);
SET_CLASS_NAME(icdata, ICData);
@@ -3058,6 +3070,10 @@
forwarder.InheritBinaryDeclarationFrom(*this);
+ const Array& checks = Array::Handle(zone, Array::New(1));
+ checks.SetAt(0, *this);
+ forwarder.SetForwardingChecks(checks);
+
return forwarder.raw();
}
@@ -3893,6 +3909,8 @@
return Symbols::Context().raw();
case kContextScopeCid:
return Symbols::ContextScope().raw();
+ case kParameterTypeCheckCid:
+ return Symbols::ParameterTypeCheck().raw();
case kSingleTargetCacheCid:
return Symbols::SingleTargetCache().raw();
case kICDataCid:
@@ -5655,6 +5673,7 @@
}
switch (kind()) {
case RawFunction::kDynamicInvocationForwarder:
+ return is_declared_in_bytecode();
case RawFunction::kImplicitClosureFunction:
case RawFunction::kIrregexpFunction:
case RawFunction::kFfiTrampoline:
@@ -5877,8 +5896,7 @@
ASSERT(kind() == RawFunction::kImplicitGetter ||
kind() == RawFunction::kImplicitSetter ||
kind() == RawFunction::kImplicitStaticGetter ||
- kind() == RawFunction::kStaticFieldInitializer ||
- kind() == RawFunction::kDynamicInvocationForwarder);
+ kind() == RawFunction::kStaticFieldInitializer);
return Field::RawCast(raw_ptr()->data_);
}
@@ -6217,6 +6235,20 @@
RedirectionData::Cast(obj).set_target(target);
}
+RawFunction* Function::ForwardingTarget() const {
+ ASSERT(kind() == RawFunction::kDynamicInvocationForwarder);
+ Array& checks = Array::Handle();
+ checks ^= raw_ptr()->data_;
+ return Function::RawCast(checks.At(0));
+}
+
+void Function::SetForwardingChecks(const Array& checks) const {
+ ASSERT(kind() == RawFunction::kDynamicInvocationForwarder);
+ ASSERT(checks.Length() >= 1);
+ ASSERT(Object::Handle(checks.At(0)).IsFunction());
+ set_data(checks);
+}
+
// This field is heavily overloaded:
// eval function: Script expression source
// kernel eval function: Array[0] = Script
@@ -6238,6 +6270,9 @@
// Array[1] = Function implicit closure function
// regular function: Function for implicit closure function
// ffi trampoline function: FfiTrampolineData (Dart->C)
+// dyn inv forwarder: Array[0] = Function target
+// Array[1] = TypeArguments default type args
+// Array[i] = ParameterTypeCheck
void Function::set_data(const Object& value) const {
StorePointer(&raw_ptr()->data_, value.raw());
}
@@ -13186,6 +13221,43 @@
#undef FORMAT2
}
+void ParameterTypeCheck::set_type_or_bound(const AbstractType& value) const {
+ StorePointer(&raw_ptr()->type_or_bound_, value.raw());
+}
+
+void ParameterTypeCheck::set_param(const AbstractType& value) const {
+ StorePointer(&raw_ptr()->param_, value.raw());
+}
+
+void ParameterTypeCheck::set_name(const String& value) const {
+ StorePointer(&raw_ptr()->name_, value.raw());
+}
+
+void ParameterTypeCheck::set_cache(const SubtypeTestCache& value) const {
+ StorePointer(&raw_ptr()->cache_, value.raw());
+}
+
+const char* ParameterTypeCheck::ToCString() const {
+ Zone* zone = Thread::Current()->zone();
+ return zone->PrintToString("ParameterTypeCheck(%" Pd " %s %s %s)", index(),
+ Object::Handle(zone, param()).ToCString(),
+ Object::Handle(zone, type_or_bound()).ToCString(),
+ Object::Handle(zone, name()).ToCString());
+}
+
+RawParameterTypeCheck* ParameterTypeCheck::New() {
+ ParameterTypeCheck& result = ParameterTypeCheck::Handle();
+ {
+ RawObject* raw =
+ Object::Allocate(ParameterTypeCheck::kClassId,
+ ParameterTypeCheck::InstanceSize(), Heap::kOld);
+ NoSafepointScope no_safepoint;
+ result ^= raw;
+ }
+ result.set_index(0);
+ return result.raw();
+}
+
void SingleTargetCache::set_target(const Code& value) const {
StorePointer(&raw_ptr()->target_, value.raw());
}
@@ -13252,14 +13324,14 @@
}
const char* ICData::ToCString() const {
- const String& name = String::Handle(target_name());
+ Zone* zone = Thread::Current()->zone();
+ const String& name = String::Handle(zone, target_name());
const intptr_t num_args = NumArgsTested();
const intptr_t num_checks = NumberOfChecks();
const intptr_t type_args_len = TypeArgsLen();
- return OS::SCreate(Thread::Current()->zone(),
- "ICData target:'%s' num-args: %" Pd " num-checks: %" Pd
- " type-args-len: %" Pd "",
- name.ToCString(), num_args, num_checks, type_args_len);
+ return zone->PrintToString(
+ "ICData(%s num-args: %" Pd " num-checks: %" Pd " type-args-len: %" Pd ")",
+ name.ToCString(), num_args, num_checks, type_args_len);
}
RawFunction* ICData::Owner() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 33261da..82b27a0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -403,6 +403,7 @@
V(Bytecode, invoke_closure_bytecode) \
V(Bytecode, invoke_field_bytecode) \
V(Bytecode, nsm_dispatcher_bytecode) \
+ V(Bytecode, dynamic_invocation_forwarder_bytecode) \
V(Instance, sentinel) \
V(Instance, transition_sentinel) \
V(Instance, unknown_constant) \
@@ -468,6 +469,7 @@
return unhandled_exception_class_;
}
static RawClass* unwind_error_class() { return unwind_error_class_; }
+ static RawClass* dyncalltypecheck_class() { return dyncalltypecheck_class_; }
static RawClass* singletargetcache_class() {
return singletargetcache_class_;
}
@@ -705,6 +707,7 @@
static RawClass* deopt_info_class_; // Class of DeoptInfo.
static RawClass* context_class_; // Class of the Context vm object.
static RawClass* context_scope_class_; // Class of ContextScope vm object.
+ static RawClass* dyncalltypecheck_class_; // Class of ParameterTypeCheck.
static RawClass* singletargetcache_class_; // Class of SingleTargetCache.
static RawClass* unlinkedcall_class_; // Class of UnlinkedCall.
static RawClass* icdata_class_; // Class of ICData.
@@ -1491,6 +1494,41 @@
friend class Class;
};
+class ParameterTypeCheck : public Object {
+ public:
+ // The FP-relative index of the parameter in a bytecode frame (after optional
+ // parameter marshalling) whose assignability needs to be checked, or 0 if
+ // this is a type parameter check.
+ intptr_t index() const { return raw_ptr()->index_; }
+ void set_index(intptr_t i) const { StoreNonPointer(&raw_ptr()->index_, i); }
+
+ // The type parameter to whose bound needs to be checked, or null if this is
+ // an ordinary parameter check.
+ RawAbstractType* param() const { return raw_ptr()->param_; }
+ void set_param(const AbstractType& t) const;
+
+ // FP[index] assignable to type, OR param is subtype of bound.
+ RawAbstractType* type_or_bound() const { return raw_ptr()->type_or_bound_; }
+ void set_type_or_bound(const AbstractType& t) const;
+
+ // The parameter or type parameter's name to use in an error message.
+ RawString* name() const { return raw_ptr()->name_; }
+ void set_name(const String& n) const;
+
+ RawSubtypeTestCache* cache() const { return raw_ptr()->cache_; }
+ void set_cache(const SubtypeTestCache& c) const;
+
+ static intptr_t InstanceSize() {
+ return RoundedAllocationSize(sizeof(RawParameterTypeCheck));
+ }
+
+ static RawParameterTypeCheck* New();
+
+ private:
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck, Object);
+ friend class Class;
+};
+
class SingleTargetCache : public Object {
public:
RawCode* target() const { return raw_ptr()->target_; }
@@ -2249,6 +2287,9 @@
RawFunction* RedirectionTarget() const;
void SetRedirectionTarget(const Function& target) const;
+ RawFunction* ForwardingTarget() const;
+ void SetForwardingChecks(const Array& checks) const;
+
RawFunction::Kind kind() const {
return KindBits::decode(raw_ptr()->kind_tag_);
}
@@ -3002,7 +3043,6 @@
void set_num_optional_parameters(intptr_t value) const; // Encoded value.
void set_kind_tag(uint32_t value) const;
void set_data(const Object& value) const;
-
static RawFunction* New(Heap::Space space = Heap::kOld);
RawString* QualifiedName(NameVisibility name_visibility) const;
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3616d4e..e95e14e 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -729,6 +729,10 @@
Object::PrintJSONImpl(stream, ref);
}
+void ParameterTypeCheck::PrintJSONImpl(JSONStream* stream, bool ref) const {
+ Object::PrintJSONImpl(stream, ref);
+}
+
void SingleTargetCache::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 0658a6d..24a79f8 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -438,6 +438,7 @@
REGULAR_VISITOR(Library)
REGULAR_VISITOR(LibraryPrefix)
REGULAR_VISITOR(Namespace)
+REGULAR_VISITOR(ParameterTypeCheck)
REGULAR_VISITOR(SingleTargetCache)
REGULAR_VISITOR(UnlinkedCall)
REGULAR_VISITOR(ICData)
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 1028af1..91ff01e 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1705,6 +1705,18 @@
friend class SnapshotReader;
};
+class RawParameterTypeCheck : public RawObject {
+ RAW_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck);
+ intptr_t index_;
+ VISIT_FROM(RawObject*, param_);
+ RawAbstractType* param_;
+ RawAbstractType* type_or_bound_;
+ RawString* name_;
+ RawSubtypeTestCache* cache_;
+ VISIT_TO(RawObject*, cache_);
+ RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
+};
+
class RawSingleTargetCache : public RawObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache);
VISIT_FROM(RawObject*, target_);
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index c4aac7c..35d4fdc 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -112,6 +112,10 @@
F(Bytecode, closures_) \
F(ExceptionHandlers, handled_types_data_) \
F(Context, parent_) \
+ F(ParameterTypeCheck, param_) \
+ F(ParameterTypeCheck, type_or_bound_) \
+ F(ParameterTypeCheck, name_) \
+ F(ParameterTypeCheck, cache_) \
F(SingleTargetCache, target_) \
F(UnlinkedCall, target_name_) \
F(UnlinkedCall, args_descriptor_) \
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index d734dbb..22a7016 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -71,22 +71,6 @@
}
}
-RawAbstractType* AbstractType::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // AbstractType is an abstract class.
- return NULL;
-}
-
-void RawAbstractType::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // AbstractType is an abstract class.
-}
-
RawType* Type::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -364,22 +348,6 @@
}
}
-RawPatchClass* PatchClass::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return PatchClass::null();
-}
-
-void RawPatchClass::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
RawClosure* Closure::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -407,326 +375,6 @@
UNREACHABLE();
}
-RawClosureData* ClosureData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ClosureData::null();
-}
-
-void RawClosureData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawSignatureData* SignatureData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return SignatureData::null();
-}
-
-void RawSignatureData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawRedirectionData* RedirectionData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return RedirectionData::null();
-}
-
-void RawRedirectionData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawFfiTrampolineData* FfiTrampolineData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return FfiTrampolineData::null();
-}
-
-void RawFfiTrampolineData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawFunction* Function::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Function::null();
-}
-
-void RawFunction::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawField* Field::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Field::null();
-}
-
-void RawField::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawScript* Script::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Script::null();
-}
-
-void RawScript::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawLibrary* Library::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Library::null();
-}
-
-void RawLibrary::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawLibraryPrefix* LibraryPrefix::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return LibraryPrefix::null();
-}
-
-void RawLibraryPrefix::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawNamespace* Namespace::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Namespace::null();
-}
-
-void RawNamespace::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawKernelProgramInfo* KernelProgramInfo::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return KernelProgramInfo::null();
-}
-
-void RawKernelProgramInfo::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawCode* Code::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Code::null();
-}
-
-void RawCode::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawBytecode* Bytecode::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Bytecode::null();
-}
-
-void RawBytecode::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawInstructions* Instructions::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Instructions::null();
-}
-
-void RawInstructions::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawObjectPool* ObjectPool::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ObjectPool::null();
-}
-
-void RawObjectPool::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawPcDescriptors* PcDescriptors::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return PcDescriptors::null();
-}
-
-void RawPcDescriptors::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawCodeSourceMap* CodeSourceMap::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return CodeSourceMap::null();
-}
-
-void RawCodeSourceMap::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawStackMap* StackMap::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return StackMap::null();
-}
-
-void RawStackMap::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawLocalVarDescriptors* LocalVarDescriptors::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return LocalVarDescriptors::null();
-}
-
-void RawLocalVarDescriptors::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawExceptionHandlers* ExceptionHandlers::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ExceptionHandlers::null();
-}
-
-void RawExceptionHandlers::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
RawContext* Context::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -836,101 +484,72 @@
UNREACHABLE();
}
-RawSingleTargetCache* SingleTargetCache::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return SingleTargetCache::null();
-}
+#define MESSAGE_SNAPSHOT_UNREACHABLE(type) \
+ Raw##type* type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
+ intptr_t tags, Snapshot::Kind kind, \
+ bool as_reference) { \
+ UNREACHABLE(); \
+ return type::null(); \
+ } \
+ void Raw##type::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
+ Snapshot::Kind kind, bool as_reference) { \
+ UNREACHABLE(); \
+ }
-void RawSingleTargetCache::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
+#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
+ Raw##type* type::ReadFrom(SnapshotReader* reader, intptr_t object_id, \
+ intptr_t tags, Snapshot::Kind kind, \
+ bool as_reference) { \
+ UNREACHABLE(); \
+ return type::null(); \
+ } \
+ void Raw##type::WriteTo(SnapshotWriter* writer, intptr_t object_id, \
+ Snapshot::Kind kind, bool as_reference) { \
+ writer->SetWriteException(Exceptions::kArgument, \
+ "Illegal argument in isolate message" \
+ " : (object is a " #type ")"); \
+ }
-RawUnlinkedCall* UnlinkedCall::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return UnlinkedCall::null();
-}
+MESSAGE_SNAPSHOT_UNREACHABLE(AbstractType);
+MESSAGE_SNAPSHOT_UNREACHABLE(Bool);
+MESSAGE_SNAPSHOT_UNREACHABLE(Bytecode);
+MESSAGE_SNAPSHOT_UNREACHABLE(ClosureData);
+MESSAGE_SNAPSHOT_UNREACHABLE(Code);
+MESSAGE_SNAPSHOT_UNREACHABLE(CodeSourceMap);
+MESSAGE_SNAPSHOT_UNREACHABLE(Error);
+MESSAGE_SNAPSHOT_UNREACHABLE(ExceptionHandlers);
+MESSAGE_SNAPSHOT_UNREACHABLE(FfiTrampolineData);
+MESSAGE_SNAPSHOT_UNREACHABLE(Field);
+MESSAGE_SNAPSHOT_UNREACHABLE(Function);
+MESSAGE_SNAPSHOT_UNREACHABLE(ICData);
+MESSAGE_SNAPSHOT_UNREACHABLE(Instructions);
+MESSAGE_SNAPSHOT_UNREACHABLE(KernelProgramInfo);
+MESSAGE_SNAPSHOT_UNREACHABLE(Library);
+MESSAGE_SNAPSHOT_UNREACHABLE(LibraryPrefix);
+MESSAGE_SNAPSHOT_UNREACHABLE(LocalVarDescriptors);
+MESSAGE_SNAPSHOT_UNREACHABLE(MegamorphicCache);
+MESSAGE_SNAPSHOT_UNREACHABLE(Namespace);
+MESSAGE_SNAPSHOT_UNREACHABLE(ObjectPool);
+MESSAGE_SNAPSHOT_UNREACHABLE(ParameterTypeCheck);
+MESSAGE_SNAPSHOT_UNREACHABLE(PatchClass);
+MESSAGE_SNAPSHOT_UNREACHABLE(PcDescriptors);
+MESSAGE_SNAPSHOT_UNREACHABLE(RedirectionData);
+MESSAGE_SNAPSHOT_UNREACHABLE(Script);
+MESSAGE_SNAPSHOT_UNREACHABLE(SignatureData);
+MESSAGE_SNAPSHOT_UNREACHABLE(SingleTargetCache);
+MESSAGE_SNAPSHOT_UNREACHABLE(StackMap);
+MESSAGE_SNAPSHOT_UNREACHABLE(String);
+MESSAGE_SNAPSHOT_UNREACHABLE(SubtypeTestCache);
+MESSAGE_SNAPSHOT_UNREACHABLE(TypedDataBase);
+MESSAGE_SNAPSHOT_UNREACHABLE(UnlinkedCall);
+MESSAGE_SNAPSHOT_UNREACHABLE(UnwindError);
-void RawUnlinkedCall::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawICData* ICData::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ICData::null();
-}
-
-void RawICData::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawMegamorphicCache* MegamorphicCache::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return MegamorphicCache::null();
-}
-
-void RawMegamorphicCache::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawSubtypeTestCache* SubtypeTestCache::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return SubtypeTestCache::null();
-}
-
-void RawSubtypeTestCache::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
-RawError* Error::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_referenec) {
- UNREACHABLE();
- return Error::null(); // Error is an abstract class.
-}
-
-void RawError::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // Error is an abstract class.
-}
+MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
+MESSAGE_SNAPSHOT_ILLEGAL(MirrorReference);
+MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
+MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
+MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
+MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
RawApiError* ApiError::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
@@ -1047,22 +666,6 @@
visitor.VisitPointers(from(), to());
}
-RawUnwindError* UnwindError::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return UnwindError::null();
-}
-
-void RawUnwindError::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
RawInstance* Instance::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -1196,22 +799,6 @@
writer->WriteDouble(ptr()->value_);
}
-RawString* String::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // String is an abstract class.
- return String::null();
-}
-
-void RawString::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // String is an abstract class.
-}
-
template <typename StringType, typename CharacterType, typename CallbackType>
void String::ReadFromImpl(SnapshotReader* reader,
String* str_obj,
@@ -1365,22 +952,6 @@
ptr()->external_data_);
}
-RawBool* Bool::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return Bool::null();
-}
-
-void RawBool::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
-}
-
RawArray* Array::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -1722,22 +1293,6 @@
writer->Write<double>(ptr()->value_[1]);
}
-RawTypedDataBase* TypedDataBase::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // TypedDataBase is an abstract class.
- return NULL;
-}
-
-void RawTypedDataBase::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // TypedDataBase is an abstract class.
-}
-
RawTypedData* TypedData::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -2021,38 +1576,6 @@
return view.raw();
}
-RawPointer* Pointer::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- FATAL("Snapshotting Pointers is not supported");
- UNREACHABLE();
-}
-
-void RawPointer::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- FATAL("Snapshotting Pointers is not supported");
-}
-
-RawDynamicLibrary* DynamicLibrary::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- FATAL("Snapshotting DynamicLibraries is not supported");
- UNREACHABLE();
-}
-
-void RawDynamicLibrary::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- FATAL("Snapshotting DynamicLibraries is not supported");
-}
-
RawCapability* Capability::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -2080,29 +1603,6 @@
writer->Write<uint64_t>(ptr()->id_);
}
-RawReceivePort* ReceivePort::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return ReceivePort::null();
-}
-
-void RawReceivePort::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- if (kind == Snapshot::kMessage) {
- // We do not allow objects with native fields in an isolate message.
- writer->SetWriteException(Exceptions::kArgument,
- "Illegal argument in isolate message"
- " : (object is a RawReceivePort)");
- } else {
- UNREACHABLE();
- }
-}
-
RawSendPort* SendPort::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -2196,25 +1696,6 @@
});
}
-RawStackTrace* StackTrace::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE(); // StackTraces are not sent in a snapshot.
- return StackTrace::null();
-}
-
-void RawStackTrace::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- ASSERT(kind == Snapshot::kMessage);
- writer->SetWriteException(Exceptions::kArgument,
- "Illegal argument in isolate message"
- " : (object is a stacktrace)");
-}
-
RawRegExp* RegExp::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -2309,50 +1790,4 @@
visitor.VisitPointers(from(), to());
}
-RawMirrorReference* MirrorReference::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_referenec) {
- UNREACHABLE();
- return MirrorReference::null();
-}
-
-void RawMirrorReference::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- if (kind == Snapshot::kMessage) {
- // We do not allow objects with native fields in an isolate message.
- writer->SetWriteException(Exceptions::kArgument,
- "Illegal argument in isolate message"
- " : (object is a MirrorReference)");
- } else {
- UNREACHABLE();
- }
-}
-
-RawUserTag* UserTag::ReadFrom(SnapshotReader* reader,
- intptr_t object_id,
- intptr_t tags,
- Snapshot::Kind kind,
- bool as_reference) {
- UNREACHABLE();
- return UserTag::null();
-}
-
-void RawUserTag::WriteTo(SnapshotWriter* writer,
- intptr_t object_id,
- Snapshot::Kind kind,
- bool as_reference) {
- if (kind == Snapshot::kMessage) {
- // We do not allow objects with native fields in an isolate message.
- writer->SetWriteException(Exceptions::kArgument,
- "Illegal argument in isolate message"
- " : (object is a UserTag)");
- } else {
- UNREACHABLE();
- }
-}
-
} // namespace dart
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 674623b..e997516 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -356,7 +356,7 @@
TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
const TypeArguments& function_type_arguments =
TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
- ASSERT(!type.IsNull() && !type.IsInstantiated());
+ ASSERT(!type.IsNull());
ASSERT(instantiator_type_arguments.IsNull() ||
instantiator_type_arguments.IsInstantiated());
ASSERT(function_type_arguments.IsNull() ||
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 0939635e..5f6c929 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -5,6 +5,9 @@
#ifndef RUNTIME_VM_SNAPSHOT_H_
#define RUNTIME_VM_SNAPSHOT_H_
+#include <memory>
+#include <utility>
+
#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/bitfield.h"
@@ -700,6 +703,7 @@
friend class RawClosureData;
friend class RawCode;
friend class RawContextScope;
+ friend class RawDynamicLibrary;
friend class RawExceptionHandlers;
friend class RawField;
friend class RawFunction;
@@ -711,6 +715,7 @@
friend class RawLocalVarDescriptors;
friend class RawMirrorReference;
friend class RawObjectPool;
+ friend class RawPointer;
friend class RawReceivePort;
friend class RawRegExp;
friend class RawScript;
@@ -718,10 +723,10 @@
friend class RawSubtypeTestCache;
friend class RawTransferableTypedData;
friend class RawType;
- friend class RawTypedDataView;
- friend class RawTypeRef;
friend class RawTypeArguments;
friend class RawTypeParameter;
+ friend class RawTypeRef;
+ friend class RawTypedDataView;
friend class RawUserTag;
friend class SnapshotWriterVisitor;
friend class WriteInlinedObjectVisitor;
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index f8b93b3..b17870e 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -18,8 +18,6 @@
// One-character symbols are added implicitly.
#define PREDEFINED_SYMBOLS_LIST(V) \
V(AbstractClassInstantiationError, "AbstractClassInstantiationError") \
- V(AddError, "addError") \
- V(AddStream, "addStream") \
V(AllocateInvocationMirror, "_allocateInvocationMirror") \
V(AllocateInvocationMirrorForClosure, "_allocateInvocationMirrorForClosure") \
V(AnonymousClosure, "<anonymous closure>") \
@@ -29,26 +27,12 @@
V(ArgumentError, "ArgumentError") \
V(AssertionError, "_AssertionError") \
V(AssignIndexToken, "[]=") \
- V(Async, "async") \
- V(AsyncAwaitHelper, "_awaitHelper") \
- V(AsyncCatchErrorCallback, ":async_op_catch_error") \
- V(AsyncCatchHelper, "_asyncCatchHelper") \
V(AsyncCompleter, ":async_completer") \
- V(AsyncErrorWrapperHelper, "_asyncErrorWrapperHelper") \
V(AsyncOperation, ":async_op") \
- V(AsyncOperationErrorParam, ":async_error_param") \
- V(AsyncOperationParam, ":async_result") \
- V(AsyncOperationStackTraceParam, ":async_stack_trace_param") \
- V(AsyncSavedTryCtxVarPrefix, ":async_saved_try_ctx_var_") \
- V(AsyncStackTraceHelper, "_asyncStackTraceHelper") \
V(AsyncStackTraceVar, ":async_stack_trace") \
V(AsyncStarMoveNextHelper, "_asyncStarMoveNextHelper") \
- V(AsyncThenCallback, ":async_op_then") \
- V(AsyncThenWrapperHelper, "_asyncThenWrapperHelper") \
- V(Await, "await") \
V(AwaitContextVar, ":await_ctx_var") \
V(AwaitJumpVar, ":await_jump_var") \
- V(AwaitTempVarPrefix, ":await_temp_var_") \
V(Bool, "bool") \
V(BooleanExpression, "boolean expression") \
V(BoundsCheckForPartialInstantiation, "_boundsCheckForPartialInstantiation") \
@@ -62,18 +46,13 @@
V(Class, "Class") \
V(ClassID, "ClassID") \
V(ClearAsyncThreadStackTrace, "_clearAsyncThreadStackTrace") \
- V(Close, "close") \
V(ClosureData, "ClosureData") \
V(ClosureParameter, ":closure") \
V(Code, "Code") \
V(CodeSourceMap, "CodeSourceMap") \
- V(ColonController, ":controller") \
V(ColonMatcher, ":matcher") \
- V(ColonStream, ":stream") \
V(CommaSpace, ", ") \
V(Completer, "Completer") \
- V(CompleterComplete, "complete") \
- V(CompleterCompleteError, "completeError") \
V(CompleterFuture, "future") \
V(CompleterGetFuture, "get:future") \
V(CompleterSyncConstructor, "Completer.sync") \
@@ -94,7 +73,6 @@
V(DartFfiLibName, "ffi") \
V(DartIOLibName, "dart.io") \
V(DartInternal, "dart:_internal") \
- V(DartInternalPackage, "package:dart_internal/") \
V(DartIsVM, "dart.isVM") \
V(DartIsolate, "dart:isolate") \
V(DartLibrary, "dart.library.") \
@@ -112,7 +90,6 @@
V(DebugProcedureName, ":Eval") \
V(Default, "Default") \
V(DefaultLabel, ":L") \
- V(DeoptInfo, "DeoptInfo") \
V(DotCreate, "._create") \
V(DotRange, ".range") \
V(DotValue, ".value") \
@@ -159,7 +136,6 @@
V(Float64List, "Float64List") \
V(Float64x2, "Float64x2") \
V(Float64x2List, "Float64x2List") \
- V(ForInIter, ":for-in-iter") \
V(FormatException, "FormatException") \
V(ForwardingCorpse, "ForwardingCorpse") \
V(FreeListElement, "FreeListElement") \
@@ -181,12 +157,10 @@
V(GrowRegExpStack, "_growRegExpStack") \
V(HandleExposedException, "_handleExposedException") \
V(HaveSameRuntimeType, "_haveSameRuntimeType") \
- V(Hide, "hide") \
V(ICData, "ICData") \
V(Identical, "identical") \
V(ImmutableMap, "_ImmutableMap") \
V(ImmutableMapConstructor, "_ImmutableMap._create") \
- V(ImplicitClosure, "<implicit closure>") \
V(InTypeCast, " in type cast") \
V(Index, "index") \
V(IndexToken, "[]") \
@@ -216,7 +190,6 @@
V(LibraryPrefix, "LibraryPrefix") \
V(List, "List") \
V(ListFactory, "List.") \
- V(ListLiteralElement, "list literal element") \
V(ListLiteralFactory, "List._fromLiteral") \
V(LoadLibrary, "loadLibrary") \
V(LocalVarDescriptors, "LocalVarDescriptors") \
@@ -236,14 +209,13 @@
V(Number, "num") \
V(Object, "Object") \
V(ObjectPool, "ObjectPool") \
- V(Of, "of") \
- V(On, "on") \
V(OneByteString, "_OneByteString") \
V(OptimizedOut, "<optimized out>") \
V(OriginalParam, ":original:") \
V(Other, "other") \
V(OutOfMemoryError, "OutOfMemoryError") \
V(PackageScheme, "package:") \
+ V(ParameterTypeCheck, "ParameterTypeCheck") \
V(Patch, "patch") \
V(PatchClass, "PatchClass") \
V(PcDescriptors, "PcDescriptors") \
@@ -255,14 +227,11 @@
V(RedirectionData, "RedirectionData") \
V(RegExp, "RegExp") \
V(RightShiftOperator, ">>") \
- V(SavedExceptionVar, ":saved_exception_var") \
- V(SavedStackTraceVar, ":saved_stack_trace_var") \
V(SavedTryContextVar, ":saved_try_context_var") \
V(Script, "Script") \
V(Set, "set") \
V(SetAsyncThreadStackTrace, "_setAsyncThreadStackTrace") \
V(SetterPrefix, "set:") \
- V(Show, "show") \
V(SignatureData, "SignatureData") \
V(SingleTargetCache, "SingleTargetCache") \
V(SpaceExtendsSpace, " extends ") \
@@ -281,8 +250,6 @@
V(SwitchExpr, ":switch_expr") \
V(Symbol, "Symbol") \
V(SymbolCtor, "Symbol.") \
- V(Sync, "sync") \
- V(TempParam, ":temp_param") \
V(ThrowNew, "_throwNew") \
V(ThrowNewInvocation, "_throwNewInvocation") \
V(TopLevel, "::") \
@@ -290,7 +257,6 @@
V(TransferableTypedData, "TransferableTypedData") \
V(TryFinallyReturnValue, ":try_finally_return_value") \
V(TwoByteString, "_TwoByteString") \
- V(TwoNewlines, "\n\n") \
V(TwoSpaces, " ") \
V(Type, "Type") \
V(TypeArguments, "TypeArguments") \
@@ -451,7 +417,6 @@
V(_stackTrace, "_stackTrace") \
V(_state, "_state") \
V(_wordCharacterMap, "_wordCharacterMap") \
- V(_yieldEachIterable, "_yieldEachIterable") \
V(add, "add") \
V(capture_length, ":capture_length") \
V(capture_start_index, ":capture_start_index") \
@@ -484,8 +449,7 @@
V(vm_entry_point, "vm:entry-point") \
V(vm_exact_result_type, "vm:exact-result-type") \
V(vm_non_nullable_result_type, "vm:non-nullable-result-type") \
- V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn") \
- V(word_character_map, ":word_character_map")
+ V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn")
// Contains a list of frequently used strings in a canonicalized form. This
// list is kept in the vm_isolate in order to share the copy across isolates