Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: runtime/lib/mirrors.cc

Issue 1584223006: Remove signature classes from the VM. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: sync Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/lib/isolate.cc ('k') | runtime/lib/mirrors_impl.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "lib/mirrors.h" 5 #include "lib/mirrors.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bootstrap_natives.h" 8 #include "vm/bootstrap_natives.h"
9 #include "vm/class_finalizer.h" 9 #include "vm/class_finalizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 EnsureConstructorsAreCompiled(func); 132 EnsureConstructorsAreCompiled(func);
133 133
134 bool has_extra_parameter_info = true; 134 bool has_extra_parameter_info = true;
135 if (non_implicit_param_count == 0) { 135 if (non_implicit_param_count == 0) {
136 has_extra_parameter_info = false; 136 has_extra_parameter_info = false;
137 } 137 }
138 if (func.IsImplicitConstructor()) { 138 if (func.IsImplicitConstructor()) {
139 // This covers the default constructor and forwarding constructors. 139 // This covers the default constructor and forwarding constructors.
140 has_extra_parameter_info = false; 140 has_extra_parameter_info = false;
141 } 141 }
142 if (func.IsSignatureFunction() &&
143 (func.token_pos() == Token::kNoSourcePos)) {
144 // Signature functions (except those describing typedefs) get canonicalized,
145 // hence do not have a token position, and therefore cannot be reparsed.
146 has_extra_parameter_info = false;
147 }
142 148
143 Array& param_descriptor = Array::Handle(); 149 Array& param_descriptor = Array::Handle();
144 if (has_extra_parameter_info) { 150 if (has_extra_parameter_info) {
145 // Reparse the function for the following information: 151 // Reparse the function for the following information:
146 // * The default value of a parameter. 152 // * The default value of a parameter.
147 // * Whether a parameters has been deflared as final. 153 // * Whether a parameters has been declared as final.
148 // * Any metadata associated with the parameter. 154 // * Any metadata associated with the parameter.
149 const Object& result = 155 const Object& result =
150 Object::Handle(Parser::ParseFunctionParameters(func)); 156 Object::Handle(Parser::ParseFunctionParameters(func));
151 if (result.IsError()) { 157 if (result.IsError()) {
152 Exceptions::PropagateError(Error::Cast(result)); 158 Exceptions::PropagateError(Error::Cast(result));
153 UNREACHABLE(); 159 UNREACHABLE();
154 } 160 }
155 param_descriptor ^= result.raw(); 161 param_descriptor ^= result.raw();
156 ASSERT(param_descriptor.Length() == 162 ASSERT(param_descriptor.Length() ==
157 (Parser::kParameterEntrySize * non_implicit_param_count)); 163 (Parser::kParameterEntrySize * non_implicit_param_count));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 236
231 237
232 static RawInstance* CreateTypedefMirror(const Class& cls, 238 static RawInstance* CreateTypedefMirror(const Class& cls,
233 const AbstractType& type, 239 const AbstractType& type,
234 const Bool& is_declaration, 240 const Bool& is_declaration,
235 const Instance& owner_mirror) { 241 const Instance& owner_mirror) {
236 const Array& args = Array::Handle(Array::New(6)); 242 const Array& args = Array::Handle(Array::New(6));
237 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); 243 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
238 args.SetAt(1, type); 244 args.SetAt(1, type);
239 args.SetAt(2, String::Handle(cls.Name())); 245 args.SetAt(2, String::Handle(cls.Name()));
240 args.SetAt(3, Bool::Get(cls.NumTypeParameters() != 0)); 246 args.SetAt(3, Bool::Get(cls.IsGeneric()));
241 args.SetAt(4, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration); 247 args.SetAt(4, cls.IsGeneric() ? is_declaration : Bool::False());
242 args.SetAt(5, owner_mirror); 248 args.SetAt(5, owner_mirror);
243 return CreateMirror(Symbols::_LocalTypedefMirror(), args); 249 return CreateMirror(Symbols::_LocalTypedefMirror(), args);
244 } 250 }
245 251
246 252
247 static RawInstance* CreateFunctionTypeMirror(const Class& cls, 253 static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) {
248 const AbstractType& type) { 254 ASSERT(type.IsFunctionType());
249 const Array& args = Array::Handle(Array::New(2)); 255 const Class& cls = Class::Handle(FunctionType::Cast(type).scope_class());
256 const Function& func = Function::Handle(FunctionType::Cast(type).signature());
257 const Array& args = Array::Handle(Array::New(3));
250 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); 258 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
251 args.SetAt(1, type); 259 args.SetAt(1, MirrorReference::Handle(MirrorReference::New(func)));
260 args.SetAt(2, type);
252 return CreateMirror(Symbols::_LocalFunctionTypeMirror(), args); 261 return CreateMirror(Symbols::_LocalFunctionTypeMirror(), args);
253 } 262 }
254 263
255 264
256 static RawInstance* CreateMethodMirror(const Function& func, 265 static RawInstance* CreateMethodMirror(const Function& func,
257 const Instance& owner_mirror, 266 const Instance& owner_mirror,
258 const AbstractType& instantiator) { 267 const AbstractType& instantiator) {
259 const Array& args = Array::Handle(Array::New(6)); 268 const Array& args = Array::Handle(Array::New(6));
260 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func))); 269 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func)));
261 270
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 args.SetAt(1, name); 306 args.SetAt(1, name);
298 args.SetAt(2, owner_mirror); 307 args.SetAt(2, owner_mirror);
299 args.SetAt(3, Object::null_instance()); // Null for type. 308 args.SetAt(3, Object::null_instance()); // Null for type.
300 args.SetAt(4, Bool::Get(field.is_static())); 309 args.SetAt(4, Bool::Get(field.is_static()));
301 args.SetAt(5, Bool::Get(field.is_final())); 310 args.SetAt(5, Bool::Get(field.is_final()));
302 args.SetAt(6, Bool::Get(field.is_const())); 311 args.SetAt(6, Bool::Get(field.is_const()));
303 312
304 return CreateMirror(Symbols::_LocalVariableMirror(), args); 313 return CreateMirror(Symbols::_LocalVariableMirror(), args);
305 } 314 }
306 315
307 static RawFunction* CallMethod(const Class& cls) {
308 if (cls.IsSignatureClass()) {
309 return cls.signature_function();
310 }
311
312 Class& lookup_cls = Class::Handle(cls.raw());
313 Function& call_function = Function::Handle();
314 do {
315 call_function = lookup_cls.LookupDynamicFunction(Symbols::Call());
316 if (!call_function.IsNull()) {
317 return call_function.raw();
318 }
319 lookup_cls = lookup_cls.SuperClass();
320 } while (!lookup_cls.IsNull());
321 return Function::null();
322 }
323 316
324 static RawInstance* CreateClassMirror(const Class& cls, 317 static RawInstance* CreateClassMirror(const Class& cls,
325 const AbstractType& type, 318 const AbstractType& type,
326 const Bool& is_declaration, 319 const Bool& is_declaration,
327 const Instance& owner_mirror) { 320 const Instance& owner_mirror) {
328 if (type.IsTypeRef()) { 321 if (type.IsTypeRef()) {
329 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type()); 322 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
330 ASSERT(!ref_type.IsTypeRef()); 323 ASSERT(!ref_type.IsTypeRef());
331 ASSERT(ref_type.IsCanonical()); 324 ASSERT(ref_type.IsCanonical());
332 return CreateClassMirror(cls, ref_type, is_declaration, owner_mirror); 325 return CreateClassMirror(cls, ref_type, is_declaration, owner_mirror);
333 } 326 }
334 ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass()); 327 ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass());
335 ASSERT(!type.IsNull()); 328 ASSERT(!type.IsNull());
336 ASSERT(type.IsFinalized()); 329 ASSERT(type.IsFinalized());
337 330
338 if (cls.IsSignatureClass()) { 331 if (cls.IsTypedefClass()) {
339 if (cls.IsCanonicalSignatureClass()) { 332 return CreateTypedefMirror(cls, type, is_declaration, owner_mirror);
340 // We represent function types as canonical signature classes.
341 return CreateFunctionTypeMirror(cls, type);
342 } else {
343 // We represent typedefs as non-canonical signature classes.
344 return CreateTypedefMirror(cls, type, is_declaration, owner_mirror);
345 }
346 } 333 }
347 334
348 const Error& error = Error::Handle(cls.EnsureIsFinalized(Thread::Current())); 335 const Error& error = Error::Handle(cls.EnsureIsFinalized(Thread::Current()));
349 if (!error.IsNull()) { 336 if (!error.IsNull()) {
350 Exceptions::PropagateError(error); 337 Exceptions::PropagateError(error);
351 UNREACHABLE(); 338 UNREACHABLE();
352 } 339 }
353 340
354 const Array& args = Array::Handle(Array::New(9)); 341 const Array& args = Array::Handle(Array::New(9));
355 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); 342 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 if (type.IsTypeRef()) { 534 if (type.IsTypeRef()) {
548 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type()); 535 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
549 ASSERT(!ref_type.IsTypeRef()); 536 ASSERT(!ref_type.IsTypeRef());
550 ASSERT(ref_type.IsCanonical()); 537 ASSERT(ref_type.IsCanonical());
551 return CreateTypeMirror(ref_type); 538 return CreateTypeMirror(ref_type);
552 } 539 }
553 ASSERT(type.IsFinalized()); 540 ASSERT(type.IsFinalized());
554 PROPAGATE_IF_MALFORMED(type); 541 PROPAGATE_IF_MALFORMED(type);
555 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType()); 542 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType());
556 543
544 if (type.IsFunctionType()) {
545 const Class& scope_class =
546 Class::Handle(FunctionType::Cast(type).scope_class());
547 if (scope_class.IsTypedefClass()) {
548 return CreateTypedefMirror(scope_class,
549 type, Bool::False(), Object::null_instance());
550 } else {
551 return CreateFunctionTypeMirror(type);
552 }
553 }
557 if (type.HasResolvedTypeClass()) { 554 if (type.HasResolvedTypeClass()) {
558 const Class& cls = Class::Handle(type.type_class()); 555 const Class& cls = Class::Handle(type.type_class());
559 // Handle void and dynamic types. 556 // Handle void and dynamic types.
560 if (cls.IsVoidClass()) { 557 if (cls.IsVoidClass()) {
561 Array& args = Array::Handle(Array::New(1)); 558 Array& args = Array::Handle(Array::New(1));
562 args.SetAt(0, Symbols::Void()); 559 args.SetAt(0, Symbols::Void());
563 return CreateMirror(Symbols::_SpecialTypeMirror(), args); 560 return CreateMirror(Symbols::_SpecialTypeMirror(), args);
564 } else if (cls.IsDynamicClass()) { 561 } else if (cls.IsDynamicClass()) {
565 Array& args = Array::Handle(Array::New(1)); 562 Array& args = Array::Handle(Array::New(1));
566 args.SetAt(0, Symbols::Dynamic()); 563 args.SetAt(0, Symbols::Dynamic());
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 return type.Canonicalize(); 775 return type.Canonicalize();
779 } 776 }
780 777
781 ASSERT(!instantiator.IsNull()); 778 ASSERT(!instantiator.IsNull());
782 ASSERT(instantiator.IsFinalized()); 779 ASSERT(instantiator.IsFinalized());
783 PROPAGATE_IF_MALFORMED(instantiator); 780 PROPAGATE_IF_MALFORMED(instantiator);
784 781
785 const TypeArguments& type_args = 782 const TypeArguments& type_args =
786 TypeArguments::Handle(instantiator.arguments()); 783 TypeArguments::Handle(instantiator.arguments());
787 Error& bound_error = Error::Handle(); 784 Error& bound_error = Error::Handle();
788 AbstractType& result = 785 AbstractType& result = AbstractType::Handle(
789 AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error)); 786 type.InstantiateFrom(type_args, &bound_error, NULL, Heap::kOld));
790 if (!bound_error.IsNull()) { 787 if (!bound_error.IsNull()) {
791 Exceptions::PropagateError(bound_error); 788 Exceptions::PropagateError(bound_error);
792 UNREACHABLE(); 789 UNREACHABLE();
793 } 790 }
794 ASSERT(result.IsFinalized()); 791 ASSERT(result.IsFinalized());
795 return result.Canonicalize(); 792 return result.Canonicalize();
796 } 793 }
797 794
798 795
799 DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0) { 796 DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0) {
(...skipping 21 matching lines...) Expand all
821 VerifyMethodKindShifts(); 818 VerifyMethodKindShifts();
822 819
823 return CreateIsolateMirror(); 820 return CreateIsolateMirror();
824 } 821 }
825 822
826 823
827 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { 824 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
828 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 825 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
829 PROPAGATE_IF_MALFORMED(type); 826 PROPAGATE_IF_MALFORMED(type);
830 ASSERT(type.IsFinalized()); 827 ASSERT(type.IsFinalized());
831 ASSERT(type.HasResolvedTypeClass()); 828 ASSERT(type.IsFunctionType() || type.HasResolvedTypeClass());
832 const Class& cls = Class::Handle(type.type_class()); 829 const Class& cls = Class::Handle(type.type_class());
833 ASSERT(!cls.IsNull()); 830 ASSERT(!cls.IsNull());
834 if (cls.IsDynamicClass() || 831 if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsTypedefClass()) {
835 cls.IsVoidClass() ||
836 (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) {
837 Exceptions::ThrowArgumentError(type); 832 Exceptions::ThrowArgumentError(type);
838 UNREACHABLE(); 833 UNREACHABLE();
839 } 834 }
840 return CreateClassMirror(cls, 835 return CreateClassMirror(cls,
841 AbstractType::Handle(cls.DeclarationType()), 836 AbstractType::Handle(cls.DeclarationType()),
842 Bool::True(), // is_declaration 837 Bool::True(), // is_declaration
843 Object::null_instance()); 838 Object::null_instance());
844 } 839 }
845 840
846 841
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 899 }
905 return metadata.raw(); 900 return metadata.raw();
906 } 901 }
907 902
908 903
909 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 2) { 904 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 2) {
910 GET_NON_NULL_NATIVE_ARGUMENT(Instance, 905 GET_NON_NULL_NATIVE_ARGUMENT(Instance,
911 owner_mirror, 906 owner_mirror,
912 arguments->NativeArgAt(0)); 907 arguments->NativeArgAt(0));
913 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); 908 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
914 const Class& cls = Class::Handle(ref.GetClassReferent()); 909 // TODO(rmacnak): Return get:call() method on class _Closure instead?
915 const Function& func = Function::Handle(CallMethod(cls)); 910 // This now returns the result of invoking that call getter.
911 const Function& func = Function::Handle(ref.GetFunctionReferent());
916 ASSERT(!func.IsNull()); 912 ASSERT(!func.IsNull());
917 return CreateMethodMirror(func, owner_mirror, AbstractType::Handle()); 913 return CreateMethodMirror(func, owner_mirror, AbstractType::Handle());
918 } 914 }
919 915
920 916
921 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 2) { 917 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 2) {
922 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); 918 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
923 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); 919 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
924 const Class& cls = Class::Handle(ref.GetClassReferent()); 920 const Function& func = Function::Handle(ref.GetFunctionReferent());
925 const Function& func = Function::Handle(cls.signature_function());
926 return CreateParameterMirrorList(func, owner); 921 return CreateParameterMirrorList(func, owner);
927 } 922 }
928 923
929 924
930 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 2) { 925 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 2) {
931 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 926 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
932 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, 927 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType,
933 instantiator, 928 instantiator,
934 arguments->NativeArgAt(1)); 929 arguments->NativeArgAt(1));
935 const Class& cls = Class::Handle(ref.GetClassReferent()); 930 const Function& func = Function::Handle(ref.GetFunctionReferent());
936 const Function& func = Function::Handle(CallMethod(cls));
937 ASSERT(!func.IsNull()); 931 ASSERT(!func.IsNull());
938 AbstractType& type = AbstractType::Handle(func.result_type()); 932 AbstractType& type = AbstractType::Handle(func.result_type());
939 return InstantiateType(type, instantiator); 933 return InstantiateType(type, instantiator);
940 } 934 }
941 935
942 936
943 DEFINE_NATIVE_ENTRY(ClassMirror_libraryUri, 1) { 937 DEFINE_NATIVE_ENTRY(ClassMirror_libraryUri, 1) {
944 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 938 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
945 const Class& klass = Class::Handle(ref.GetClassReferent()); 939 const Class& klass = Class::Handle(ref.GetClassReferent());
946 const Library& library = Library::Handle(klass.library()); 940 const Library& library = Library::Handle(klass.library());
947 ASSERT(!library.IsNull()); 941 ASSERT(!library.IsNull());
948 return library.url(); 942 return library.url();
949 } 943 }
950 944
951 945
952 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { 946 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) {
953 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 947 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
954 PROPAGATE_IF_MALFORMED(type); 948 PROPAGATE_IF_MALFORMED(type);
955 ASSERT(type.IsFinalized()); 949 ASSERT(type.IsFinalized());
956 if (!type.HasResolvedTypeClass()) {
957 Exceptions::ThrowArgumentError(type);
958 UNREACHABLE();
959 }
960 const Class& cls = Class::Handle(type.type_class()); 950 const Class& cls = Class::Handle(type.type_class());
961 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); 951 const AbstractType& super_type = AbstractType::Handle(cls.super_type());
962 ASSERT(super_type.IsNull() || super_type.IsFinalized()); 952 ASSERT(super_type.IsNull() || super_type.IsFinalized());
963 return super_type.raw(); 953 return super_type.raw();
964 } 954 }
965 955
966 956
967 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { 957 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) {
968 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 958 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
969 PROPAGATE_IF_MALFORMED(type); 959 PROPAGATE_IF_MALFORMED(type);
970 ASSERT(type.IsFinalized()); 960 ASSERT(type.IsFinalized());
971 if (!type.HasResolvedTypeClass()) {
972 Exceptions::ThrowArgumentError(type);
973 UNREACHABLE();
974 }
975 const Class& cls = Class::Handle(type.type_class()); 961 const Class& cls = Class::Handle(type.type_class());
976 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); 962 const AbstractType& super_type = AbstractType::Handle(cls.super_type());
977 return InstantiateType(super_type, type); 963 return InstantiateType(super_type, type);
978 } 964 }
979 965
980 966
981 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) { 967 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) {
982 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 968 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
983 PROPAGATE_IF_MALFORMED(type); 969 PROPAGATE_IF_MALFORMED(type);
984 ASSERT(type.IsFinalized()); 970 ASSERT(type.IsFinalized());
985 if (!type.HasResolvedTypeClass()) {
986 Exceptions::ThrowArgumentError(type);
987 UNREACHABLE();
988 }
989 const Class& cls = Class::Handle(type.type_class()); 971 const Class& cls = Class::Handle(type.type_class());
990 const Error& error = Error::Handle(cls.EnsureIsFinalized(thread)); 972 const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
991 if (!error.IsNull()) { 973 if (!error.IsNull()) {
992 Exceptions::PropagateError(error); 974 Exceptions::PropagateError(error);
993 } 975 }
994 976
995 return cls.interfaces(); 977 return cls.interfaces();
996 } 978 }
997 979
998 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) { 980 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) {
999 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 981 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
1000 PROPAGATE_IF_MALFORMED(type); 982 PROPAGATE_IF_MALFORMED(type);
1001 ASSERT(type.IsFinalized()); 983 ASSERT(type.IsFinalized());
1002 if (!type.HasResolvedTypeClass()) {
1003 Exceptions::ThrowArgumentError(type);
1004 UNREACHABLE();
1005 }
1006 const Class& cls = Class::Handle(type.type_class()); 984 const Class& cls = Class::Handle(type.type_class());
1007 const Error& error = Error::Handle(cls.EnsureIsFinalized(thread)); 985 const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
1008 if (!error.IsNull()) { 986 if (!error.IsNull()) {
1009 Exceptions::PropagateError(error); 987 Exceptions::PropagateError(error);
1010 } 988 }
1011 989
1012 Array& interfaces = Array::Handle(cls.interfaces()); 990 Array& interfaces = Array::Handle(cls.interfaces());
1013 Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length())); 991 Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length()));
1014 AbstractType& interface = AbstractType::Handle(); 992 AbstractType& interface = AbstractType::Handle();
1015 993
1016 for (int i = 0; i < interfaces.Length(); i++) { 994 for (int i = 0; i < interfaces.Length(); i++) {
1017 interface ^= interfaces.At(i); 995 interface ^= interfaces.At(i);
1018 interface = InstantiateType(interface, type); 996 interface = InstantiateType(interface, type);
1019 interfaces_inst.SetAt(i, interface); 997 interfaces_inst.SetAt(i, interface);
1020 } 998 }
1021 999
1022 return interfaces_inst.raw(); 1000 return interfaces_inst.raw();
1023 } 1001 }
1024 1002
1025 1003
1026 DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) { 1004 DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) {
1027 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 1005 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
1028 PROPAGATE_IF_MALFORMED(type); 1006 PROPAGATE_IF_MALFORMED(type);
1029 ASSERT(type.IsFinalized()); 1007 ASSERT(type.IsFinalized());
1030 if (!type.HasResolvedTypeClass()) {
1031 Exceptions::ThrowArgumentError(type);
1032 UNREACHABLE();
1033 }
1034 const Class& cls = Class::Handle(type.type_class()); 1008 const Class& cls = Class::Handle(type.type_class());
1035 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); 1009 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
1036 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized()); 1010 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized());
1037 return mixin_type.raw(); 1011 return mixin_type.raw();
1038 } 1012 }
1039 1013
1040 1014
1041 DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) { 1015 DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) {
1042 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 1016 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
1043 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, 1017 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType,
1044 instantiator, 1018 instantiator,
1045 arguments->NativeArgAt(1)); 1019 arguments->NativeArgAt(1));
1046 PROPAGATE_IF_MALFORMED(type); 1020 PROPAGATE_IF_MALFORMED(type);
1047 ASSERT(type.IsFinalized()); 1021 ASSERT(type.IsFinalized());
1048 if (!type.HasResolvedTypeClass()) {
1049 Exceptions::ThrowArgumentError(type);
1050 UNREACHABLE();
1051 }
1052 const Class& cls = Class::Handle(type.type_class()); 1022 const Class& cls = Class::Handle(type.type_class());
1053 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); 1023 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
1054 if (mixin_type.IsNull()) { 1024 if (mixin_type.IsNull()) {
1055 return mixin_type.raw(); 1025 return mixin_type.raw();
1056 } 1026 }
1057 1027
1058 return InstantiateType(mixin_type, instantiator); 1028 return InstantiateType(mixin_type, instantiator);
1059 } 1029 }
1060 1030
1061 1031
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 1129
1160 Object& entry = Object::Handle(); 1130 Object& entry = Object::Handle();
1161 DictionaryIterator entries(library); 1131 DictionaryIterator entries(library);
1162 1132
1163 AbstractType& type = AbstractType::Handle(); 1133 AbstractType& type = AbstractType::Handle();
1164 1134
1165 while (entries.HasNext()) { 1135 while (entries.HasNext()) {
1166 entry = entries.GetNext(); 1136 entry = entries.GetNext();
1167 if (entry.IsClass()) { 1137 if (entry.IsClass()) {
1168 const Class& klass = Class::Cast(entry); 1138 const Class& klass = Class::Cast(entry);
1169 // We filter out function signature classes and dynamic. 1139 // We filter out mixin application classes and dynamic.
1170 // TODO(12478): Should not need to filter out dynamic. 1140 // TODO(12478): Should not need to filter out dynamic.
1171 // Note that the VM does not consider mixin application aliases to be 1141 // Note that the VM does not consider mixin application aliases to be
1172 // mixin applications. 1142 // mixin applications.
1173 if (!klass.IsCanonicalSignatureClass() && 1143 if (!klass.IsDynamicClass() && !klass.IsMixinApplication()) {
1174 !klass.IsDynamicClass() &&
1175 !klass.IsMixinApplication()) {
1176 type = klass.DeclarationType(); 1144 type = klass.DeclarationType();
1177 member_mirror = CreateClassMirror(klass, 1145 member_mirror = CreateClassMirror(klass,
1178 type, 1146 type,
1179 Bool::True(), // is_declaration 1147 Bool::True(), // is_declaration
1180 owner_mirror); 1148 owner_mirror);
1181 member_mirrors.Add(member_mirror); 1149 member_mirrors.Add(member_mirror);
1182 } 1150 }
1183 } else if (entry.IsField()) { 1151 } else if (entry.IsField()) {
1184 const Field& field = Field::Cast(entry); 1152 const Field& field = Field::Cast(entry);
1185 if (field.is_reflectable()) { 1153 if (field.is_reflectable()) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 Array::empty_array())); 1268 Array::empty_array()));
1301 if (result.IsError()) { 1269 if (result.IsError()) {
1302 Exceptions::PropagateError(Error::Cast(result)); 1270 Exceptions::PropagateError(Error::Cast(result));
1303 UNREACHABLE(); 1271 UNREACHABLE();
1304 } 1272 }
1305 1273
1306 // Because we currently only use this native for building field extractors and 1274 // Because we currently only use this native for building field extractors and
1307 // setters, assume the result is a closure and mark its function as invisible, 1275 // setters, assume the result is a closure and mark its function as invisible,
1308 // so it will not appear in stack traces. Whenever we support 1276 // so it will not appear in stack traces. Whenever we support
1309 // ObjectMirror.evaluate this will need to be separated. 1277 // ObjectMirror.evaluate this will need to be separated.
1310 ASSERT(Instance::Cast(result).IsClosure()); 1278 ASSERT(result.IsClosure());
1311 const Function& func = 1279 const Function& func = Function::Handle(Closure::Cast(result).function());
1312 Function::Handle(Closure::function(Instance::Cast(result)));
1313 func.set_is_visible(false); 1280 func.set_is_visible(false);
1314 func.set_is_debuggable(false); 1281 func.set_is_debuggable(false);
1315 1282
1316 return result.raw(); 1283 return result.raw();
1317 } 1284 }
1318 1285
1319 DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) { 1286 DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) {
1320 GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); 1287 GET_NON_NULL_NATIVE_ARGUMENT(FunctionType, type, arguments->NativeArgAt(0));
1321 const Class& cls = Class::Handle(type.type_class()); 1288 const Class& cls = Class::Handle(type.scope_class());
1322 // We represent typedefs as non-canonical signature classes. 1289 ASSERT(cls.IsTypedefClass());
1323 ASSERT(cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass());
1324 return CreateTypedefMirror(cls, 1290 return CreateTypedefMirror(cls,
1325 AbstractType::Handle(cls.DeclarationType()), 1291 AbstractType::Handle(cls.DeclarationType()),
1326 Bool::True(), // is_declaration 1292 Bool::True(), // is_declaration
1327 Object::null_instance()); 1293 Object::null_instance());
1328 } 1294 }
1329 1295
1330 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) { 1296 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) {
1331 // Argument 0 is the mirror, which is unused by the native. It exists 1297 // Argument 0 is the mirror, which is unused by the native. It exists
1332 // because this native is an instance method in order to be polymorphic 1298 // because this native is an instance method in order to be polymorphic
1333 // with its cousins. 1299 // with its cousins.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 return InvokeDynamicFunction(reflectee, 1413 return InvokeDynamicFunction(reflectee,
1448 setter, 1414 setter,
1449 internal_setter_name, 1415 internal_setter_name,
1450 args, 1416 args,
1451 args_descriptor); 1417 args_descriptor);
1452 } 1418 }
1453 1419
1454 1420
1455 DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 1) { 1421 DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 1) {
1456 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); 1422 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
1457 const Type& type = Type::Handle(instance.GetType()); 1423 const AbstractType& type = AbstractType::Handle(instance.GetType());
1458 // The static type of null is specified to be the bottom type, however, the 1424 // The static type of null is specified to be the bottom type, however, the
1459 // runtime type of null is the Null type, which we correctly return here. 1425 // runtime type of null is the Null type, which we correctly return here.
1460 return type.Canonicalize(); 1426 return type.Canonicalize();
1461 } 1427 }
1462 1428
1463 1429
1464 DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) { 1430 DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) {
1465 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); 1431 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
1466 ASSERT(!closure.IsNull()); 1432 ASSERT(!closure.IsNull());
1467 1433
1468 Function& function = Function::Handle(); 1434 Function& function = Function::Handle();
1469 bool callable = closure.IsCallable(&function); 1435 bool callable = closure.IsCallable(&function);
1470 if (callable) { 1436 if (callable) {
1471 if (function.IsImplicitClosureFunction()) { 1437 if (function.IsImplicitClosureFunction()) {
1472 // The VM uses separate Functions for tear-offs, but the mirrors consider 1438 // The VM uses separate Functions for tear-offs, but the mirrors consider
1473 // the tear-offs to be the same as the torn-off methods. Avoid handing out 1439 // the tear-offs to be the same as the torn-off methods. Avoid handing out
1474 // a reference to the tear-off here to avoid a special case in the 1440 // a reference to the tear-off here to avoid a special case in the
1475 // the equality test. 1441 // the equality test.
1476 function = function.parent_function(); 1442 function = function.parent_function();
1477 } 1443 }
1478 1444
1479 Type& instantiator = Type::Handle(); 1445 Type& instantiator = Type::Handle();
1480 if (closure.IsClosure()) { 1446 if (closure.IsClosure()) {
1481 const TypeArguments& arguments = 1447 const TypeArguments& arguments =
1482 TypeArguments::Handle(Closure::GetTypeArguments(closure)); 1448 TypeArguments::Handle(closure.GetTypeArguments());
1483 const Class& cls = 1449 const Class& cls =
1484 Class::Handle(Isolate::Current()->object_store()->object_class()); 1450 Class::Handle(Isolate::Current()->object_store()->object_class());
1485 instantiator = Type::New(cls, arguments, Token::kNoSourcePos); 1451 instantiator = Type::New(cls, arguments, Token::kNoSourcePos);
1486 instantiator.SetIsFinalized(); 1452 instantiator.SetIsFinalized();
1487 } 1453 }
1488 return CreateMethodMirror(function, 1454 return CreateMethodMirror(function,
1489 Instance::null_instance(), 1455 Instance::null_instance(),
1490 instantiator); 1456 instantiator);
1491 } 1457 }
1492 return Instance::null(); 1458 return Instance::null();
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 Class& redirected_klass = Class::Handle(klass.raw()); 1667 Class& redirected_klass = Class::Handle(klass.raw());
1702 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); 1668 Function& redirected_constructor = Function::Handle(lookup_constructor.raw());
1703 if (lookup_constructor.IsRedirectingFactory()) { 1669 if (lookup_constructor.IsRedirectingFactory()) {
1704 ClassFinalizer::ResolveRedirectingFactory(klass, lookup_constructor); 1670 ClassFinalizer::ResolveRedirectingFactory(klass, lookup_constructor);
1705 Type& redirect_type = Type::Handle(lookup_constructor.RedirectionType()); 1671 Type& redirect_type = Type::Handle(lookup_constructor.RedirectionType());
1706 1672
1707 if (!redirect_type.IsInstantiated()) { 1673 if (!redirect_type.IsInstantiated()) {
1708 // The type arguments of the redirection type are instantiated from the 1674 // The type arguments of the redirection type are instantiated from the
1709 // type arguments of the type reflected by the class mirror. 1675 // type arguments of the type reflected by the class mirror.
1710 Error& bound_error = Error::Handle(); 1676 Error& bound_error = Error::Handle();
1711 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, 1677 redirect_type ^= redirect_type.InstantiateFrom(
1712 &bound_error); 1678 type_arguments, &bound_error, NULL, Heap::kOld);
1713 if (!bound_error.IsNull()) { 1679 if (!bound_error.IsNull()) {
1714 Exceptions::PropagateError(bound_error); 1680 Exceptions::PropagateError(bound_error);
1715 UNREACHABLE(); 1681 UNREACHABLE();
1716 } 1682 }
1717 redirect_type ^= redirect_type.Canonicalize(); 1683 redirect_type ^= redirect_type.Canonicalize();
1718 } 1684 }
1719 1685
1720 type = redirect_type.raw(); 1686 type = redirect_type.raw();
1721 type_arguments = redirect_type.arguments(); 1687 type_arguments = redirect_type.arguments();
1722 1688
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 if (decl.IsFunction()) { 1974 if (decl.IsFunction()) {
2009 const Function& func = Function::Cast(decl); 1975 const Function& func = Function::Cast(decl);
2010 if (func.IsImplicitConstructor() || func.IsSignatureFunction()) { 1976 if (func.IsImplicitConstructor() || func.IsSignatureFunction()) {
2011 // These are synthetic methods; they have no source. 1977 // These are synthetic methods; they have no source.
2012 return Instance::null(); 1978 return Instance::null();
2013 } 1979 }
2014 script = func.script(); 1980 script = func.script();
2015 token_pos = func.token_pos(); 1981 token_pos = func.token_pos();
2016 } else if (decl.IsClass()) { 1982 } else if (decl.IsClass()) {
2017 const Class& cls = Class::Cast(decl); 1983 const Class& cls = Class::Cast(decl);
2018 const bool is_typedef = cls.IsSignatureClass() && 1984 const bool is_typedef = cls.IsTypedefClass();
2019 !cls.IsCanonicalSignatureClass();
2020 if (cls.is_synthesized_class() && 1985 if (cls.is_synthesized_class() &&
2021 !is_typedef && 1986 !is_typedef &&
2022 !cls.is_mixin_app_alias() && 1987 !cls.is_mixin_app_alias() &&
2023 !cls.is_enum_class()) { 1988 !cls.is_enum_class()) {
2024 return Instance::null(); // Synthetic. 1989 return Instance::null(); // Synthetic.
2025 } 1990 }
2026 script = cls.script(); 1991 script = cls.script();
2027 token_pos = cls.token_pos(); 1992 token_pos = cls.token_pos();
2028 } else if (decl.IsField()) { 1993 } else if (decl.IsField()) {
2029 const Field& field = Field::Cast(decl); 1994 const Field& field = Field::Cast(decl);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 // information is not available. 2035 // information is not available.
2071 script.GetTokenLocation(token_pos, &from_line, NULL); 2036 script.GetTokenLocation(token_pos, &from_line, NULL);
2072 } 2037 }
2073 // We should always have at least the line number. 2038 // We should always have at least the line number.
2074 ASSERT(from_line != 0); 2039 ASSERT(from_line != 0);
2075 return CreateSourceLocation(uri, from_line, from_col); 2040 return CreateSourceLocation(uri, from_line, from_col);
2076 } 2041 }
2077 2042
2078 2043
2079 DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) { 2044 DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) {
2080 GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); 2045 GET_NON_NULL_NATIVE_ARGUMENT(FunctionType, type, arguments->NativeArgAt(0));
2081 const Class& cls = Class::Handle(type.type_class()); 2046 const Class& cls = Class::Handle(type.scope_class());
2047 ASSERT(cls.IsTypedefClass());
2082 const Function& sig_func = Function::Handle(cls.signature_function()); 2048 const Function& sig_func = Function::Handle(cls.signature_function());
2083 const Class& sig_cls = Class::Handle(sig_func.signature_class()); 2049 FunctionType& referent_type = FunctionType::Handle(sig_func.SignatureType());
2084 2050 // If the scope class of the function type is not generic, replace it with
2085 AbstractType& referent_type = AbstractType::Handle(sig_cls.DeclarationType()); 2051 // Closure class (Function::SignatureType() keeps it).
2086 referent_type = InstantiateType(referent_type, type); 2052 ASSERT(cls.raw() == referent_type.scope_class());
2087 2053 if (!cls.IsGeneric()) {
2088 return CreateFunctionTypeMirror(sig_cls, referent_type); 2054 referent_type = FunctionType::New(
2055 Class::Handle(Isolate::Current()->object_store()->closure_class()),
2056 TypeArguments::Handle(referent_type.arguments()),
2057 sig_func,
2058 referent_type.token_pos());
2059 referent_type ^= ClassFinalizer::FinalizeType(
2060 cls, referent_type, ClassFinalizer::kCanonicalize);
2061 }
2062 referent_type ^= InstantiateType(referent_type, type);
2063 return CreateFunctionTypeMirror(referent_type);
2089 } 2064 }
2090 2065
2091 2066
2092 DEFINE_NATIVE_ENTRY(ParameterMirror_type, 3) { 2067 DEFINE_NATIVE_ENTRY(ParameterMirror_type, 3) {
2093 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 2068 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
2094 GET_NON_NULL_NATIVE_ARGUMENT(Smi, pos, arguments->NativeArgAt(1)); 2069 GET_NON_NULL_NATIVE_ARGUMENT(Smi, pos, arguments->NativeArgAt(1));
2095 GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(2)); 2070 GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(2));
2096 const Function& func = Function::Handle(ref.GetFunctionReferent()); 2071 const Function& func = Function::Handle(ref.GetFunctionReferent());
2097 const AbstractType& type = AbstractType::Handle( 2072 const AbstractType& type = AbstractType::Handle(
2098 func.ParameterTypeAt(func.NumImplicitParameters() + pos.Value())); 2073 func.ParameterTypeAt(func.NumImplicitParameters() + pos.Value()));
(...skipping 10 matching lines...) Expand all
2109 } 2084 }
2110 2085
2111 DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 2) { 2086 DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 2) {
2112 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); 2087 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0));
2113 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); 2088 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1));
2114 return Bool::Get(a.IsSubtypeOf(b, NULL)).raw(); 2089 return Bool::Get(a.IsSubtypeOf(b, NULL)).raw();
2115 } 2090 }
2116 2091
2117 2092
2118 } // namespace dart 2093 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/isolate.cc ('k') | runtime/lib/mirrors_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698