📄 poljac.c
字号:
#include <jpr/log.h>#include <jpr/const.h>#include <jpr/utf8.h>#include <aegisvm/pol.h>#include "jac.h"intjac_pol_init(void) { return 0;}intjac_pol_finish(void) { return 0;}booljac_safe_field_import(POLEnv env, ju2 nargs, const void *args[const]) { POLField field = args[0]; POLClass class = pol_field_class(field); const struct jac_commitments *commitments = pol_env_commitments(env, class); const char *import_type = args[1]; const char *export_type; ju2 index = pol_field_index(field); ju2 aindex = jac_get_field_annotation_index(commitments, index); if (aindex == 0) export_type = "."; else export_type = pol_class_utf8_constant(class, aindex); if (import_type == 0) import_type = "."; return *import_type == *export_type;}booljac_method_subtype(const char *S, const char *T) { if (S != 0) { if (T != 0) { /* * both S & T are given */ /* this */ if (! jac_subtype(*T, *S)) return false; ++S; ++T; /* skip '(' */ ++S; ++T; /* arguments */ while (*S != J_ASCII_rbracket) { if (! jac_subtype(*T, *S)) return false; ++S; ++T; } /* skip ')' */ ++S; ++T; /* return type */ return jac_subtype(*S, *T); } else { /* * only S is given, T is default */ /* all parameters have type JAC_TYP_Writable, and as such they must be <: their counterparts in S */ while (*S != J_ASCII_rbracket) { ++S; ++T; } /* skip ')' */ ++S; ++T; /* return type */ return jac_subtype(*S, JAC_TYP_Writable); } } else { if (T != 0) { /* * S is default, T is given */ /* this */ if (! jac_subtype(*T, JAC_TYP_Writable)) return false; /* skip '(' */ ++S; ++T; /* arguments */ while (*T != J_ASCII_rbracket) { if (! jac_subtype(*T, JAC_TYP_Writable)) return false; ++S; ++T; } /* no need to check return type */ return true; } else { /* * Both S & T are default */ return true; } }}booljac_safe_method_import(POLEnv env, ju2 nargs, const void *args[const]) { POLMethod method = args[0]; ju2 index = pol_method_index(method); POLClass class = pol_method_class(method); const struct jac_commitments *commitments = pol_env_commitments(env, class); const char *import_type = args[1]; const char *export_type; ju2 aindex = jac_get_method_annotation_index(commitments, index); if (aindex == 0) export_type = 0; else export_type = pol_class_utf8_constant(class, aindex); return jac_method_subtype(export_type, import_type);}enum { JAC_SMO_failed, JAC_SMO_succeeded, JAC_SMO_indeterminate};intjac_safe_method_override2(POLEnv env, const char *name, const char *descriptor, const char *annotation, POLClass class) { const struct jac_commitments *commitments = pol_env_commitments(env, class); ju2 i, k; /* examine all methods of this class */ k = pol_class_methods_count(class); for (i = 0; i < k; i++) { POLMethod M = pol_class_method(class, i); /* check if method name matches */ const char *n = pol_method_name(M); if (j_utf8_eq(name, n)) { /* check if method descriptor matches */ const char *d = pol_method_descriptor(M); if (j_utf8_eq(descriptor, d)) { /* retrieve export type for overridden method */ ju2 ai = jac_get_method_annotation_index(commitments, i); const char *a = ((ai == 0) ? (a = 0) : (a = pol_class_utf8_constant(class, ai))); /* check if export type of overriding method is a subtype of export type of overridden method */ if (! jac_method_subtype(annotation, a)) return JAC_SMO_failed; /* succeeded */ return JAC_SMO_succeeded; } } } /* no method is overridden */ /* examine all superinterfaces of this class */ k = pol_class_interfaces_count(class); for (i = 0; i < k; i++) { int result = jac_safe_method_override2(env, name, descriptor, annotation, pol_class_interface(class, i)); if (result == JAC_SMO_failed) return JAC_SMO_failed; } return JAC_SMO_indeterminate;}booljac_safe_method_override(POLEnv env, ju2 nargs, const void *args[const]) { /* retrieve verification interface for this class */ POLClass class = args[0]; const struct jac_commitments *commitments = pol_env_commitments(env, class); /* for each of the method in this class ... */ ju2 i; ju2 methods_count = pol_class_methods_count(class); for (i = 0; i < methods_count; i++) { /* identify method signature */ POLMethod method = pol_class_method(class, i); if (pol_method_is_static(method)) continue; const char *name = pol_method_name(method); if (name[0] == '<') continue; const char *descriptor = pol_method_descriptor(method); /* retrieve method export type */ ju2 annot_index = jac_get_method_annotation_index(commitments, i); const char *annotation; if (annot_index == 0) annotation = 0; else annotation = pol_class_utf8_constant(class, annot_index); /* examine each superclass in turn */ POLClass C = pol_class_super_class(class); for (; C != 0; C = pol_class_super_class(C)) { switch (jac_safe_method_override2(env, name, descriptor, annotation, C)){ case JAC_SMO_failed: return false; case JAC_SMO_succeeded: goto Bypass; } } Bypass: ; } return true;}booljac_debug_commitments(POLEnv env, ju2 nargs, const void *args[const]) { POLClass class = args[0]; const struct jac_commitments *commitments = pol_env_commitments(env, class); if (commitments != 0) { j_log("class: %U", pol_class_name(class)); if (commitments->field_annotations != 0) { ju2 fields_count = pol_class_fields_count(class); ju2 i; for (i = 0; i < fields_count; i++) { ju2 index = commitments->field_annotations[i]; if (index != 0) { j_log("field [%u2] \"%U\"", i, pol_class_utf8_constant(class, index)); } } } if (commitments->method_annotations != 0) { ju2 methods_count = pol_class_methods_count(class); ju2 i; for (i = 0; i < methods_count; i++) { ju2 index = commitments->method_annotations[i]; if (index != 0) { j_log("method [%u2] \"%U\"", i, pol_class_utf8_constant(class, index)); } } } } return true;}pol_predicate_t jac_pol_predicates[] = { &jac_debug_commitments, &jac_safe_field_import, &jac_safe_method_import, &jac_safe_method_override};const void * const jac_pol_constants[] = { 0 /* default type */};struct pol_profile_t pol_profile = { "JAC", &jac_pol_init, &jac_pol_finish, sizeof(jac_pol_predicates)/sizeof(pol_predicate_t), jac_pol_predicates, 0, /* nclasses */ 0, /* global_classes */ sizeof(jac_pol_constants)/sizeof(const void *), jac_pol_constants};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -