improve structure-type property handling
Make the optimizer recognize and track `make-struct-property-type` values, and use that information to recognize `make-struct-type` calls that will defnitely succeed because a property that hs no guard is given a value in the list of properties. Combined with the change to require-keyword expansion, this change allows the optimizer to inline `f` in (define (g y) (f #:x y)) (define (f #:x x) (list x)) because the `make-struct-type` that appears between `g` and `f` is determined to have no side-effect that would prevent `f` from having its expected value.
This commit is contained in:
parent
7bcc9afd4c
commit
ad230d2ca0
|
@ -142,6 +142,9 @@ returns.}
|
||||||
@defstruct+[(predicate-shape struct-shape) ()]
|
@defstruct+[(predicate-shape struct-shape) ()]
|
||||||
@defstruct+[(accessor-shape struct-shape) ([field-count exact-nonnegative-integer?])]
|
@defstruct+[(accessor-shape struct-shape) ([field-count exact-nonnegative-integer?])]
|
||||||
@defstruct+[(mutator-shape struct-shape) ([field-count exact-nonnegative-integer?])]
|
@defstruct+[(mutator-shape struct-shape) ([field-count exact-nonnegative-integer?])]
|
||||||
|
@defstruct+[(struct-type-property-shape struct-shape) ([has-guard? boolean?])]
|
||||||
|
@defstruct+[(property-predicate-shape struct-shape) ()]
|
||||||
|
@defstruct+[(property-accessor-shape struct-shape) ()]
|
||||||
@defstruct+[(struct-other-shape struct-shape) ()]
|
@defstruct+[(struct-other-shape struct-shape) ()]
|
||||||
)]{
|
)]{
|
||||||
|
|
||||||
|
|
|
@ -4128,6 +4128,97 @@
|
||||||
(a? (a-x (a 1 2)))
|
(a? (a-x (a 1 2)))
|
||||||
5)))
|
5)))
|
||||||
|
|
||||||
|
(test-comp '(lambda ()
|
||||||
|
(make-struct-type 'a #f 0 0 #f)
|
||||||
|
10)
|
||||||
|
'(lambda ()
|
||||||
|
10))
|
||||||
|
|
||||||
|
(test-comp '(lambda ()
|
||||||
|
(make-struct-type-property 'a)
|
||||||
|
10)
|
||||||
|
'(lambda ()
|
||||||
|
10))
|
||||||
|
|
||||||
|
(test-comp '(module m racket/base
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a))
|
||||||
|
(lambda (x)
|
||||||
|
(a? x)
|
||||||
|
(if a? (if a-ref x 11) 10)))
|
||||||
|
'(module m racket/base
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a))
|
||||||
|
(lambda (x)
|
||||||
|
x)))
|
||||||
|
|
||||||
|
(test-comp '(module m racket/base
|
||||||
|
(define (f x) (list (g x) g))
|
||||||
|
;; Defining and using a property doesn't interrupt a sequence
|
||||||
|
;; of simultaneous definitions, so `g` above can be inlined
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y)))
|
||||||
|
'(module m racket/base
|
||||||
|
(define (f x) (list (list x) g))
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y))))
|
||||||
|
|
||||||
|
(test-comp '(module m racket/base
|
||||||
|
(define (f x) (list (g x) g))
|
||||||
|
;; A property type with a guard inhibits inlining, because the
|
||||||
|
;; guard might raise an error
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a error))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y)))
|
||||||
|
'(module m racket/base
|
||||||
|
(define (f x) (list (list x) g))
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a error))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y)))
|
||||||
|
#f)
|
||||||
|
|
||||||
|
(module struct-type-property-a racket/base
|
||||||
|
(provide prop:a)
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a)))
|
||||||
|
|
||||||
|
(test-comp '(module m racket/base
|
||||||
|
(require 'struct-type-property-a)
|
||||||
|
(define (f x) (list (g x) g))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y)))
|
||||||
|
'(module m racket/base
|
||||||
|
(require 'struct-type-property-a)
|
||||||
|
(define (f x) (list (list x) g))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y))))
|
||||||
|
|
||||||
|
(module struct-type-property-a-with-guard racket/base
|
||||||
|
(provide prop:a)
|
||||||
|
(define-values (prop:a a? a-ref) (make-struct-type-property 'a error)))
|
||||||
|
|
||||||
|
(test-comp '(module m racket/base
|
||||||
|
(require 'struct-type-property-a-with-guard)
|
||||||
|
(define (f x) (list (g x) g))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y)))
|
||||||
|
'(module m racket/base
|
||||||
|
(require 'struct-type-property-a-with-guard)
|
||||||
|
(define (f x) (list (list x) g))
|
||||||
|
(struct b () #:property prop:a 'a)
|
||||||
|
(define (g y) (list y)))
|
||||||
|
#f)
|
||||||
|
|
||||||
|
;; A function with a required optional argument creates a pattern like
|
||||||
|
;; the ones above, but intermediate points include extra references
|
||||||
|
;; that make it difficult to check with `test-comp`
|
||||||
|
#;
|
||||||
|
(test-comp '(module m racket/base
|
||||||
|
(define (f x) (list (g #:x x)))
|
||||||
|
(define (g #:x y) (list y)))
|
||||||
|
'(module m racket/base
|
||||||
|
(define (f x) (list (list x)))
|
||||||
|
(define (g #:x y) (list y))))
|
||||||
|
|
||||||
(test-comp `(lambda (b)
|
(test-comp `(lambda (b)
|
||||||
(let ([v (unbox b)])
|
(let ([v (unbox b)])
|
||||||
(with-continuation-mark 'x 'y (unbox v))))
|
(with-continuation-mark 'x 'y (unbox v))))
|
||||||
|
|
|
@ -627,7 +627,8 @@
|
||||||
[(? (lambda (s) (and (scope? s) (eq? (scope-name s) 'root))))
|
[(? (lambda (s) (and (scope? s) (eq? (scope-name s) 'root))))
|
||||||
(out-byte CPT_ROOT_SCOPE out)]
|
(out-byte CPT_ROOT_SCOPE out)]
|
||||||
[(struct module-variable (modidx sym pos phase constantness))
|
[(struct module-variable (modidx sym pos phase constantness))
|
||||||
(define (to-sym n) (string->symbol (format "struct~a" n)))
|
(define (to-sym #:prefix [prefix "struct"] n)
|
||||||
|
(string->symbol (format "~a~a" prefix n)))
|
||||||
(out-byte CPT_MODULE_VAR out)
|
(out-byte CPT_MODULE_VAR out)
|
||||||
(out-anything modidx out)
|
(out-anything modidx out)
|
||||||
(out-anything sym out)
|
(out-anything sym out)
|
||||||
|
@ -664,6 +665,15 @@
|
||||||
[(mutator-shape? constantness)
|
[(mutator-shape? constantness)
|
||||||
(to-sym (bitwise-ior 4 (arithmetic-shift (mutator-shape-field-count constantness)
|
(to-sym (bitwise-ior 4 (arithmetic-shift (mutator-shape-field-count constantness)
|
||||||
4)))]
|
4)))]
|
||||||
|
[(struct-type-property-shape? constantness)
|
||||||
|
(to-sym #:prefix "prop"
|
||||||
|
(if (struct-type-property-shape-has-guard? constantness)
|
||||||
|
1
|
||||||
|
0))]
|
||||||
|
[(property-predicate-shape? constantness)
|
||||||
|
(to-sym #:prefix "prop" 2)]
|
||||||
|
[(property-accessor-shape? constantness)
|
||||||
|
(to-sym #:prefix "prop" 3)]
|
||||||
[(struct-other-shape? constantness)
|
[(struct-other-shape? constantness)
|
||||||
(to-sym 5)]
|
(to-sym 5)]
|
||||||
[else #f])
|
[else #f])
|
||||||
|
|
|
@ -796,6 +796,13 @@
|
||||||
[(3) (make-accessor-shape (arithmetic-shift n -3))]
|
[(3) (make-accessor-shape (arithmetic-shift n -3))]
|
||||||
[(4) (make-mutator-shape (arithmetic-shift n -3))]
|
[(4) (make-mutator-shape (arithmetic-shift n -3))]
|
||||||
[else (make-struct-other-shape)])]
|
[else (make-struct-other-shape)])]
|
||||||
|
[(and (symbol? shape)
|
||||||
|
(regexp-match? #rx"^prop" (symbol->string shape)))
|
||||||
|
(define n (string->number (substring (symbol->string shape) 4)))
|
||||||
|
(case n
|
||||||
|
[(0 1) (make-struct-type-property-shape (= n 1))]
|
||||||
|
[(3) (make-property-predicate-shape)]
|
||||||
|
[else (make-property-accessor-shape)])]
|
||||||
[else
|
[else
|
||||||
;; parse symbol as ":"-separated sequence of arities
|
;; parse symbol as ":"-separated sequence of arities
|
||||||
(make-function-shape
|
(make-function-shape
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
(define-form-struct (accessor-shape struct-shape) ([field-count exact-nonnegative-integer?]))
|
(define-form-struct (accessor-shape struct-shape) ([field-count exact-nonnegative-integer?]))
|
||||||
(define-form-struct (mutator-shape struct-shape) ([field-count exact-nonnegative-integer?]))
|
(define-form-struct (mutator-shape struct-shape) ([field-count exact-nonnegative-integer?]))
|
||||||
(define-form-struct (struct-type-shape struct-shape) ([field-count exact-nonnegative-integer?]))
|
(define-form-struct (struct-type-shape struct-shape) ([field-count exact-nonnegative-integer?]))
|
||||||
|
(define-form-struct (struct-type-property-shape struct-shape) ([has-guard? boolean?]))
|
||||||
|
(define-form-struct (property-predicate-shape struct-shape) ())
|
||||||
|
(define-form-struct (property-accessor-shape struct-shape) ())
|
||||||
(define-form-struct (struct-other-shape struct-shape) ())
|
(define-form-struct (struct-other-shape struct-shape) ())
|
||||||
|
|
||||||
;; In toplevels of resove prefix:
|
;; In toplevels of resove prefix:
|
||||||
|
|
|
@ -1144,6 +1144,13 @@ Scheme_Object *scheme_intern_struct_proc_shape(int shape)
|
||||||
return scheme_intern_symbol(buf);
|
return scheme_intern_symbol(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scheme_Object *scheme_intern_struct_prop_proc_shape(int shape)
|
||||||
|
{
|
||||||
|
char buf[20];
|
||||||
|
sprintf(buf, "prop%d", shape);
|
||||||
|
return scheme_intern_symbol(buf);
|
||||||
|
}
|
||||||
|
|
||||||
void scheme_dump_env(Scheme_Comp_Env *env)
|
void scheme_dump_env(Scheme_Comp_Env *env)
|
||||||
{
|
{
|
||||||
Scheme_Comp_Env *frame;
|
Scheme_Comp_Env *frame;
|
||||||
|
@ -1588,6 +1595,11 @@ scheme_compile_lookup(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags,
|
||||||
*_inline_variant = mod_constant;
|
*_inline_variant = mod_constant;
|
||||||
is_constant = 2;
|
is_constant = 2;
|
||||||
shape = scheme_intern_struct_proc_shape(SCHEME_PROC_SHAPE_MODE(mod_constant));
|
shape = scheme_intern_struct_proc_shape(SCHEME_PROC_SHAPE_MODE(mod_constant));
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(mod_constant), scheme_struct_prop_proc_shape_type)) {
|
||||||
|
if (_inline_variant)
|
||||||
|
*_inline_variant = mod_constant;
|
||||||
|
is_constant = 2;
|
||||||
|
shape = scheme_intern_struct_prop_proc_shape(SCHEME_PROC_SHAPE_MODE(mod_constant));
|
||||||
} else if (SAME_TYPE(SCHEME_TYPE(mod_constant), scheme_inline_variant_type)) {
|
} else if (SAME_TYPE(SCHEME_TYPE(mod_constant), scheme_inline_variant_type)) {
|
||||||
if (_inline_variant) {
|
if (_inline_variant) {
|
||||||
/* In case the inline variant includes references to module
|
/* In case the inline variant includes references to module
|
||||||
|
|
|
@ -2031,11 +2031,17 @@ define_execute_with_dynamic_state(Scheme_Object *vec, int delta, int defmacro,
|
||||||
|
|
||||||
if (dm_env)
|
if (dm_env)
|
||||||
is_st = 0;
|
is_st = 0;
|
||||||
else
|
else if (scheme_is_simple_make_struct_type(vals_expr, g, CHECK_STRUCT_TYPE_RESOLVED,
|
||||||
is_st = !!scheme_is_simple_make_struct_type(vals_expr, g, 1, 0, 1,
|
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, MZ_RUNSTACK, 0,
|
NULL, NULL, MZ_RUNSTACK, 0,
|
||||||
NULL, NULL, NULL, 5);
|
NULL, NULL, NULL, 5))
|
||||||
|
is_st = 1;
|
||||||
|
else if (scheme_is_simple_make_struct_type_property(vals_expr, g, CHECK_STRUCT_TYPE_RESOLVED,
|
||||||
|
NULL, NULL, NULL, NULL, MZ_RUNSTACK, 0,
|
||||||
|
NULL, NULL, 5))
|
||||||
|
is_st = 1;
|
||||||
|
else
|
||||||
|
is_st = 0;
|
||||||
|
|
||||||
for (i = 0; i < g; i++) {
|
for (i = 0; i < g; i++) {
|
||||||
var = SCHEME_VEC_ELS(vec)[i+delta];
|
var = SCHEME_VEC_ELS(vec)[i+delta];
|
||||||
|
|
|
@ -2568,11 +2568,16 @@ Scheme_Object *scheme_get_or_check_procedure_shape(Scheme_Object *e, Scheme_Obje
|
||||||
Scheme_Object *p;
|
Scheme_Object *p;
|
||||||
|
|
||||||
if (expected
|
if (expected
|
||||||
&& SCHEME_SYMBOLP(expected)
|
&& SCHEME_SYMBOLP(expected)) {
|
||||||
&& SCHEME_SYM_VAL(expected)[0] == 's') {
|
if (SCHEME_SYM_VAL(expected)[0] == 's') {
|
||||||
return (scheme_check_structure_shape(e, expected)
|
return (scheme_check_structure_shape(e, expected)
|
||||||
? expected
|
? expected
|
||||||
: NULL);
|
: NULL);
|
||||||
|
} else if (SCHEME_SYM_VAL(expected)[0] == 'p') {
|
||||||
|
return (scheme_check_structure_property_shape(e, expected)
|
||||||
|
? expected
|
||||||
|
: NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SAME_TYPE(SCHEME_TYPE(e), scheme_inline_variant_type))
|
if (SAME_TYPE(SCHEME_TYPE(e), scheme_inline_variant_type))
|
||||||
|
|
|
@ -4558,7 +4558,7 @@ static void setup_accessible_table(Scheme_Module *m)
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
form = SCHEME_VEC_ELS(m->bodies[0])[i];
|
form = SCHEME_VEC_ELS(m->bodies[0])[i];
|
||||||
if (SAME_TYPE(SCHEME_TYPE(form), scheme_define_values_type)) {
|
if (SAME_TYPE(SCHEME_TYPE(form), scheme_define_values_type)) {
|
||||||
int checked_st = 0;
|
int checked_st = 0, is_st_prop = 0, has_guard = 0;
|
||||||
Scheme_Object *is_st = NULL;
|
Scheme_Object *is_st = NULL;
|
||||||
Simple_Stuct_Type_Info stinfo;
|
Simple_Stuct_Type_Info stinfo;
|
||||||
Scheme_Object *parent_identity;
|
Scheme_Object *parent_identity;
|
||||||
|
@ -4597,14 +4597,24 @@ static void setup_accessible_table(Scheme_Module *m)
|
||||||
if (!checked_st) {
|
if (!checked_st) {
|
||||||
if (scheme_is_simple_make_struct_type(SCHEME_VEC_ELS(form)[0],
|
if (scheme_is_simple_make_struct_type(SCHEME_VEC_ELS(form)[0],
|
||||||
SCHEME_VEC_SIZE(form)-1,
|
SCHEME_VEC_SIZE(form)-1,
|
||||||
1, 0, 1, NULL, &stinfo, &parent_identity,
|
CHECK_STRUCT_TYPE_RESOLVED,
|
||||||
|
NULL, &stinfo, &parent_identity,
|
||||||
NULL, NULL, NULL, NULL, 0,
|
NULL, NULL, NULL, NULL, 0,
|
||||||
m->prefix->toplevels, ht,
|
m->prefix->toplevels, ht,
|
||||||
&is_st,
|
&is_st,
|
||||||
5)) {
|
5)) {
|
||||||
is_st = scheme_make_pair(is_st, parent_identity);
|
is_st = scheme_make_pair(is_st, parent_identity);
|
||||||
} else
|
} else {
|
||||||
is_st = NULL;
|
is_st = NULL;
|
||||||
|
if (scheme_is_simple_make_struct_type_property(SCHEME_VEC_ELS(form)[0],
|
||||||
|
SCHEME_VEC_SIZE(form)-1,
|
||||||
|
CHECK_STRUCT_TYPE_RESOLVED,
|
||||||
|
&has_guard,
|
||||||
|
NULL, NULL, NULL, NULL, 0,
|
||||||
|
m->prefix->toplevels, ht,
|
||||||
|
5))
|
||||||
|
is_st_prop = 1;
|
||||||
|
}
|
||||||
checked_st = 1;
|
checked_st = 1;
|
||||||
}
|
}
|
||||||
if (is_st) {
|
if (is_st) {
|
||||||
|
@ -4614,6 +4624,14 @@ static void setup_accessible_table(Scheme_Module *m)
|
||||||
v = scheme_make_vector(3, v);
|
v = scheme_make_vector(3, v);
|
||||||
SCHEME_VEC_ELS(v)[1] = scheme_make_integer(shape);
|
SCHEME_VEC_ELS(v)[1] = scheme_make_integer(shape);
|
||||||
SCHEME_VEC_ELS(v)[2] = is_st;
|
SCHEME_VEC_ELS(v)[2] = is_st;
|
||||||
|
} else if (is_st_prop) {
|
||||||
|
intptr_t shape;
|
||||||
|
shape = scheme_get_struct_property_proc_shape(k-1, has_guard);
|
||||||
|
/* Vector of size 4 => struct property shape */
|
||||||
|
v = scheme_make_vector(4, v);
|
||||||
|
SCHEME_VEC_ELS(v)[1] = scheme_make_integer(shape);
|
||||||
|
SCHEME_VEC_ELS(v)[2] = scheme_false;
|
||||||
|
SCHEME_VEC_ELS(v)[3] = scheme_false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scheme_hash_set(ht, tl, v);
|
scheme_hash_set(ht, tl, v);
|
||||||
|
@ -4843,7 +4861,7 @@ static Scheme_Object *check_accessible_in_module(Scheme_Module *module, intptr_t
|
||||||
if (SCHEME_VEC_SIZE(pos) == 2) {
|
if (SCHEME_VEC_SIZE(pos) == 2) {
|
||||||
if (_is_constant)
|
if (_is_constant)
|
||||||
get_procedure_shape(SCHEME_VEC_ELS(pos)[1], _is_constant);
|
get_procedure_shape(SCHEME_VEC_ELS(pos)[1], _is_constant);
|
||||||
} else {
|
} else if (SCHEME_VEC_SIZE(pos) == 3) {
|
||||||
/* vector of size 3 => struct proc */
|
/* vector of size 3 => struct proc */
|
||||||
if (_is_constant) {
|
if (_is_constant) {
|
||||||
Scheme_Object *ps;
|
Scheme_Object *ps;
|
||||||
|
@ -4851,6 +4869,16 @@ static Scheme_Object *check_accessible_in_module(Scheme_Module *module, intptr_t
|
||||||
ps = scheme_make_struct_proc_shape(SCHEME_INT_VAL(SCHEME_VEC_ELS(pos)[1]),
|
ps = scheme_make_struct_proc_shape(SCHEME_INT_VAL(SCHEME_VEC_ELS(pos)[1]),
|
||||||
SCHEME_VEC_ELS(pos)[2]);
|
SCHEME_VEC_ELS(pos)[2]);
|
||||||
|
|
||||||
|
*_is_constant = ps;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MZ_ASSERT(SCHEME_VEC_SIZE(pos) == 4);
|
||||||
|
/* vector of size 4 => struct property proc */
|
||||||
|
if (_is_constant) {
|
||||||
|
Scheme_Object *ps;
|
||||||
|
|
||||||
|
ps = scheme_make_struct_property_proc_shape(SCHEME_INT_VAL(SCHEME_VEC_ELS(pos)[1]));
|
||||||
|
|
||||||
*_is_constant = ps;
|
*_is_constant = ps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,7 @@ int scheme_is_functional_nonfailing_primitive(Scheme_Object *rator, int num_args
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *get_struct_proc_shape(Scheme_Object *rator, Optimize_Info *info)
|
static Scheme_Object *get_struct_proc_shape(Scheme_Object *rator, Optimize_Info *info, int prop_ok)
|
||||||
/* Determines whether `rator` is known to be a struct accessor, etc. */
|
/* Determines whether `rator` is known to be a struct accessor, etc. */
|
||||||
{
|
{
|
||||||
Scheme_Object *c;
|
Scheme_Object *c;
|
||||||
|
@ -364,7 +364,8 @@ static Scheme_Object *get_struct_proc_shape(Scheme_Object *rator, Optimize_Info
|
||||||
c = scheme_hash_get(info->top_level_consts, scheme_make_integer(pos));
|
c = scheme_hash_get(info->top_level_consts, scheme_make_integer(pos));
|
||||||
if (!c && info->cp->inline_variants)
|
if (!c && info->cp->inline_variants)
|
||||||
c = scheme_hash_get(info->cp->inline_variants, scheme_make_integer(pos));
|
c = scheme_hash_get(info->cp->inline_variants, scheme_make_integer(pos));
|
||||||
if (c && SAME_TYPE(SCHEME_TYPE(c), scheme_struct_proc_shape_type)) {
|
if (c && (SAME_TYPE(SCHEME_TYPE(c), scheme_struct_proc_shape_type)
|
||||||
|
|| (prop_ok && SAME_TYPE(SCHEME_TYPE(c), scheme_struct_prop_proc_shape_type)))) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,14 +379,20 @@ int scheme_is_struct_functional(Scheme_Object *rator, int num_args, Optimize_Inf
|
||||||
Scheme_Object *c;
|
Scheme_Object *c;
|
||||||
|
|
||||||
if ((vals == 1) || (vals == -1)) {
|
if ((vals == 1) || (vals == -1)) {
|
||||||
c = get_struct_proc_shape(rator, info);
|
c = get_struct_proc_shape(rator, info, 1);
|
||||||
if (c) {
|
if (c) {
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(c), scheme_struct_proc_shape_type)) {
|
||||||
int mode = (SCHEME_PROC_SHAPE_MODE(c) & STRUCT_PROC_SHAPE_MASK);
|
int mode = (SCHEME_PROC_SHAPE_MODE(c) & STRUCT_PROC_SHAPE_MASK);
|
||||||
int field_count = (SCHEME_PROC_SHAPE_MODE(c) >> STRUCT_PROC_SHAPE_SHIFT);
|
int field_count = (SCHEME_PROC_SHAPE_MODE(c) >> STRUCT_PROC_SHAPE_SHIFT);
|
||||||
if (((num_args == 1) && (mode == STRUCT_PROC_SHAPE_PRED))
|
if (((num_args == 1) && (mode == STRUCT_PROC_SHAPE_PRED))
|
||||||
|| ((num_args == field_count) && (mode == STRUCT_PROC_SHAPE_CONSTR))) {
|
|| ((num_args == field_count) && (mode == STRUCT_PROC_SHAPE_CONSTR))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(c), scheme_struct_prop_proc_shape_type)) {
|
||||||
|
if ((SCHEME_PROP_PROC_SHAPE_MODE(c) == STRUCT_PROP_PROC_SHAPE_PRED)
|
||||||
|
&& (num_args == 1))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,6 +561,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SAME_OBJ(scheme_make_struct_type_proc, app->args[0]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,6 +587,8 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
||||||
note_match(1, vals, warn_info);
|
note_match(1, vals, warn_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SAME_OBJ(scheme_make_struct_type_property_proc, app->rator))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,6 +614,8 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
||||||
note_match(2, vals, warn_info);
|
note_match(2, vals, warn_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SAME_OBJ(scheme_make_struct_type_property_proc, app->rator))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,10 +632,14 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for struct-type declaration: */
|
/* check for struct-type declaration: */
|
||||||
{
|
if (!(flags & OMITTABLE_IGNORE_MAKE_STRUCT_TYPE)) {
|
||||||
Scheme_Object *auto_e;
|
Scheme_Object *auto_e;
|
||||||
int auto_e_depth;
|
int auto_e_depth;
|
||||||
auto_e = scheme_is_simple_make_struct_type(o, vals, flags, 1, 0, &auto_e_depth,
|
auto_e = scheme_is_simple_make_struct_type(o, vals,
|
||||||
|
(((flags & OMITTABLE_RESOLVED) ? CHECK_STRUCT_TYPE_RESOLVED : 0)
|
||||||
|
| CHECK_STRUCT_TYPE_ALWAYS_SUCCEED
|
||||||
|
| CHECK_STRUCT_TYPE_DELAY_AUTO_CHECK),
|
||||||
|
&auto_e_depth,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
(opt_info ? opt_info->top_level_consts : NULL),
|
(opt_info ? opt_info->top_level_consts : NULL),
|
||||||
((opt_info && opt_info->cp) ? opt_info->cp->inline_variants : NULL),
|
((opt_info && opt_info->cp) ? opt_info->cp->inline_variants : NULL),
|
||||||
|
@ -635,6 +651,19 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for struct-type property declaration: */
|
||||||
|
if (!(flags & OMITTABLE_IGNORE_MAKE_STRUCT_TYPE)) {
|
||||||
|
if (scheme_is_simple_make_struct_type_property(o, vals,
|
||||||
|
(((flags & OMITTABLE_RESOLVED) ? CHECK_STRUCT_TYPE_RESOLVED : 0)
|
||||||
|
| CHECK_STRUCT_TYPE_ALWAYS_SUCCEED),
|
||||||
|
NULL,
|
||||||
|
(opt_info ? opt_info->top_level_consts : NULL),
|
||||||
|
((opt_info && opt_info->cp) ? opt_info->cp->inline_variants : NULL),
|
||||||
|
NULL, NULL, 0, NULL, NULL,
|
||||||
|
5))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,7 +993,7 @@ static int is_proc_spec_proc(Scheme_Object *p, int init_field_count)
|
||||||
|
|
||||||
vtype = SCHEME_TYPE(p);
|
vtype = SCHEME_TYPE(p);
|
||||||
|
|
||||||
if (vtype == scheme_lambda_type) {
|
if ((vtype == scheme_lambda_type) || (vtype == scheme_ir_lambda_type)) {
|
||||||
if (((Scheme_Lambda *)p)->num_params >= 1)
|
if (((Scheme_Lambda *)p)->num_params >= 1)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1127,34 +1156,36 @@ static Scheme_Object *skip_clears(Scheme_Object *body)
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_constant_super(Scheme_Object *arg,
|
typedef int (*Ok_Value_Callback)(void *data, Scheme_Object *v, int mode);
|
||||||
|
#define OK_CONSTANT_SHAPE 1
|
||||||
|
#define OK_CONSTANT_ENCODED_SHAPE 2
|
||||||
|
#define OK_CONSTANT_VALIDATE_SHAPE 3
|
||||||
|
#define OK_CONSTANT_VARIANT 4
|
||||||
|
#define OK_CONSTANT_VALUE 5
|
||||||
|
|
||||||
|
static int is_ok_value(Ok_Value_Callback ok_value, void *data,
|
||||||
|
Scheme_Object *arg,
|
||||||
Scheme_Hash_Table *top_level_consts,
|
Scheme_Hash_Table *top_level_consts,
|
||||||
Scheme_Hash_Table *inline_variants,
|
Scheme_Hash_Table *inline_variants,
|
||||||
Scheme_Hash_Table *top_level_table,
|
Scheme_Hash_Table *top_level_table,
|
||||||
Scheme_Object **runstack, int rs_delta,
|
Scheme_Object **runstack, int rs_delta,
|
||||||
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table)
|
||||||
Scheme_Object **_parent_identity)
|
/* Does `arg` produce a value that satisfies `ok_value`? */
|
||||||
/* Does `arg` produce another structure type (which can serve as a supertype)? */
|
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
Scheme_Object *v;
|
Scheme_Object *v;
|
||||||
|
|
||||||
if (SAME_TYPE(SCHEME_TYPE(arg), scheme_ir_toplevel_type)) {
|
if (SAME_TYPE(SCHEME_TYPE(arg), scheme_ir_toplevel_type)) {
|
||||||
pos = SCHEME_TOPLEVEL_POS(arg);
|
pos = SCHEME_TOPLEVEL_POS(arg);
|
||||||
if (top_level_consts) {
|
if (top_level_consts || inline_variants) {
|
||||||
/* This is optimize mode */
|
/* This is optimize mode */
|
||||||
|
v = NULL;
|
||||||
|
if (top_level_consts)
|
||||||
v = scheme_hash_get(top_level_consts, scheme_make_integer(pos));
|
v = scheme_hash_get(top_level_consts, scheme_make_integer(pos));
|
||||||
if (!v && inline_variants)
|
if (!v && inline_variants)
|
||||||
v = scheme_hash_get(inline_variants, scheme_make_integer(pos));
|
v = scheme_hash_get(inline_variants, scheme_make_integer(pos));
|
||||||
if (v && SAME_TYPE(SCHEME_TYPE(v), scheme_struct_proc_shape_type)) {
|
if (v)
|
||||||
int mode = (SCHEME_PROC_SHAPE_MODE(v) & STRUCT_PROC_SHAPE_MASK);
|
return ok_value(data, v, OK_CONSTANT_SHAPE);
|
||||||
int field_count = (SCHEME_PROC_SHAPE_MODE(v) >> STRUCT_PROC_SHAPE_SHIFT);
|
|
||||||
if (mode == STRUCT_PROC_SHAPE_STRUCT) {
|
|
||||||
if (_parent_identity)
|
|
||||||
*_parent_identity = SCHEME_PROC_SHAPE_IDENTITY(v);
|
|
||||||
return field_count + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (SAME_TYPE(SCHEME_TYPE(arg), scheme_toplevel_type)) {
|
} else if (SAME_TYPE(SCHEME_TYPE(arg), scheme_toplevel_type)) {
|
||||||
pos = SCHEME_TOPLEVEL_POS(arg);
|
pos = SCHEME_TOPLEVEL_POS(arg);
|
||||||
|
@ -1165,14 +1196,8 @@ static int is_constant_super(Scheme_Object *arg,
|
||||||
Scheme_Prefix *toplevels;
|
Scheme_Prefix *toplevels;
|
||||||
toplevels = (Scheme_Prefix *)runstack[SCHEME_TOPLEVEL_DEPTH(arg) - rs_delta];
|
toplevels = (Scheme_Prefix *)runstack[SCHEME_TOPLEVEL_DEPTH(arg) - rs_delta];
|
||||||
b = (Scheme_Bucket *)toplevels->a[pos];
|
b = (Scheme_Bucket *)toplevels->a[pos];
|
||||||
if (b->val) {
|
if (b->val && (((Scheme_Bucket_With_Flags *)b)->flags & GLOB_IS_CONSISTENT))
|
||||||
if (SCHEME_STRUCT_TYPEP(b->val)
|
return ok_value(data, b->val, OK_CONSTANT_VALUE);
|
||||||
&& (((Scheme_Bucket_With_Flags *)b)->flags & GLOB_IS_CONSISTENT)) {
|
|
||||||
Scheme_Struct_Type *st = (Scheme_Struct_Type *)b->val;
|
|
||||||
if (st->num_slots == st->num_islots)
|
|
||||||
return st->num_slots + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (symbols) {
|
if (symbols) {
|
||||||
/* This is module-export mode; conceptually, this code belongs in
|
/* This is module-export mode; conceptually, this code belongs in
|
||||||
|
@ -1181,7 +1206,54 @@ static int is_constant_super(Scheme_Object *arg,
|
||||||
name = symbols[pos];
|
name = symbols[pos];
|
||||||
if (SCHEME_SYMBOLP(name)) {
|
if (SCHEME_SYMBOLP(name)) {
|
||||||
v = scheme_hash_get(symbol_table, name);
|
v = scheme_hash_get(symbol_table, name);
|
||||||
if (v && SCHEME_VECTORP(v) && (SCHEME_VEC_SIZE(v) == 3)) {
|
if (v)
|
||||||
|
return ok_value(data, v, OK_CONSTANT_VARIANT);
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(name), scheme_module_variable_type)) {
|
||||||
|
if (((Module_Variable *)name)->shape)
|
||||||
|
return ok_value(data, ((Module_Variable *)name)->shape, OK_CONSTANT_ENCODED_SHAPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (top_level_table) {
|
||||||
|
/* This is validate mode; conceptually, this code belongs in
|
||||||
|
define_values_validate() */
|
||||||
|
v = scheme_hash_get(top_level_table, scheme_make_integer(pos));
|
||||||
|
if (v) {
|
||||||
|
return ok_value(data, v, OK_CONSTANT_VALIDATE_SHAPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ok_constant_super_value(void *data, Scheme_Object *v, int mode)
|
||||||
|
/* Is `v` a structure type (which can serve as a supertype)? */
|
||||||
|
{
|
||||||
|
Scheme_Object **_parent_identity = (Scheme_Object **)data;
|
||||||
|
|
||||||
|
if (mode == OK_CONSTANT_SHAPE) {
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(v), scheme_struct_proc_shape_type)) {
|
||||||
|
int mode = (SCHEME_PROC_SHAPE_MODE(v) & STRUCT_PROC_SHAPE_MASK);
|
||||||
|
int field_count = (SCHEME_PROC_SHAPE_MODE(v) >> STRUCT_PROC_SHAPE_SHIFT);
|
||||||
|
if (mode == STRUCT_PROC_SHAPE_STRUCT) {
|
||||||
|
if (_parent_identity)
|
||||||
|
*_parent_identity = SCHEME_PROC_SHAPE_IDENTITY(v);
|
||||||
|
return field_count + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (mode == OK_CONSTANT_ENCODED_SHAPE) {
|
||||||
|
intptr_t k;
|
||||||
|
if (scheme_decode_struct_shape(v, &k)) {
|
||||||
|
if ((k & STRUCT_PROC_SHAPE_MASK) == STRUCT_PROC_SHAPE_STRUCT)
|
||||||
|
return (k >> STRUCT_PROC_SHAPE_SHIFT) + 1;
|
||||||
|
}
|
||||||
|
} else if (mode == OK_CONSTANT_VALIDATE_SHAPE) {
|
||||||
|
int k = SCHEME_INT_VAL(v);
|
||||||
|
if ((k >= 0)
|
||||||
|
&& (k & STRUCT_PROC_SHAPE_MASK) == STRUCT_PROC_SHAPE_STRUCT)
|
||||||
|
return (k >> STRUCT_PROC_SHAPE_SHIFT) + 1;
|
||||||
|
} else if (mode == OK_CONSTANT_VARIANT) {
|
||||||
|
if (SCHEME_VECTORP(v) && (SCHEME_VEC_SIZE(v) == 3)) {
|
||||||
if (_parent_identity)
|
if (_parent_identity)
|
||||||
*_parent_identity = SCHEME_VEC_ELS(v)[2];
|
*_parent_identity = SCHEME_VEC_ELS(v)[2];
|
||||||
v = SCHEME_VEC_ELS(v)[1];
|
v = SCHEME_VEC_ELS(v)[1];
|
||||||
|
@ -1192,31 +1264,143 @@ static int is_constant_super(Scheme_Object *arg,
|
||||||
return field_count + 1;
|
return field_count + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (SAME_TYPE(SCHEME_TYPE(name), scheme_module_variable_type)) {
|
} else if (mode == OK_CONSTANT_VALUE) {
|
||||||
intptr_t k;
|
if (SCHEME_STRUCT_TYPEP(v)) {
|
||||||
if (scheme_decode_struct_shape(((Module_Variable *)name)->shape, &k)) {
|
Scheme_Struct_Type *st = (Scheme_Struct_Type *)v;
|
||||||
if ((k & STRUCT_PROC_SHAPE_MASK) == STRUCT_PROC_SHAPE_STRUCT)
|
if (st->num_slots == st->num_islots)
|
||||||
return (k >> STRUCT_PROC_SHAPE_SHIFT) + 1;
|
return st->num_slots + 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (top_level_table) {
|
|
||||||
/* This is validate mode; conceptually, this code belongs in
|
|
||||||
define_values_validate() */
|
|
||||||
v = scheme_hash_get(top_level_table, scheme_make_integer(pos));
|
|
||||||
if (v) {
|
|
||||||
int k = SCHEME_INT_VAL(v);
|
|
||||||
if ((k & STRUCT_PROC_SHAPE_MASK) == STRUCT_PROC_SHAPE_STRUCT)
|
|
||||||
return (k >> STRUCT_PROC_SHAPE_SHIFT) + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int resolved,
|
static int is_constant_super(Scheme_Object *arg,
|
||||||
int must_always_succeed, int check_auto,
|
Scheme_Hash_Table *top_level_consts,
|
||||||
|
Scheme_Hash_Table *inline_variants,
|
||||||
|
Scheme_Hash_Table *top_level_table,
|
||||||
|
Scheme_Object **runstack, int rs_delta,
|
||||||
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
||||||
|
Scheme_Object **_parent_identity)
|
||||||
|
/* Does `arg` produce another structure type (which can serve as a supertype)? */
|
||||||
|
{
|
||||||
|
return is_ok_value(ok_constant_super_value, _parent_identity,
|
||||||
|
arg,
|
||||||
|
top_level_consts,
|
||||||
|
inline_variants, top_level_table,
|
||||||
|
runstack, rs_delta,
|
||||||
|
symbols, symbol_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ok_constant_property_with_guard(void *data, Scheme_Object *v, int mode)
|
||||||
|
{
|
||||||
|
intptr_t k = 0;
|
||||||
|
|
||||||
|
if (mode == OK_CONSTANT_SHAPE) {
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(v), scheme_struct_prop_proc_shape_type)) {
|
||||||
|
k = SCHEME_PROC_SHAPE_MODE(v);
|
||||||
|
}
|
||||||
|
} else if (mode == OK_CONSTANT_ENCODED_SHAPE) {
|
||||||
|
if (!scheme_decode_struct_prop_shape(v, &k))
|
||||||
|
k = 0;
|
||||||
|
} else if (mode == OK_CONSTANT_VALIDATE_SHAPE) {
|
||||||
|
int k = SCHEME_INT_VAL(v);
|
||||||
|
if (k < 0)
|
||||||
|
k = -(k+1);
|
||||||
|
else
|
||||||
|
k = 0;
|
||||||
|
} else if (mode == OK_CONSTANT_VARIANT) {
|
||||||
|
if (SCHEME_VECTORP(v) && (SCHEME_VEC_SIZE(v) == 4)) {
|
||||||
|
v = SCHEME_VEC_ELS(v)[1];
|
||||||
|
if (v && SCHEME_INTP(v))
|
||||||
|
k = SCHEME_INT_VAL(v);
|
||||||
|
}
|
||||||
|
} else if (mode == OK_CONSTANT_VALUE) {
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(v), scheme_struct_property_type)) {
|
||||||
|
if (!((Scheme_Struct_Property *)v)->guard)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (k == STRUCT_PROP_PROC_SHAPE_PROP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_struct_type_property_without_guard(Scheme_Object *arg,
|
||||||
|
Scheme_Hash_Table *top_level_consts,
|
||||||
|
Scheme_Hash_Table *inline_variants,
|
||||||
|
Scheme_Hash_Table *top_level_table,
|
||||||
|
Scheme_Object **runstack, int rs_delta,
|
||||||
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table)
|
||||||
|
/* Does `arg` produce a structure type property that has no guard (so that any value is ok)? */
|
||||||
|
{
|
||||||
|
return is_ok_value(ok_constant_property_with_guard, NULL,
|
||||||
|
arg,
|
||||||
|
top_level_consts,
|
||||||
|
inline_variants, top_level_table,
|
||||||
|
runstack, rs_delta,
|
||||||
|
symbols, symbol_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_simple_property_list(Scheme_Object *a, int resolved,
|
||||||
|
Scheme_Hash_Table *top_level_consts,
|
||||||
|
Scheme_Hash_Table *inline_variants,
|
||||||
|
Scheme_Hash_Table *top_level_table,
|
||||||
|
Scheme_Object **runstack, int rs_delta,
|
||||||
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table)
|
||||||
|
/* Does `a` produce a property list that always lets `make-struct-type` succeed? */
|
||||||
|
{
|
||||||
|
Scheme_Object *arg;
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(a), scheme_application_type)) {
|
||||||
|
if (!SAME_OBJ(((Scheme_App_Rec *)a)->args[0], scheme_list_proc))
|
||||||
|
return 0;
|
||||||
|
count = ((Scheme_App_Rec *)a)->num_args;
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(a), scheme_application2_type)) {
|
||||||
|
if (!SAME_OBJ(((Scheme_App2_Rec *)a)->rator, scheme_list_proc))
|
||||||
|
return 0;
|
||||||
|
count = 1;
|
||||||
|
} else if (SAME_TYPE(SCHEME_TYPE(a), scheme_application3_type)) {
|
||||||
|
if (!SAME_OBJ(((Scheme_App3_Rec *)a)->rator, scheme_list_proc))
|
||||||
|
return 0;
|
||||||
|
count = 2;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(a), scheme_application_type))
|
||||||
|
arg = ((Scheme_App_Rec *)a)->args[i+1];
|
||||||
|
else if (SAME_TYPE(SCHEME_TYPE(a), scheme_application2_type))
|
||||||
|
arg = ((Scheme_App2_Rec *)a)->rand;
|
||||||
|
else {
|
||||||
|
if (i == 0)
|
||||||
|
arg = ((Scheme_App3_Rec *)a)->rand1;
|
||||||
|
else
|
||||||
|
arg = ((Scheme_App3_Rec *)a)->rand2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(arg), scheme_application3_type)) {
|
||||||
|
Scheme_App3_Rec *a3 = (Scheme_App3_Rec *)arg;
|
||||||
|
|
||||||
|
if (!SAME_OBJ(a3->rator, scheme_cons_proc))
|
||||||
|
return 0;
|
||||||
|
if (is_struct_type_property_without_guard(a3->rand1,
|
||||||
|
top_level_consts,
|
||||||
|
inline_variants, top_level_table,
|
||||||
|
runstack, rs_delta,
|
||||||
|
symbols, symbol_table)) {
|
||||||
|
if (!scheme_omittable_expr(a3->rand2, 1, 3, (resolved ? OMITTABLE_RESOLVED : 0), NULL, NULL))
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int flags,
|
||||||
GC_CAN_IGNORE int *_auto_e_depth,
|
GC_CAN_IGNORE int *_auto_e_depth,
|
||||||
Simple_Stuct_Type_Info *_stinfo,
|
Simple_Stuct_Type_Info *_stinfo,
|
||||||
Scheme_Object **_parent_identity,
|
Scheme_Object **_parent_identity,
|
||||||
|
@ -1227,13 +1411,18 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int
|
||||||
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
||||||
Scheme_Object **_name,
|
Scheme_Object **_name,
|
||||||
int fuel)
|
int fuel)
|
||||||
/* Checks whether it's a `make-struct-type' call --- that, if `must_always_succeed` is
|
/* Checks whether it's a `make-struct-type' call --- that, if `flags` includes
|
||||||
true, certainly succeeds (i.e., no exception) --- pending a check of the auto-value
|
`CHECK_STRUCT_TYPE_ALWAYS_SUCCEED`, certainly succeeds (i.e., no exception) ---
|
||||||
argument if !check_auto. The resulting constructor must always succeed (i.e., no
|
pending a check of the auto-value argument if `flags` includes `CHECK_STRUCT_TYPE_DELAY_AUTO_CHECK`.
|
||||||
guards). The result is the auto-value argument or scheme_true if it's simple, NULL if not.
|
The expression itself must have no side-effects except for errors (but the possibility
|
||||||
|
of errors means that the expression is not necessarily omittable).
|
||||||
|
The resulting *constructor* must always succeed (i.e., no guards).
|
||||||
|
The result is the auto-value argument or scheme_true if it's simple, NULL if not.
|
||||||
The first result of `e` will be a struct type, the second a constructor, and the third a predicate;
|
The first result of `e` will be a struct type, the second a constructor, and the third a predicate;
|
||||||
the rest are selectors and mutators. */
|
the rest are selectors and mutators. */
|
||||||
{
|
{
|
||||||
|
int resolved = (flags & CHECK_STRUCT_TYPE_RESOLVED);
|
||||||
|
|
||||||
if (!fuel) return NULL;
|
if (!fuel) return NULL;
|
||||||
|
|
||||||
if (SAME_TYPE(SCHEME_TYPE(e), scheme_application_type)) {
|
if (SAME_TYPE(SCHEME_TYPE(e), scheme_application_type)) {
|
||||||
|
@ -1263,7 +1452,7 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int
|
||||||
&& (SCHEME_INT_VAL(app->args[4]) >= 0)
|
&& (SCHEME_INT_VAL(app->args[4]) >= 0)
|
||||||
&& ((app->num_args < 5)
|
&& ((app->num_args < 5)
|
||||||
/* auto-field value: */
|
/* auto-field value: */
|
||||||
|| !check_auto
|
|| (flags & CHECK_STRUCT_TYPE_DELAY_AUTO_CHECK)
|
||||||
|| scheme_omittable_expr(app->args[5], 1, 3, (resolved ? OMITTABLE_RESOLVED : 0), NULL, NULL))
|
|| scheme_omittable_expr(app->args[5], 1, 3, (resolved ? OMITTABLE_RESOLVED : 0), NULL, NULL))
|
||||||
&& ((app->num_args < 6)
|
&& ((app->num_args < 6)
|
||||||
/* no properties... */
|
/* no properties... */
|
||||||
|
@ -1273,8 +1462,14 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int
|
||||||
or selectors in a way that matters (although supplying the
|
or selectors in a way that matters (although supplying the
|
||||||
`prop:chaperone-unsafe-undefined` property can affect the
|
`prop:chaperone-unsafe-undefined` property can affect the
|
||||||
constructor in an optimizer-irrelevant way) */
|
constructor in an optimizer-irrelevant way) */
|
||||||
|| (!must_always_succeed
|
|| (!(flags & CHECK_STRUCT_TYPE_ALWAYS_SUCCEED)
|
||||||
&& scheme_omittable_expr(app->args[6], 1, 4, (resolved ? OMITTABLE_RESOLVED : 0), NULL, NULL)))
|
&& scheme_omittable_expr(app->args[6], 1, 4, (resolved ? OMITTABLE_RESOLVED : 0), NULL, NULL))
|
||||||
|
|| ((flags & CHECK_STRUCT_TYPE_ALWAYS_SUCCEED)
|
||||||
|
&& is_simple_property_list(app->args[6], resolved,
|
||||||
|
top_level_consts, inline_variants,
|
||||||
|
top_level_table,
|
||||||
|
runstack, rs_delta,
|
||||||
|
symbols, symbol_table)))
|
||||||
&& ((app->num_args < 7)
|
&& ((app->num_args < 7)
|
||||||
/* inspector: */
|
/* inspector: */
|
||||||
|| SCHEME_FALSEP(app->args[7])
|
|| SCHEME_FALSEP(app->args[7])
|
||||||
|
@ -1333,8 +1528,7 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int
|
||||||
Scheme_Object *auto_e;
|
Scheme_Object *auto_e;
|
||||||
Simple_Stuct_Type_Info stinfo;
|
Simple_Stuct_Type_Info stinfo;
|
||||||
if (!_stinfo) _stinfo = &stinfo;
|
if (!_stinfo) _stinfo = &stinfo;
|
||||||
auto_e = scheme_is_simple_make_struct_type(lv->value, 5, resolved,
|
auto_e = scheme_is_simple_make_struct_type(lv->value, 5, flags,
|
||||||
must_always_succeed, check_auto,
|
|
||||||
_auto_e_depth, _stinfo, _parent_identity,
|
_auto_e_depth, _stinfo, _parent_identity,
|
||||||
top_level_consts, inline_variants, top_level_table,
|
top_level_consts, inline_variants, top_level_table,
|
||||||
runstack, rs_delta,
|
runstack, rs_delta,
|
||||||
|
@ -1366,8 +1560,7 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int
|
||||||
Scheme_Object *auto_e;
|
Scheme_Object *auto_e;
|
||||||
Simple_Stuct_Type_Info stinfo;
|
Simple_Stuct_Type_Info stinfo;
|
||||||
if (!_stinfo) _stinfo = &stinfo;
|
if (!_stinfo) _stinfo = &stinfo;
|
||||||
auto_e = scheme_is_simple_make_struct_type(e2, 5, resolved,
|
auto_e = scheme_is_simple_make_struct_type(e2, 5, flags,
|
||||||
must_always_succeed, check_auto,
|
|
||||||
_auto_e_depth, _stinfo, _parent_identity,
|
_auto_e_depth, _stinfo, _parent_identity,
|
||||||
top_level_consts, inline_variants, top_level_table,
|
top_level_consts, inline_variants, top_level_table,
|
||||||
runstack, rs_delta + lvd->count,
|
runstack, rs_delta + lvd->count,
|
||||||
|
@ -1391,6 +1584,48 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *e, int vals, int
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int scheme_is_simple_make_struct_type_property(Scheme_Object *e, int vals, int flags,
|
||||||
|
int *_has_guard,
|
||||||
|
Scheme_Hash_Table *top_level_consts,
|
||||||
|
Scheme_Hash_Table *inline_variants,
|
||||||
|
Scheme_Hash_Table *top_level_table,
|
||||||
|
Scheme_Object **runstack, int rs_delta,
|
||||||
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
||||||
|
int fuel)
|
||||||
|
/* Reports whether `app` is a call to `make-struct-type-property` to
|
||||||
|
produce a propert with no guard. */
|
||||||
|
{
|
||||||
|
int resolved = (flags & CHECK_STRUCT_TYPE_RESOLVED);
|
||||||
|
|
||||||
|
if ((vals != 3) && (vals >= 0)) return 0;
|
||||||
|
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(e), scheme_application2_type)) {
|
||||||
|
Scheme_App2_Rec *app = (Scheme_App2_Rec *)e;
|
||||||
|
if (SAME_OBJ(app->rator, scheme_make_struct_type_property_proc)) {
|
||||||
|
if (SCHEME_SYMBOLP(app->rand)) {
|
||||||
|
if (_has_guard) *_has_guard = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(e), scheme_application3_type)) {
|
||||||
|
Scheme_App3_Rec *app = (Scheme_App3_Rec *)e;
|
||||||
|
if (SAME_OBJ(app->rator, scheme_make_struct_type_property_proc)) {
|
||||||
|
if (SCHEME_SYMBOLP(app->rand1)
|
||||||
|
&& (!(flags & CHECK_STRUCT_TYPE_ALWAYS_SUCCEED)
|
||||||
|
|| SCHEME_LAMBDAP(app->rand2))
|
||||||
|
&& (scheme_omittable_expr(app->rator, 1, 4, (resolved ? OMITTABLE_RESOLVED : 0), NULL, NULL))) {
|
||||||
|
if (_has_guard) *_has_guard = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
/* more utils */
|
/* more utils */
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
|
@ -1436,6 +1671,33 @@ Scheme_Object *scheme_make_struct_proc_shape(intptr_t k, Scheme_Object *identity
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intptr_t scheme_get_struct_property_proc_shape(int k, int has_guard)
|
||||||
|
{
|
||||||
|
switch (k) {
|
||||||
|
case 0:
|
||||||
|
if (has_guard)
|
||||||
|
return STRUCT_PROP_PROC_SHAPE_GUARDED_PROP;
|
||||||
|
else
|
||||||
|
return STRUCT_PROP_PROC_SHAPE_PROP;
|
||||||
|
case 1:
|
||||||
|
return STRUCT_PROP_PROC_SHAPE_PRED;
|
||||||
|
case 2:
|
||||||
|
default:
|
||||||
|
return STRUCT_PROP_PROC_SHAPE_GETTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Scheme_Object *scheme_make_struct_property_proc_shape(intptr_t k)
|
||||||
|
{
|
||||||
|
Scheme_Object *ps;
|
||||||
|
|
||||||
|
ps = scheme_alloc_small_object();
|
||||||
|
ps->type = scheme_struct_prop_proc_shape_type;
|
||||||
|
SCHEME_PROP_PROC_SHAPE_MODE(ps) = k;
|
||||||
|
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
XFORM_NONGCING static int is_struct_identity_subtype(Scheme_Object *sub, Scheme_Object *sup)
|
XFORM_NONGCING static int is_struct_identity_subtype(Scheme_Object *sub, Scheme_Object *sup)
|
||||||
{
|
{
|
||||||
/* A structure identity is a list of symbols, but the symbols are
|
/* A structure identity is a list of symbols, but the symbols are
|
||||||
|
@ -3831,7 +4093,7 @@ static Scheme_Object *finish_optimize_application2(Scheme_App2_Rec *app, Optimiz
|
||||||
|
|
||||||
if (SAME_OBJ(scheme_struct_type_p_proc, rator)) {
|
if (SAME_OBJ(scheme_struct_type_p_proc, rator)) {
|
||||||
Scheme_Object *c;
|
Scheme_Object *c;
|
||||||
c = get_struct_proc_shape(rand, info);
|
c = get_struct_proc_shape(rand, info, 0);
|
||||||
if (c && ((SCHEME_PROC_SHAPE_MODE(c) & STRUCT_PROC_SHAPE_MASK)
|
if (c && ((SCHEME_PROC_SHAPE_MODE(c) & STRUCT_PROC_SHAPE_MASK)
|
||||||
== STRUCT_PROC_SHAPE_STRUCT)) {
|
== STRUCT_PROC_SHAPE_STRUCT)) {
|
||||||
info->preserves_marks = 1;
|
info->preserves_marks = 1;
|
||||||
|
@ -3935,7 +4197,7 @@ static Scheme_Object *finish_optimize_application2(Scheme_App2_Rec *app, Optimiz
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Using a struct getter or predicate? */
|
/* Using a struct getter or predicate? */
|
||||||
alt = get_struct_proc_shape(rator, info);
|
alt = get_struct_proc_shape(rator, info, 0);
|
||||||
if (alt) {
|
if (alt) {
|
||||||
int mode = (SCHEME_PROC_SHAPE_MODE(alt) & STRUCT_PROC_SHAPE_MASK);
|
int mode = (SCHEME_PROC_SHAPE_MODE(alt) & STRUCT_PROC_SHAPE_MASK);
|
||||||
|
|
||||||
|
@ -4987,7 +5249,7 @@ static void add_types_for_t_branch(Scheme_Object *t, Optimize_Info *info, int fu
|
||||||
|
|
||||||
if (SAME_TYPE(SCHEME_TYPE(app->rand), scheme_ir_local_type)) {
|
if (SAME_TYPE(SCHEME_TYPE(app->rand), scheme_ir_local_type)) {
|
||||||
Scheme_Object *shape;
|
Scheme_Object *shape;
|
||||||
shape = get_struct_proc_shape(app->rator, info);
|
shape = get_struct_proc_shape(app->rator, info, 0);
|
||||||
if (shape
|
if (shape
|
||||||
&& ((SCHEME_PROC_SHAPE_MODE(shape) & STRUCT_PROC_SHAPE_MASK) == STRUCT_PROC_SHAPE_PRED)
|
&& ((SCHEME_PROC_SHAPE_MODE(shape) & STRUCT_PROC_SHAPE_MASK) == STRUCT_PROC_SHAPE_PRED)
|
||||||
&& SCHEME_PAIRP(SCHEME_PROC_SHAPE_IDENTITY(shape))) {
|
&& SCHEME_PAIRP(SCHEME_PROC_SHAPE_IDENTITY(shape))) {
|
||||||
|
@ -7914,6 +8176,23 @@ int split_define_values(Scheme_Object *e, int n, Scheme_Object *vars, Scheme_Obj
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Scheme_Hash_Table *set_as_fixed(Scheme_Hash_Table *fixed_table, Optimize_Info *info, int pos)
|
||||||
|
{
|
||||||
|
if (!fixed_table) {
|
||||||
|
fixed_table = scheme_make_hash_table(SCHEME_hash_ptr);
|
||||||
|
if (!info->top_level_consts) {
|
||||||
|
Scheme_Hash_Table *consts;
|
||||||
|
consts = scheme_make_hash_table(SCHEME_hash_ptr);
|
||||||
|
info->top_level_consts = consts;
|
||||||
|
}
|
||||||
|
scheme_hash_set(info->top_level_consts, scheme_false, (Scheme_Object *)fixed_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
scheme_hash_set(fixed_table, scheme_make_integer(pos), scheme_true);
|
||||||
|
|
||||||
|
return fixed_table;
|
||||||
|
}
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *
|
||||||
module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
{
|
{
|
||||||
|
@ -7951,7 +8230,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
|
|
||||||
/* Use `limited_info` for optimization decisions that need to be
|
/* Use `limited_info` for optimization decisions that need to be
|
||||||
rediscovered by the validator. The validator knows shape
|
rediscovered by the validator. The validator knows shape
|
||||||
information for imported variables, and it know about structure
|
information for imported variables, and it knows about structure
|
||||||
bindings for later forms. */
|
bindings for later forms. */
|
||||||
limited_info = MALLOC_ONE_RT(Optimize_Info);
|
limited_info = MALLOC_ONE_RT(Optimize_Info);
|
||||||
#ifdef MZTAG_REQUIRED
|
#ifdef MZTAG_REQUIRED
|
||||||
|
@ -8077,7 +8356,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
(including raising an exception), then continue the group of
|
(including raising an exception), then continue the group of
|
||||||
simultaneous definitions: */
|
simultaneous definitions: */
|
||||||
if (SAME_TYPE(SCHEME_TYPE(e), scheme_define_values_type)) {
|
if (SAME_TYPE(SCHEME_TYPE(e), scheme_define_values_type)) {
|
||||||
int n, cnst = 0, sproc = 0;
|
int n, cnst = 0, sproc = 0, sprop = 0, has_guard = 0;
|
||||||
Scheme_Object *sstruct = NULL, *parent_identity = NULL;
|
Scheme_Object *sstruct = NULL, *parent_identity = NULL;
|
||||||
Simple_Stuct_Type_Info stinfo;
|
Simple_Stuct_Type_Info stinfo;
|
||||||
|
|
||||||
|
@ -8088,8 +8367,11 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
cont = scheme_omittable_expr(e, n, -1,
|
cont = scheme_omittable_expr(e, n, -1,
|
||||||
/* ignore APPN_FLAG_OMITTABLE, because the
|
/* ignore APPN_FLAG_OMITTABLE, because the
|
||||||
validator won't be able to reconstruct it
|
validator won't be able to reconstruct it
|
||||||
in general */
|
in general; also, don't recognize struct-type
|
||||||
OMITTABLE_IGNORE_APPN_OMIT,
|
functions, since they weren't recognized
|
||||||
|
as immediate calls */
|
||||||
|
(OMITTABLE_IGNORE_APPN_OMIT
|
||||||
|
| OMITTABLE_IGNORE_MAKE_STRUCT_TYPE),
|
||||||
/* similarly, use `limited_info` instead of `info'
|
/* similarly, use `limited_info` instead of `info'
|
||||||
here, because the decision
|
here, because the decision
|
||||||
of omittable should not depend on
|
of omittable should not depend on
|
||||||
|
@ -8105,7 +8387,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
cnst = 1;
|
cnst = 1;
|
||||||
sproc = 1;
|
sproc = 1;
|
||||||
}
|
}
|
||||||
} else if (scheme_is_simple_make_struct_type(e, n, 0, 0, 1, NULL,
|
} else if (scheme_is_simple_make_struct_type(e, n, 0, NULL,
|
||||||
&stinfo, &parent_identity,
|
&stinfo, &parent_identity,
|
||||||
info->top_level_consts,
|
info->top_level_consts,
|
||||||
info->cp->inline_variants,
|
info->cp->inline_variants,
|
||||||
|
@ -8114,9 +8396,24 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
5)) {
|
5)) {
|
||||||
sstruct = scheme_make_pair(sstruct, parent_identity);
|
sstruct = scheme_make_pair(sstruct, parent_identity);
|
||||||
cnst = 1;
|
cnst = 1;
|
||||||
|
} else if (scheme_is_simple_make_struct_type_property(e, n, 0,
|
||||||
|
&has_guard,
|
||||||
|
info->top_level_consts,
|
||||||
|
info->cp->inline_variants,
|
||||||
|
NULL, NULL, 0, NULL, NULL,
|
||||||
|
5)) {
|
||||||
|
sprop = 1;
|
||||||
|
cnst = 1;
|
||||||
} else
|
} else
|
||||||
sstruct = NULL;
|
sstruct = NULL;
|
||||||
|
|
||||||
|
if ((sstruct || sprop) && !cont) {
|
||||||
|
/* Since the `make-struct-type` or `make-struct-tye-property` form is immediate
|
||||||
|
enough that the validator can see it, re-check whether we can continue
|
||||||
|
a group of simultaneously defined variables. */
|
||||||
|
cont = scheme_omittable_expr(e, n, 5, OMITTABLE_IGNORE_APPN_OMIT, limited_info, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (cnst) {
|
if (cnst) {
|
||||||
Scheme_Toplevel *tl;
|
Scheme_Toplevel *tl;
|
||||||
int i;
|
int i;
|
||||||
|
@ -8130,6 +8427,8 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
if (sstruct) {
|
if (sstruct) {
|
||||||
e2 = scheme_make_struct_proc_shape(scheme_get_struct_proc_shape(i, &stinfo),
|
e2 = scheme_make_struct_proc_shape(scheme_get_struct_proc_shape(i, &stinfo),
|
||||||
sstruct);
|
sstruct);
|
||||||
|
} else if (sprop) {
|
||||||
|
e2 = scheme_make_struct_property_proc_shape(scheme_get_struct_property_proc_shape(i, has_guard));
|
||||||
} else if (sproc) {
|
} else if (sproc) {
|
||||||
e2 = scheme_make_noninline_proc(e);
|
e2 = scheme_make_noninline_proc(e);
|
||||||
} else if (SCHEME_LAMBDAP(e)) {
|
} else if (SCHEME_LAMBDAP(e)) {
|
||||||
|
@ -8159,7 +8458,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
}
|
}
|
||||||
scheme_hash_set(consts, scheme_make_integer(pos), e2);
|
scheme_hash_set(consts, scheme_make_integer(pos), e2);
|
||||||
|
|
||||||
if (sstruct) {
|
if (sstruct || sprop) {
|
||||||
/* include in `limited_info` */
|
/* include in `limited_info` */
|
||||||
Scheme_Hash_Table *limited_consts = limited_info->top_level_consts;
|
Scheme_Hash_Table *limited_consts = limited_info->top_level_consts;
|
||||||
if (!limited_consts) {
|
if (!limited_consts) {
|
||||||
|
@ -8179,23 +8478,15 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* At least mark it as fixed */
|
/* At least mark it as fixed */
|
||||||
if (!fixed_table) {
|
fixed_table = set_as_fixed(fixed_table, info, tl->position);
|
||||||
fixed_table = scheme_make_hash_table(SCHEME_hash_ptr);
|
|
||||||
if (!info->top_level_consts) {
|
|
||||||
consts = scheme_make_hash_table(SCHEME_hash_ptr);
|
|
||||||
info->top_level_consts = consts;
|
|
||||||
consts = NULL;
|
|
||||||
}
|
|
||||||
scheme_hash_set(info->top_level_consts, scheme_false, (Scheme_Object *)fixed_table);
|
|
||||||
}
|
|
||||||
scheme_hash_set(fixed_table, scheme_make_integer(tl->position), scheme_true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The binding is not inlinable/propagatable, but unless it's
|
/* The binding is not inlinable/propagatable, but unless it's
|
||||||
set!ed, it is constant after evaluating the definition. We
|
set!ed, it is constant after evaluating the definition. We
|
||||||
map the top-level position to indicate constantness. */
|
map the top-level position to indicate constantness --- immediately
|
||||||
|
if `cont`, and later if not. */
|
||||||
Scheme_Object *l, *a;
|
Scheme_Object *l, *a;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
|
@ -8206,6 +8497,9 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
if (!(SCHEME_TOPLEVEL_FLAGS(a) & SCHEME_TOPLEVEL_MUTATED)) {
|
if (!(SCHEME_TOPLEVEL_FLAGS(a) & SCHEME_TOPLEVEL_MUTATED)) {
|
||||||
pos = SCHEME_TOPLEVEL_POS(a);
|
pos = SCHEME_TOPLEVEL_POS(a);
|
||||||
|
|
||||||
|
if (cont)
|
||||||
|
fixed_table = set_as_fixed(fixed_table, info, pos);
|
||||||
|
else
|
||||||
next_pos_ready = pos;
|
next_pos_ready = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8321,16 +8615,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_pos_ready > -1) {
|
if (next_pos_ready > -1) {
|
||||||
if (!fixed_table) {
|
fixed_table = set_as_fixed(fixed_table, info, next_pos_ready);
|
||||||
fixed_table = scheme_make_hash_table(SCHEME_hash_ptr);
|
|
||||||
if (!info->top_level_consts) {
|
|
||||||
consts = scheme_make_hash_table(SCHEME_hash_ptr);
|
|
||||||
info->top_level_consts = consts;
|
|
||||||
consts = NULL;
|
|
||||||
}
|
|
||||||
scheme_hash_set(info->top_level_consts, scheme_false, (Scheme_Object *)fixed_table);
|
|
||||||
}
|
|
||||||
scheme_hash_set(fixed_table, scheme_make_integer(next_pos_ready), scheme_true);
|
|
||||||
next_pos_ready = -1;
|
next_pos_ready = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,6 +538,7 @@ extern Scheme_Object *scheme_call_with_immed_mark_proc;
|
||||||
extern Scheme_Object *scheme_make_struct_type_proc;
|
extern Scheme_Object *scheme_make_struct_type_proc;
|
||||||
extern Scheme_Object *scheme_make_struct_field_accessor_proc;
|
extern Scheme_Object *scheme_make_struct_field_accessor_proc;
|
||||||
extern Scheme_Object *scheme_make_struct_field_mutator_proc;
|
extern Scheme_Object *scheme_make_struct_field_mutator_proc;
|
||||||
|
extern Scheme_Object *scheme_make_struct_type_property_proc;
|
||||||
extern Scheme_Object *scheme_struct_to_vector_proc;
|
extern Scheme_Object *scheme_struct_to_vector_proc;
|
||||||
extern Scheme_Object *scheme_struct_type_p_proc;
|
extern Scheme_Object *scheme_struct_type_p_proc;
|
||||||
extern Scheme_Object *scheme_current_inspector_proc;
|
extern Scheme_Object *scheme_current_inspector_proc;
|
||||||
|
@ -3480,6 +3481,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int flags,
|
||||||
#define OMITTABLE_KEEP_VARS 0x2
|
#define OMITTABLE_KEEP_VARS 0x2
|
||||||
#define OMITTABLE_KEEP_MUTABLE_VARS 0x4
|
#define OMITTABLE_KEEP_MUTABLE_VARS 0x4
|
||||||
#define OMITTABLE_IGNORE_APPN_OMIT 0x8
|
#define OMITTABLE_IGNORE_APPN_OMIT 0x8
|
||||||
|
#define OMITTABLE_IGNORE_MAKE_STRUCT_TYPE 0x10
|
||||||
|
|
||||||
int scheme_might_invoke_call_cc(Scheme_Object *value);
|
int scheme_might_invoke_call_cc(Scheme_Object *value);
|
||||||
int scheme_is_liftable(Scheme_Object *o, Scheme_Hash_Tree *exclude_vars, int fuel, int as_rator, int or_escape);
|
int scheme_is_liftable(Scheme_Object *o, Scheme_Hash_Tree *exclude_vars, int fuel, int as_rator, int or_escape);
|
||||||
|
@ -3495,9 +3497,8 @@ typedef struct {
|
||||||
int num_gets, num_sets;
|
int num_gets, num_sets;
|
||||||
} Simple_Stuct_Type_Info;
|
} Simple_Stuct_Type_Info;
|
||||||
|
|
||||||
Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *app, int vals, int resolved,
|
Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *app, int vals, int flags,
|
||||||
int must_always_succeed,
|
int *_auto_e_depth,
|
||||||
int check_auto, int *_auto_e_depth,
|
|
||||||
Simple_Stuct_Type_Info *_stinfo,
|
Simple_Stuct_Type_Info *_stinfo,
|
||||||
Scheme_Object **_parent_identity,
|
Scheme_Object **_parent_identity,
|
||||||
Scheme_Hash_Table *top_level_consts,
|
Scheme_Hash_Table *top_level_consts,
|
||||||
|
@ -3507,6 +3508,17 @@ Scheme_Object *scheme_is_simple_make_struct_type(Scheme_Object *app, int vals, i
|
||||||
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
||||||
Scheme_Object **_name,
|
Scheme_Object **_name,
|
||||||
int fuel);
|
int fuel);
|
||||||
|
int scheme_is_simple_make_struct_type_property(Scheme_Object *app, int vals, int flags,
|
||||||
|
int *_has_guard,
|
||||||
|
Scheme_Hash_Table *top_level_consts,
|
||||||
|
Scheme_Hash_Table *inline_variants,
|
||||||
|
Scheme_Hash_Table *top_level_table,
|
||||||
|
Scheme_Object **runstack, int rs_delta,
|
||||||
|
Scheme_Object **symbols, Scheme_Hash_Table *symbol_table,
|
||||||
|
int fuel);
|
||||||
|
#define CHECK_STRUCT_TYPE_RESOLVED 0x1
|
||||||
|
#define CHECK_STRUCT_TYPE_ALWAYS_SUCCEED 0x2
|
||||||
|
#define CHECK_STRUCT_TYPE_DELAY_AUTO_CHECK 0x4
|
||||||
|
|
||||||
Scheme_Object *scheme_intern_struct_proc_shape(int shape);
|
Scheme_Object *scheme_intern_struct_proc_shape(int shape);
|
||||||
intptr_t scheme_get_struct_proc_shape(int k, Simple_Stuct_Type_Info *sinfo);
|
intptr_t scheme_get_struct_proc_shape(int k, Simple_Stuct_Type_Info *sinfo);
|
||||||
|
@ -3528,9 +3540,20 @@ typedef struct Scheme_Struct_Proc_Shape {
|
||||||
#define SCHEME_PROC_SHAPE_MODE(obj) ((Scheme_Struct_Proc_Shape *)obj)->mode
|
#define SCHEME_PROC_SHAPE_MODE(obj) ((Scheme_Struct_Proc_Shape *)obj)->mode
|
||||||
#define SCHEME_PROC_SHAPE_IDENTITY(obj) ((Scheme_Struct_Proc_Shape *)obj)->identity
|
#define SCHEME_PROC_SHAPE_IDENTITY(obj) ((Scheme_Struct_Proc_Shape *)obj)->identity
|
||||||
|
|
||||||
|
Scheme_Object *scheme_intern_struct_prop_proc_shape(int shape);
|
||||||
|
intptr_t scheme_get_struct_property_proc_shape(int k, int has_guard);
|
||||||
|
Scheme_Object *scheme_make_struct_property_proc_shape(intptr_t k);
|
||||||
|
#define STRUCT_PROP_PROC_SHAPE_PROP 0
|
||||||
|
#define STRUCT_PROP_PROC_SHAPE_GUARDED_PROP 1
|
||||||
|
#define STRUCT_PROP_PROC_SHAPE_PRED 2
|
||||||
|
#define STRUCT_PROP_PROC_SHAPE_GETTER 3
|
||||||
|
#define SCHEME_PROP_PROC_SHAPE_MODE(obj) ((Scheme_Small_Object *)obj)->u.int_val
|
||||||
|
|
||||||
Scheme_Object *scheme_get_or_check_procedure_shape(Scheme_Object *e, Scheme_Object *expected);
|
Scheme_Object *scheme_get_or_check_procedure_shape(Scheme_Object *e, Scheme_Object *expected);
|
||||||
int scheme_check_structure_shape(Scheme_Object *e, Scheme_Object *expected);
|
int scheme_check_structure_shape(Scheme_Object *e, Scheme_Object *expected);
|
||||||
int scheme_decode_struct_shape(Scheme_Object *shape, intptr_t *_v);
|
int scheme_decode_struct_shape(Scheme_Object *shape, intptr_t *_v);
|
||||||
|
int scheme_check_structure_property_shape(Scheme_Object *e, Scheme_Object *expected);
|
||||||
|
int scheme_decode_struct_prop_shape(Scheme_Object *shape, intptr_t *_v);
|
||||||
int scheme_closure_preserves_marks(Scheme_Object *p);
|
int scheme_closure_preserves_marks(Scheme_Object *p);
|
||||||
int scheme_native_closure_preserves_marks(Scheme_Object *p);
|
int scheme_native_closure_preserves_marks(Scheme_Object *p);
|
||||||
int scheme_native_closure_is_single_result(Scheme_Object *rator);
|
int scheme_native_closure_is_single_result(Scheme_Object *rator);
|
||||||
|
|
|
@ -39,6 +39,7 @@ READ_ONLY Scheme_Object *scheme_impersonator_of_property;
|
||||||
READ_ONLY Scheme_Object *scheme_make_struct_type_proc;
|
READ_ONLY Scheme_Object *scheme_make_struct_type_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_make_struct_field_accessor_proc;
|
READ_ONLY Scheme_Object *scheme_make_struct_field_accessor_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_make_struct_field_mutator_proc;
|
READ_ONLY Scheme_Object *scheme_make_struct_field_mutator_proc;
|
||||||
|
READ_ONLY Scheme_Object *scheme_make_struct_type_property_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_struct_type_p_proc;
|
READ_ONLY Scheme_Object *scheme_struct_type_p_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_current_inspector_proc;
|
READ_ONLY Scheme_Object *scheme_current_inspector_proc;
|
||||||
READ_ONLY Scheme_Object *scheme_make_inspector_proc;
|
READ_ONLY Scheme_Object *scheme_make_inspector_proc;
|
||||||
|
@ -557,11 +558,13 @@ scheme_init_struct (Scheme_Env *env)
|
||||||
scheme_make_struct_type_proc,
|
scheme_make_struct_type_proc,
|
||||||
env);
|
env);
|
||||||
|
|
||||||
scheme_add_global_constant("make-struct-type-property",
|
REGISTER_SO(scheme_make_struct_type_property_proc);
|
||||||
scheme_make_prim_w_arity2(make_struct_type_property,
|
scheme_make_struct_type_property_proc = scheme_make_prim_w_arity2(make_struct_type_property,
|
||||||
"make-struct-type-property",
|
"make-struct-type-property",
|
||||||
1, 4,
|
1, 4,
|
||||||
3, 3),
|
3, 3);
|
||||||
|
scheme_add_global_constant("make-struct-type-property",
|
||||||
|
scheme_make_struct_type_property_proc,
|
||||||
env);
|
env);
|
||||||
|
|
||||||
REGISTER_SO(scheme_make_struct_field_accessor_proc);
|
REGISTER_SO(scheme_make_struct_field_accessor_proc);
|
||||||
|
@ -3555,7 +3558,8 @@ int scheme_decode_struct_shape(Scheme_Object *expected, intptr_t *_v)
|
||||||
if (!expected || !SCHEME_SYMBOLP(expected))
|
if (!expected || !SCHEME_SYMBOLP(expected))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (SCHEME_SYM_VAL(expected)[0] != 's')
|
if ((SCHEME_SYM_VAL(expected)[0] != 's')
|
||||||
|
|| (SCHEME_SYM_LEN(expected) < 6))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 6, v = 0; SCHEME_SYM_VAL(expected)[i]; i++) {
|
for (i = 6, v = 0; SCHEME_SYM_VAL(expected)[i]; i++) {
|
||||||
|
@ -3611,6 +3615,53 @@ int scheme_check_structure_shape(Scheme_Object *e, Scheme_Object *expected)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int scheme_decode_struct_prop_shape(Scheme_Object *expected, intptr_t *_v)
|
||||||
|
{
|
||||||
|
intptr_t v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!expected || !SCHEME_SYMBOLP(expected))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((SCHEME_SYM_VAL(expected)[0] != 'p')
|
||||||
|
|| (SCHEME_SYM_LEN(expected) < 4))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 4, v = 0; SCHEME_SYM_VAL(expected)[i]; i++) {
|
||||||
|
v = (v * 10) + (SCHEME_SYM_VAL(expected)[i] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
*_v = v;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scheme_check_structure_property_shape(Scheme_Object *e, Scheme_Object *expected)
|
||||||
|
{
|
||||||
|
intptr_t _v, v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!scheme_decode_struct_prop_shape(expected, &_v))
|
||||||
|
return 0;
|
||||||
|
v = _v;
|
||||||
|
|
||||||
|
if (SAME_TYPE(SCHEME_TYPE(e), scheme_struct_property_type)) {
|
||||||
|
if (((Scheme_Struct_Property *)e)->guard)
|
||||||
|
return (v == STRUCT_PROP_PROC_SHAPE_GUARDED_PROP);
|
||||||
|
return ((v == STRUCT_PROP_PROC_SHAPE_PROP)
|
||||||
|
|| (v == STRUCT_PROP_PROC_SHAPE_GUARDED_PROP));
|
||||||
|
} else if (!SCHEME_PRIMP(e))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
i = (((Scheme_Primitive_Proc *)e)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK);
|
||||||
|
if (i == SCHEME_PRIM_STRUCT_TYPE_STRUCT_PROP_PRED)
|
||||||
|
return (v == STRUCT_PROP_PROC_SHAPE_PRED);
|
||||||
|
else if (i == SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER)
|
||||||
|
return (v == STRUCT_PROP_PROC_SHAPE_GETTER);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static Scheme_Object *make_struct_field_xxor(const char *who, int getter,
|
static Scheme_Object *make_struct_field_xxor(const char *who, int getter,
|
||||||
int argc, Scheme_Object *argv[])
|
int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
|
|
|
@ -224,94 +224,95 @@ enum {
|
||||||
scheme_port_closed_evt_type, /* 193 */
|
scheme_port_closed_evt_type, /* 193 */
|
||||||
scheme_proc_shape_type, /* 194 */
|
scheme_proc_shape_type, /* 194 */
|
||||||
scheme_struct_proc_shape_type, /* 195 */
|
scheme_struct_proc_shape_type, /* 195 */
|
||||||
scheme_phantom_bytes_type, /* 196 */
|
scheme_struct_prop_proc_shape_type, /* 196 */
|
||||||
scheme_environment_variables_type, /* 197 */
|
scheme_phantom_bytes_type, /* 197 */
|
||||||
scheme_filesystem_change_evt_type, /* 198 */
|
scheme_environment_variables_type, /* 198 */
|
||||||
scheme_ctype_type, /* 199 */
|
scheme_filesystem_change_evt_type, /* 199 */
|
||||||
scheme_plumber_type, /* 200 */
|
scheme_ctype_type, /* 200 */
|
||||||
scheme_plumber_handle_type, /* 201 */
|
scheme_plumber_type, /* 201 */
|
||||||
scheme_deferred_expr_type, /* 202 */
|
scheme_plumber_handle_type, /* 202 */
|
||||||
scheme_will_be_lambda_type, /* 203 */
|
scheme_deferred_expr_type, /* 203 */
|
||||||
scheme_syntax_property_preserve_type, /* 204 */
|
scheme_will_be_lambda_type, /* 204 */
|
||||||
|
scheme_syntax_property_preserve_type, /* 205 */
|
||||||
|
|
||||||
#ifdef MZTAG_REQUIRED
|
#ifdef MZTAG_REQUIRED
|
||||||
_scheme_last_normal_type_, /* 205 */
|
_scheme_last_normal_type_, /* 206 */
|
||||||
|
|
||||||
/* The remaining tags exist for GC tracing (in non-conservative
|
/* The remaining tags exist for GC tracing (in non-conservative
|
||||||
mode), but they are not needed for run-time tag tests */
|
mode), but they are not needed for run-time tag tests */
|
||||||
|
|
||||||
scheme_rt_weak_array, /* 206 */
|
scheme_rt_weak_array, /* 207 */
|
||||||
|
|
||||||
scheme_rt_comp_env, /* 207 */
|
scheme_rt_comp_env, /* 208 */
|
||||||
scheme_rt_constant_binding, /* 208 */
|
scheme_rt_constant_binding, /* 209 */
|
||||||
scheme_rt_resolve_info, /* 209 */
|
scheme_rt_resolve_info, /* 210 */
|
||||||
scheme_rt_unresolve_info, /* 210 */
|
scheme_rt_unresolve_info, /* 211 */
|
||||||
scheme_rt_optimize_info, /* 211 */
|
scheme_rt_optimize_info, /* 212 */
|
||||||
scheme_rt_cont_mark, /* 212 */
|
scheme_rt_cont_mark, /* 213 */
|
||||||
scheme_rt_saved_stack, /* 213 */
|
scheme_rt_saved_stack, /* 214 */
|
||||||
scheme_rt_reply_item, /* 214 */
|
scheme_rt_reply_item, /* 215 */
|
||||||
scheme_rt_ir_lambda_info, /* 215 */
|
scheme_rt_ir_lambda_info, /* 216 */
|
||||||
scheme_rt_overflow, /* 216 */
|
scheme_rt_overflow, /* 217 */
|
||||||
scheme_rt_overflow_jmp, /* 217 */
|
scheme_rt_overflow_jmp, /* 218 */
|
||||||
scheme_rt_meta_cont, /* 218 */
|
scheme_rt_meta_cont, /* 219 */
|
||||||
scheme_rt_dyn_wind_cell, /* 219 */
|
scheme_rt_dyn_wind_cell, /* 220 */
|
||||||
scheme_rt_dyn_wind_info, /* 220 */
|
scheme_rt_dyn_wind_info, /* 221 */
|
||||||
scheme_rt_dyn_wind, /* 221 */
|
scheme_rt_dyn_wind, /* 222 */
|
||||||
scheme_rt_dup_check, /* 222 */
|
scheme_rt_dup_check, /* 223 */
|
||||||
scheme_rt_thread_memory, /* 223 */
|
scheme_rt_thread_memory, /* 224 */
|
||||||
scheme_rt_input_file, /* 224 */
|
scheme_rt_input_file, /* 225 */
|
||||||
scheme_rt_input_fd, /* 225 */
|
scheme_rt_input_fd, /* 226 */
|
||||||
scheme_rt_oskit_console_input, /* 226 */
|
scheme_rt_oskit_console_input, /* 227 */
|
||||||
scheme_rt_tested_input_file, /* 227 */
|
scheme_rt_tested_input_file, /* 228 */
|
||||||
scheme_rt_tested_output_file, /* 228 */
|
scheme_rt_tested_output_file, /* 229 */
|
||||||
scheme_rt_indexed_string, /* 229 */
|
scheme_rt_indexed_string, /* 230 */
|
||||||
scheme_rt_output_file, /* 230 */
|
scheme_rt_output_file, /* 231 */
|
||||||
scheme_rt_load_handler_data, /* 231 */
|
scheme_rt_load_handler_data, /* 232 */
|
||||||
scheme_rt_pipe, /* 232 */
|
scheme_rt_pipe, /* 233 */
|
||||||
scheme_rt_beos_process, /* 233 */
|
scheme_rt_beos_process, /* 234 */
|
||||||
scheme_rt_system_child, /* 234 */
|
scheme_rt_system_child, /* 235 */
|
||||||
scheme_rt_tcp, /* 235 */
|
scheme_rt_tcp, /* 236 */
|
||||||
scheme_rt_write_data, /* 236 */
|
scheme_rt_write_data, /* 237 */
|
||||||
scheme_rt_tcp_select_info, /* 237 */
|
scheme_rt_tcp_select_info, /* 238 */
|
||||||
scheme_rt_param_data, /* 238 */
|
scheme_rt_param_data, /* 239 */
|
||||||
scheme_rt_will, /* 239 */
|
scheme_rt_will, /* 240 */
|
||||||
scheme_rt_linker_name, /* 240 */
|
scheme_rt_linker_name, /* 241 */
|
||||||
scheme_rt_param_map, /* 241 */
|
scheme_rt_param_map, /* 242 */
|
||||||
scheme_rt_finalization, /* 242 */
|
scheme_rt_finalization, /* 243 */
|
||||||
scheme_rt_finalizations, /* 243 */
|
scheme_rt_finalizations, /* 244 */
|
||||||
scheme_rt_cpp_object, /* 244 */
|
scheme_rt_cpp_object, /* 245 */
|
||||||
scheme_rt_cpp_array_object, /* 245 */
|
scheme_rt_cpp_array_object, /* 246 */
|
||||||
scheme_rt_stack_object, /* 246 */
|
scheme_rt_stack_object, /* 247 */
|
||||||
scheme_rt_preallocated_object, /* 247 */
|
scheme_rt_preallocated_object, /* 248 */
|
||||||
scheme_thread_hop_type, /* 248 */
|
scheme_thread_hop_type, /* 249 */
|
||||||
scheme_rt_srcloc, /* 249 */
|
scheme_rt_srcloc, /* 250 */
|
||||||
scheme_rt_evt, /* 250 */
|
scheme_rt_evt, /* 251 */
|
||||||
scheme_rt_syncing, /* 251 */
|
scheme_rt_syncing, /* 252 */
|
||||||
scheme_rt_comp_prefix, /* 252 */
|
scheme_rt_comp_prefix, /* 253 */
|
||||||
scheme_rt_user_input, /* 253 */
|
scheme_rt_user_input, /* 254 */
|
||||||
scheme_rt_user_output, /* 254 */
|
scheme_rt_user_output, /* 255 */
|
||||||
scheme_rt_compact_port, /* 255 */
|
scheme_rt_compact_port, /* 256 */
|
||||||
scheme_rt_read_special_dw, /* 256 */
|
scheme_rt_read_special_dw, /* 257 */
|
||||||
scheme_rt_regwork, /* 257 */
|
scheme_rt_regwork, /* 258 */
|
||||||
scheme_rt_rx_lazy_string, /* 258 */
|
scheme_rt_rx_lazy_string, /* 259 */
|
||||||
scheme_rt_buf_holder, /* 259 */
|
scheme_rt_buf_holder, /* 260 */
|
||||||
scheme_rt_parameterization, /* 260 */
|
scheme_rt_parameterization, /* 261 */
|
||||||
scheme_rt_print_params, /* 261 */
|
scheme_rt_print_params, /* 262 */
|
||||||
scheme_rt_read_params, /* 262 */
|
scheme_rt_read_params, /* 263 */
|
||||||
scheme_rt_native_code, /* 263 */
|
scheme_rt_native_code, /* 264 */
|
||||||
scheme_rt_native_code_plus_case, /* 264 */
|
scheme_rt_native_code_plus_case, /* 265 */
|
||||||
scheme_rt_jitter_data, /* 265 */
|
scheme_rt_jitter_data, /* 266 */
|
||||||
scheme_rt_module_exports, /* 266 */
|
scheme_rt_module_exports, /* 267 */
|
||||||
scheme_rt_delay_load_info, /* 267 */
|
scheme_rt_delay_load_info, /* 268 */
|
||||||
scheme_rt_marshal_info, /* 268 */
|
scheme_rt_marshal_info, /* 269 */
|
||||||
scheme_rt_unmarshal_info, /* 269 */
|
scheme_rt_unmarshal_info, /* 270 */
|
||||||
scheme_rt_runstack, /* 270 */
|
scheme_rt_runstack, /* 271 */
|
||||||
scheme_rt_sfs_info, /* 271 */
|
scheme_rt_sfs_info, /* 272 */
|
||||||
scheme_rt_validate_clearing, /* 272 */
|
scheme_rt_validate_clearing, /* 273 */
|
||||||
scheme_rt_lightweight_cont, /* 273 */
|
scheme_rt_lightweight_cont, /* 274 */
|
||||||
scheme_rt_export_info, /* 274 */
|
scheme_rt_export_info, /* 275 */
|
||||||
scheme_rt_cont_jmp, /* 275 */
|
scheme_rt_cont_jmp, /* 276 */
|
||||||
scheme_rt_letrec_check_frame, /* 276 */
|
scheme_rt_letrec_check_frame, /* 277 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_scheme_last_type_
|
_scheme_last_type_
|
||||||
|
|
|
@ -740,6 +740,7 @@ void scheme_register_traversers(void)
|
||||||
|
|
||||||
GC_REG_TRAV(scheme_proc_shape_type, small_atomic_obj);
|
GC_REG_TRAV(scheme_proc_shape_type, small_atomic_obj);
|
||||||
GC_REG_TRAV(scheme_struct_proc_shape_type, struct_proc_shape);
|
GC_REG_TRAV(scheme_struct_proc_shape_type, struct_proc_shape);
|
||||||
|
GC_REG_TRAV(scheme_struct_prop_proc_shape_type, small_atomic_obj);
|
||||||
|
|
||||||
GC_REG_TRAV(scheme_environment_variables_type, small_object);
|
GC_REG_TRAV(scheme_environment_variables_type, small_object);
|
||||||
GC_REG_TRAV(scheme_syntax_property_preserve_type, small_object);
|
GC_REG_TRAV(scheme_syntax_property_preserve_type, small_object);
|
||||||
|
|
|
@ -123,13 +123,19 @@ static void noclear_stack_push(struct Validate_Clearing *vc, int pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void add_struct_mapping(Scheme_Hash_Table **_st_ht, int pos, int shape)
|
static void add_struct_mapping(Scheme_Hash_Table **_st_ht, int pos, int shape, int for_property)
|
||||||
{
|
{
|
||||||
if (!*_st_ht) {
|
if (!*_st_ht) {
|
||||||
Scheme_Hash_Table *ht;
|
Scheme_Hash_Table *ht;
|
||||||
ht = scheme_make_hash_table_eqv();
|
ht = scheme_make_hash_table_eqv();
|
||||||
*_st_ht = ht;
|
*_st_ht = ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (for_property) {
|
||||||
|
/* negative value is for a structure type property: */
|
||||||
|
shape = -(shape+1);
|
||||||
|
}
|
||||||
|
|
||||||
scheme_hash_set(*_st_ht,
|
scheme_hash_set(*_st_ht,
|
||||||
scheme_make_integer(pos),
|
scheme_make_integer(pos),
|
||||||
scheme_make_integer(shape));
|
scheme_make_integer(shape));
|
||||||
|
@ -185,7 +191,9 @@ void scheme_validate_code(Mz_CPort *port, Scheme_Object *code,
|
||||||
intptr_t k;
|
intptr_t k;
|
||||||
tl_state[i] = SCHEME_TOPLEVEL_CONST;
|
tl_state[i] = SCHEME_TOPLEVEL_CONST;
|
||||||
if (scheme_decode_struct_shape(((Module_Variable *)toplevels[i])->shape, &k))
|
if (scheme_decode_struct_shape(((Module_Variable *)toplevels[i])->shape, &k))
|
||||||
add_struct_mapping(_st_ht, i, k);
|
add_struct_mapping(_st_ht, i, k, 0);
|
||||||
|
else if (scheme_decode_struct_prop_shape(((Module_Variable *)toplevels[i])->shape, &k))
|
||||||
|
add_struct_mapping(_st_ht, i, k, 1);
|
||||||
} else if (mv_flags & SCHEME_MODVAR_FIXED)
|
} else if (mv_flags & SCHEME_MODVAR_FIXED)
|
||||||
tl_state[i] = SCHEME_TOPLEVEL_FIXED;
|
tl_state[i] = SCHEME_TOPLEVEL_FIXED;
|
||||||
else
|
else
|
||||||
|
@ -295,7 +303,7 @@ static int define_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||||
Scheme_Hash_Tree *procs,
|
Scheme_Hash_Tree *procs,
|
||||||
Scheme_Hash_Table **_st_ht)
|
Scheme_Hash_Table **_st_ht)
|
||||||
{
|
{
|
||||||
int i, size, flags, result, is_struct;
|
int i, size, flags, result, is_struct, is_struct_prop, has_guard;
|
||||||
Simple_Stuct_Type_Info stinfo;
|
Simple_Stuct_Type_Info stinfo;
|
||||||
Scheme_Object *val, *only_var;
|
Scheme_Object *val, *only_var;
|
||||||
|
|
||||||
|
@ -399,7 +407,8 @@ static int define_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||||
only_var = NULL;
|
only_var = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scheme_is_simple_make_struct_type(val, size-1, 1, 0, 1, NULL,
|
if (scheme_is_simple_make_struct_type(val, size-1, CHECK_STRUCT_TYPE_RESOLVED,
|
||||||
|
NULL,
|
||||||
&stinfo, NULL,
|
&stinfo, NULL,
|
||||||
NULL, NULL, (_st_ht ? *_st_ht : NULL),
|
NULL, NULL, (_st_ht ? *_st_ht : NULL),
|
||||||
NULL, 0, NULL, NULL, NULL, 5)) {
|
NULL, 0, NULL, NULL, NULL, 5)) {
|
||||||
|
@ -411,6 +420,16 @@ static int define_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||||
is_struct = 0;
|
is_struct = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has_guard = 0;
|
||||||
|
if (scheme_is_simple_make_struct_type_property(val, size-1, CHECK_STRUCT_TYPE_RESOLVED,
|
||||||
|
&has_guard,
|
||||||
|
NULL, NULL, (_st_ht ? *_st_ht : NULL),
|
||||||
|
NULL, 0, NULL, NULL, 5)) {
|
||||||
|
is_struct_prop = 1;
|
||||||
|
} else {
|
||||||
|
is_struct_prop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
result = validate_expr(port, val, stack, tls,
|
result = validate_expr(port, val, stack, tls,
|
||||||
depth, letlimit, delta,
|
depth, letlimit, delta,
|
||||||
num_toplevels, num_stxes, num_lifts, tl_use_map,
|
num_toplevels, num_stxes, num_lifts, tl_use_map,
|
||||||
|
@ -430,7 +449,22 @@ static int define_values_validate(Scheme_Object *data, Mz_CPort *port,
|
||||||
|| (stinfo.field_count == stinfo.init_field_count))
|
|| (stinfo.field_count == stinfo.init_field_count))
|
||||||
add_struct_mapping(_st_ht,
|
add_struct_mapping(_st_ht,
|
||||||
SCHEME_TOPLEVEL_POS(SCHEME_VEC_ELS(data)[i]),
|
SCHEME_TOPLEVEL_POS(SCHEME_VEC_ELS(data)[i]),
|
||||||
scheme_get_struct_proc_shape(i-1, &stinfo));
|
scheme_get_struct_proc_shape(i-1, &stinfo),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* In any case, treat the bindings as constant */
|
||||||
|
result = 2;
|
||||||
|
} else if (is_struct_prop) {
|
||||||
|
if (_st_ht) {
|
||||||
|
/* Record `prop:' binding as constant across invocations,
|
||||||
|
so that it can be recognized for struct declarations,
|
||||||
|
and so on: */
|
||||||
|
for (i = 1; i < size; i++) {
|
||||||
|
add_struct_mapping(_st_ht,
|
||||||
|
SCHEME_TOPLEVEL_POS(SCHEME_VEC_ELS(data)[i]),
|
||||||
|
scheme_get_struct_property_proc_shape(i-1, has_guard),
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* In any case, treat the bindings as constant */
|
/* In any case, treat the bindings as constant */
|
||||||
|
@ -1385,10 +1419,12 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr,
|
||||||
} else {
|
} else {
|
||||||
/* check expectation */
|
/* check expectation */
|
||||||
if (((tl_state[p] & SCHEME_TOPLEVEL_FLAGS_MASK) < flags)
|
if (((tl_state[p] & SCHEME_TOPLEVEL_FLAGS_MASK) < flags)
|
||||||
|| ((tl_state[p] >> 2) > tl_timestamp))
|
|| ((tl_state[p] >> 2) > tl_timestamp)) {
|
||||||
|
printf("?? %d\n", p);
|
||||||
scheme_ill_formed_code(port);
|
scheme_ill_formed_code(port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((proc_with_refs_ok != 1)
|
if ((proc_with_refs_ok != 1)
|
||||||
&& !argument_to_arity_error(app_rator, proc_with_refs_ok)) {
|
&& !argument_to_arity_error(app_rator, proc_with_refs_ok)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user