00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "arch.h"
00048 ARCH_COPYRIGHT_APACHE(linkage, c, "$URL: https://svn.apache.org/path/name/linkage.c $ $Id: linkage.c 0 09/28/2005 dlydick $");
00049
00050 #include "jvmcfg.h"
00051 #include "cfmacros.h"
00052 #include "classfile.h"
00053 #include "attribute.h"
00054 #include "exit.h"
00055 #include "field.h"
00056 #include "gc.h"
00057 #include "jvm.h"
00058 #include "jvmclass.h"
00059 #include "linkage.h"
00060 #include "method.h"
00061 #include "native.h"
00062 #include "util.h"
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 rboolean linkage_resolve_class(jvm_class_index clsidx,
00092 rboolean find_registerNatives)
00093 {
00094 if (jvm_class_index_null == clsidx)
00095 {
00096
00097
00098
00099
00100 return(rfalse);
00101 }
00102
00103
00104 if (!(CLASS_STATUS_INUSE & CLASS(clsidx).status))
00105 {
00106 return(rfalse);
00107 }
00108
00109
00110 if (CLASS_STATUS_LINKED & CLASS(clsidx).status)
00111 {
00112 return(rtrue);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 rboolean class_fully_linked = rtrue;
00125
00126
00127
00128
00129
00130
00131 ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00132
00133 jvm_constant_pool_index cpidx;
00134 for (cpidx = CONSTANT_CP_START_INDEX;
00135 cpidx < pcfs->constant_pool_count + CONSTANT_CP_START_INDEX -1;
00136 cpidx++)
00137 {
00138 jvm_class_index clsidxFIND;
00139 jvm_field_index fldidxFIND;
00140 jvm_field_lookup_index fluidxFIND;
00141
00142 jvm_method_index mthidxFIND;
00143 jvm_attribute_index atridxFIND;
00144
00145 cp_info_dup *pcpd = pcfs->constant_pool[cpidx];
00146
00147 CONSTANT_Class_info *pcpd_Class;
00148 CONSTANT_Fieldref_info *pcpd_Fieldref;
00149 CONSTANT_Methodref_info *pcpd_Methodref;
00150 CONSTANT_InterfaceMethodref_info *pcpd_InterfaceMethodref;
00151 CONSTANT_NameAndType_info *pcpd_NameAndType;
00152
00153 cp_info_dup *clsname;
00154
00155 switch (CP_TAG(pcfs, cpidx))
00156 {
00157 case CONSTANT_Class:
00158
00159 pcpd_Class = PTR_THIS_CP_Class(pcpd);
00160
00161
00162 if (jvm_class_index_null ==
00163 pcpd_Class->LOCAL_Class_binding.clsidxJVM)
00164 {
00165 clsname =
00166 pcfs->constant_pool[pcpd_Class->name_index];
00167
00168 clsidxFIND = class_find_by_cp_entry(clsname);
00169
00170 if (jvm_class_index_null == clsidxFIND)
00171 {
00172
00173 class_fully_linked = rfalse;
00174 }
00175 else
00176 {
00177 PTR_THIS_CP_Class(pcpd)
00178 ->LOCAL_Class_binding.clsidxJVM = clsidxFIND;
00179
00180
00181 if (clsidx != clsidxFIND)
00182 {
00183 (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00184 clsidx,
00185 clsidxFIND);
00186 }
00187 }
00188 }
00189 break;
00190
00191 case CONSTANT_Fieldref:
00192
00193 pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd);
00194
00195
00196 if (jvm_class_index_null ==
00197 pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM)
00198 {
00199 pcpd_Class =
00200 PTR_THIS_CP_Class(pcfs->constant_pool
00201 [pcpd_Fieldref->class_index]);
00202
00203 clsname =
00204 pcfs->constant_pool[pcpd_Class->name_index];
00205
00206 clsidxFIND = class_find_by_cp_entry(clsname);
00207
00208 pcpd_Fieldref
00209 ->LOCAL_Fieldref_binding.clsidxJVM = clsidxFIND;
00210
00211 if (jvm_class_index_null == clsidxFIND)
00212 {
00213
00214 class_fully_linked = rfalse;
00215 }
00216 else
00217 {
00218 pcpd_NameAndType =
00219 PTR_THIS_CP_NameAndType(
00220 pcfs->constant_pool
00221 [pcpd_Fieldref->name_and_type_index]);
00222
00223 fldidxFIND =
00224 field_find_by_cp_entry(
00225 clsidxFIND,
00226 pcfs->constant_pool
00227 [pcpd_NameAndType->name_index],
00228 pcfs->constant_pool
00229 [pcpd_NameAndType->descriptor_index]);
00230
00231 if (jvm_field_index_bad == fldidxFIND)
00232 {
00233
00234 exit_throw_exception(EXIT_JVM_CLASS,
00235 JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);
00236
00237 #if 0
00238 pcpd_Fieldref
00239 ->LOCAL_Fieldref_binding.fluidxJVM =
00240 jvm_field_lookup_index_bad;
00241
00242 pcpd_Fieldref
00243 ->LOCAL_Fieldref_binding.oiflagJVM =
00244 rneither_true_nor_false;
00245
00246 pcpd_Fieldref
00247 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00248 LOCAL_BASETYPE_ERROR;
00249
00250
00251 continue;
00252 #endif
00253 }
00254
00255
00256
00257
00258
00259 if (FIELD(clsidxFIND, fldidxFIND)
00260 ->access_flags & ACC_STATIC)
00261 {
00262 fluidxFIND =
00263 field_index_get_class_static_lookup(clsidxFIND, fldidxFIND);
00264
00265 }
00266 else
00267 {
00268 fluidxFIND =
00269 field_index_get_object_instance_lookup(clsidxFIND, fldidxFIND);
00270
00271 }
00272
00273 pcpd_Fieldref
00274 ->LOCAL_Fieldref_binding.fluidxJVM =
00275 fluidxFIND;
00276
00277 if (jvm_field_lookup_index_bad == fluidxFIND)
00278 {
00279
00280 exit_throw_exception(EXIT_JVM_CLASS,
00281 JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);
00282
00283
00284 pcpd_Fieldref
00285 ->LOCAL_Fieldref_binding.oiflagJVM =
00286 rneither_true_nor_false;
00287
00288 pcpd_Fieldref
00289 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00290 LOCAL_BASETYPE_ERROR;
00291
00292
00293
00294
00295
00296 continue;
00297 }
00298
00299 pcpd_Fieldref
00300 ->LOCAL_Fieldref_binding.oiflagJVM =
00301 (FIELD(clsidxFIND, fldidxFIND)
00302 ->access_flags & ACC_STATIC)
00303 ? rfalse
00304 : rtrue;
00305
00306 cp_info_dup *pfldesc_dup =
00307 CLASS_OBJECT_LINKAGE(clsidxFIND)
00308 ->pcfs
00309 ->constant_pool
00310 [FIELD(clsidxFIND, fldidxFIND)
00311 ->descriptor_index];
00312
00313 CONSTANT_Utf8_info *pfldesc =
00314 PTR_THIS_CP_Utf8(pfldesc_dup);
00315
00316
00317
00318
00319
00320
00321 pcpd_Fieldref
00322 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00323
00324 pfldesc->bytes[0];
00325
00326
00327 if (clsidx != clsidxFIND)
00328 {
00329 (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00330 clsidx,
00331 clsidxFIND);
00332 }
00333 }
00334 }
00335 break;
00336
00337 case CONSTANT_Methodref:
00338
00339 pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd);
00340
00341
00342 if (jvm_class_index_null ==
00343 pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM)
00344 {
00345 pcpd_Class =
00346 PTR_THIS_CP_Class(pcfs->constant_pool
00347 [pcpd_Methodref->class_index]);
00348
00349 clsname =
00350 pcfs->constant_pool[pcpd_Class->name_index];
00351
00352 clsidxFIND = class_find_by_cp_entry(clsname);
00353
00354 pcpd_Methodref
00355 ->LOCAL_Methodref_binding.clsidxJVM =clsidxFIND;
00356
00357 if (jvm_class_index_null == clsidxFIND)
00358 {
00359
00360 class_fully_linked = rfalse;
00361 }
00362 else
00363 {
00364 pcpd_NameAndType =
00365 PTR_THIS_CP_NameAndType(
00366 pcfs->constant_pool
00367 [pcpd_Methodref->name_and_type_index]);
00368
00369 mthidxFIND =
00370 method_find_by_cp_entry(
00371 clsidxFIND,
00372 pcfs->constant_pool
00373 [pcpd_NameAndType->name_index],
00374 pcfs->constant_pool
00375 [pcpd_NameAndType->descriptor_index]);
00376
00377 pcpd_Methodref
00378 ->LOCAL_Methodref_binding.mthidxJVM =
00379 mthidxFIND;
00380
00381 if (jvm_method_index_bad == mthidxFIND)
00382 {
00383
00384 exit_throw_exception(EXIT_JVM_CLASS,
00385 JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00386
00387 }
00388
00389
00390
00391
00392
00393
00394
00395 if (ACC_NATIVE &
00396 METHOD(clsidxFIND,mthidxFIND)->access_flags)
00397 {
00398 atridxFIND = jvm_attribute_index_native;
00399
00400 pcpd_Methodref
00401 ->LOCAL_Methodref_binding
00402 .nmordJVM =
00403 native_locate_local_method(
00404 pcfs,
00405 pcpd_Class->name_index,
00406 pcpd_NameAndType->name_index,
00407 pcpd_NameAndType
00408 ->descriptor_index,
00409 find_registerNatives);
00410 }
00411 else
00412 {
00413 atridxFIND =
00414 attribute_find_in_method_by_enum(
00415 clsidxFIND,
00416 mthidxFIND,
00417 LOCAL_CODE_ATTRIBUTE);
00418 }
00419
00420 pcpd_Methodref
00421 ->LOCAL_Methodref_binding.codeatridxJVM =
00422 atridxFIND;
00423
00424 if (jvm_attribute_index_bad == atridxFIND)
00425 {
00426
00427 exit_throw_exception(EXIT_JVM_ATTRIBUTE,
00428 JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00429
00430 }
00431
00432
00433
00434
00435
00436
00437 atridxFIND =
00438 attribute_find_in_method_by_enum(
00439 clsidxFIND,
00440 mthidxFIND,
00441 LOCAL_EXCEPTIONS_ATTRIBUTE);
00442
00443 pcpd_Methodref
00444 ->LOCAL_Methodref_binding.excpatridxJVM =
00445 atridxFIND;
00446
00447 if (jvm_attribute_index_bad == atridxFIND)
00448 {
00449
00450 }
00451
00452
00453 if (clsidx != clsidxFIND)
00454 {
00455 (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00456 clsidx,
00457 clsidxFIND);
00458 }
00459 }
00460 }
00461 break;
00462
00463 case CONSTANT_InterfaceMethodref:
00464
00465 pcpd_InterfaceMethodref =
00466 PTR_THIS_CP_InterfaceMethodref(pcpd);
00467
00468
00469 if (jvm_class_index_null ==
00470 pcpd_InterfaceMethodref
00471 ->LOCAL_InterfaceMethodref_binding.clsidxJVM)
00472 {
00473 pcpd_Class =
00474 PTR_THIS_CP_Class(pcfs->constant_pool
00475 [pcpd_InterfaceMethodref->class_index]);
00476 clsname =
00477 pcfs->constant_pool[pcpd_Class->name_index];
00478
00479 clsidxFIND = class_find_by_cp_entry(clsname);
00480
00481 pcpd_InterfaceMethodref
00482 ->LOCAL_InterfaceMethodref_binding.clsidxJVM =
00483 clsidxFIND;
00484
00485 if (jvm_class_index_null == clsidxFIND)
00486 {
00487
00488 class_fully_linked = rfalse;
00489 }
00490 else
00491 {
00492 pcpd_NameAndType =
00493 PTR_THIS_CP_NameAndType(
00494 pcfs->constant_pool
00495 [pcpd_InterfaceMethodref
00496 ->name_and_type_index]);
00497
00498 mthidxFIND =
00499 method_find_by_cp_entry(
00500 clsidxFIND,
00501 pcfs->constant_pool
00502 [pcpd_NameAndType->name_index],
00503 pcfs->constant_pool
00504 [pcpd_NameAndType->descriptor_index]);
00505
00506 pcpd_InterfaceMethodref
00507 ->LOCAL_InterfaceMethodref_binding
00508 .mthidxJVM =
00509 mthidxFIND;
00510
00511 if (jvm_method_index_bad == mthidxFIND)
00512 {
00513
00514 exit_throw_exception(EXIT_JVM_CLASS,
00515 JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00516
00517 }
00518
00519
00520
00521
00522
00523
00524
00525 if (ACC_NATIVE &
00526 METHOD(clsidxFIND,mthidxFIND)->access_flags)
00527 {
00528 atridxFIND = jvm_attribute_index_native;
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 pcpd_InterfaceMethodref
00541 ->LOCAL_InterfaceMethodref_binding
00542 .nmordJVM =
00543 native_locate_local_method(
00544 pcfs,
00545 pcpd_Class->name_index,
00546 pcpd_NameAndType->name_index,
00547 pcpd_NameAndType
00548 ->descriptor_index,
00549 find_registerNatives);
00550 }
00551 else
00552 {
00553 atridxFIND =
00554 attribute_find_in_method_by_enum(
00555 clsidxFIND,
00556 mthidxFIND,
00557 LOCAL_CODE_ATTRIBUTE);
00558 }
00559
00560 pcpd_InterfaceMethodref
00561 ->LOCAL_InterfaceMethodref_binding
00562 .codeatridxJVM =
00563 atridxFIND;
00564
00565 if (jvm_attribute_index_bad == atridxFIND)
00566 {
00567
00568 exit_throw_exception(EXIT_JVM_ATTRIBUTE,
00569 JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00570
00571 }
00572
00573
00574
00575
00576
00577
00578 atridxFIND =
00579 attribute_find_in_method_by_enum(
00580 clsidxFIND,
00581 mthidxFIND,
00582 LOCAL_EXCEPTIONS_ATTRIBUTE);
00583
00584 pcpd_InterfaceMethodref
00585 ->LOCAL_InterfaceMethodref_binding
00586 .excpatridxJVM =
00587 atridxFIND;
00588
00589 if (jvm_attribute_index_bad == atridxFIND)
00590 {
00591
00592 }
00593
00594
00595 if (clsidx != clsidxFIND)
00596 {
00597 (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00598 clsidx,
00599 clsidxFIND);
00600 }
00601 }
00602 }
00603 break;
00604
00605 case CONSTANT_String:
00606
00607 case CONSTANT_Integer:
00608
00609 case CONSTANT_Float:
00610
00611 case CONSTANT_Long:
00612
00613 case CONSTANT_Double:
00614
00615 case CONSTANT_NameAndType:
00616
00617 case CONSTANT_Utf8:
00618
00619
00620
00621
00622
00623
00624 break;
00625
00626 default:
00627 GENERIC_FAILURE1_VALUE(rtrue,
00628 DMLNORM,
00629 "linkage_resolve_class",
00630 "Invalid CP tag %d",
00631 CP_TAG(pcfs, cpidx),
00632 rfalse,
00633 rnull,
00634 rnull);
00635
00636 }
00637
00638 }
00639
00640
00641 if (rtrue == class_fully_linked)
00642 {
00643 CLASS(clsidx).status |= CLASS_STATUS_LINKED;
00644 }
00645
00646 cfmsgs_show_constant_pool(CLASS_OBJECT_LINKAGE(clsidx)->pcfs);
00647
00648 return(class_fully_linked);
00649
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 rboolean linkage_unresolve_class(jvm_class_index clsidx)
00668 {
00669 if (jvm_class_index_null == clsidx)
00670 {
00671
00672
00673
00674
00675 return(rfalse);
00676 }
00677
00678
00679 if (!(CLASS_STATUS_INUSE & CLASS(clsidx).status))
00680 {
00681 return(rfalse);
00682 }
00683
00684
00685 ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00686
00687
00688
00689
00690
00691 jvm_constant_pool_index cpidx;
00692 for (cpidx = CONSTANT_CP_START_INDEX;
00693 cpidx < pcfs->constant_pool_count + CONSTANT_CP_START_INDEX -1;
00694 cpidx++)
00695 {
00696 cp_info_dup *pcpd = pcfs->constant_pool[cpidx];
00697
00698 CONSTANT_Class_info *pcpd_Class;
00699 CONSTANT_Fieldref_info *pcpd_Fieldref;
00700 CONSTANT_Methodref_info *pcpd_Methodref;
00701 CONSTANT_InterfaceMethodref_info *pcpd_InterfaceMethodref;
00702
00703 switch (CP_TAG(pcfs, cpidx))
00704 {
00705 case CONSTANT_Class:
00706
00707 pcpd_Class = PTR_THIS_CP_Class(pcpd);
00708
00709
00710 if (jvm_class_index_null !=
00711 pcpd_Class->LOCAL_Class_binding.clsidxJVM)
00712 {
00713
00714 if (clsidx !=
00715 pcpd_Class->LOCAL_Class_binding.clsidxJVM)
00716 {
00717 (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00718 clsidx,
00719 pcpd_Class
00720 ->LOCAL_Class_binding
00721 .clsidxJVM);
00722 }
00723
00724 pcpd_Class->LOCAL_Class_binding.clsidxJVM =
00725 jvm_class_index_null;
00726 }
00727 break;
00728
00729 case CONSTANT_Fieldref:
00730
00731 pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd);
00732
00733
00734 if (jvm_class_index_null !=
00735 pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM)
00736 {
00737
00738 if (clsidx !=
00739 pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM)
00740 {
00741 (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00742 clsidx,
00743 pcpd_Fieldref
00744 ->LOCAL_Fieldref_binding
00745 .clsidxJVM);
00746 }
00747
00748 pcpd_Fieldref
00749 ->LOCAL_Fieldref_binding.clsidxJVM =
00750 jvm_class_index_null;
00751
00752 pcpd_Fieldref
00753 ->LOCAL_Fieldref_binding.fluidxJVM =
00754 jvm_field_lookup_index_bad;
00755
00756 pcpd_Fieldref
00757 ->LOCAL_Fieldref_binding.oiflagJVM =
00758 rneither_true_nor_false;
00759
00760 pcpd_Fieldref
00761 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00762 LOCAL_BASETYPE_ERROR;
00763 }
00764 break;
00765
00766 case CONSTANT_Methodref:
00767
00768 pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd);
00769
00770
00771 if (jvm_class_index_null !=
00772 pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM)
00773 {
00774
00775 if (clsidx !=
00776 pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM)
00777 {
00778 (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00779 clsidx,
00780 pcpd_Methodref
00781 ->LOCAL_Methodref_binding
00782 .clsidxJVM);
00783 }
00784
00785 pcpd_Methodref
00786 ->LOCAL_Methodref_binding.clsidxJVM =
00787 jvm_class_index_null;
00788
00789 pcpd_Methodref
00790 ->LOCAL_Methodref_binding.mthidxJVM =
00791 jvm_method_index_bad;
00792
00793 pcpd_Methodref
00794 ->LOCAL_Methodref_binding.codeatridxJVM =
00795 jvm_attribute_index_bad;
00796
00797 pcpd_Methodref
00798 ->LOCAL_Methodref_binding.excpatridxJVM =
00799 jvm_attribute_index_bad;
00800
00801 pcpd_Methodref
00802 ->LOCAL_Methodref_binding.nmordJVM =
00803 jvm_native_method_ordinal_null;
00804 }
00805 break;
00806
00807 case CONSTANT_InterfaceMethodref:
00808
00809 pcpd_InterfaceMethodref =
00810 PTR_THIS_CP_InterfaceMethodref(pcpd);
00811
00812
00813 if (jvm_class_index_null !=
00814 pcpd_InterfaceMethodref
00815 ->LOCAL_InterfaceMethodref_binding.clsidxJVM)
00816 {
00817
00818 if (clsidx !=
00819 pcpd_InterfaceMethodref
00820 ->LOCAL_InterfaceMethodref_binding.clsidxJVM)
00821 {
00822 (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00823 clsidx,
00824 pcpd_InterfaceMethodref
00825 ->LOCAL_InterfaceMethodref_binding
00826 .clsidxJVM);
00827 }
00828
00829 pcpd_InterfaceMethodref
00830 ->LOCAL_InterfaceMethodref_binding.clsidxJVM =
00831 jvm_class_index_null;
00832
00833 pcpd_InterfaceMethodref
00834 ->LOCAL_InterfaceMethodref_binding.mthidxJVM =
00835 jvm_method_index_bad;
00836
00837 pcpd_InterfaceMethodref
00838 ->LOCAL_InterfaceMethodref_binding.codeatridxJVM=
00839 jvm_attribute_index_bad;
00840
00841 pcpd_InterfaceMethodref
00842 ->LOCAL_InterfaceMethodref_binding.excpatridxJVM=
00843 jvm_attribute_index_bad;
00844
00845 pcpd_InterfaceMethodref
00846 ->LOCAL_InterfaceMethodref_binding.nmordJVM=
00847 jvm_native_method_ordinal_null;
00848 }
00849 break;
00850
00851 case CONSTANT_String:
00852
00853 case CONSTANT_Integer:
00854
00855 case CONSTANT_Float:
00856
00857 case CONSTANT_Long:
00858
00859 case CONSTANT_Double:
00860
00861 case CONSTANT_NameAndType:
00862
00863 case CONSTANT_Utf8:
00864
00865
00866
00867
00868
00869
00870 break;
00871
00872 default:
00873 GENERIC_FAILURE1_VALUE(rtrue,
00874 DMLNORM,
00875 "linkage_rmresolve_class",
00876 "Invalid CP tag %d",
00877 CP_TAG(pcfs, cpidx),
00878 rfalse,
00879 rnull,
00880 rnull);
00881
00882 }
00883
00884 }
00885
00886
00887 CLASS(clsidx).status &= ~CLASS_STATUS_LINKED;
00888
00889 return(rtrue);
00890
00891 }
00892
00893
00894
00895