Replace ratio and complex built-in types with tuples defined in the library. This frees up two lo-tags, so move array and quotation over to these tags and update compiler for new tags

db4
Slava Pestov 2009-04-30 00:27:35 -05:00
parent 9f4ac667dc
commit fc4894fbdf
44 changed files with 265 additions and 312 deletions

View File

@ -27,11 +27,11 @@ IN: compiler.cfg.intrinsics.allot
[ tuple ##set-slots ] [ ds-push drop ] 2bi
] [ drop emit-primitive ] if ;
: store-length ( len reg -- )
[ ^^load-literal ] dip 1 object tag-number ##set-slot-imm ;
: store-length ( len reg class -- )
[ [ ^^load-literal ] dip 1 ] dip tag-number ##set-slot-imm ;
: store-initial-element ( elt reg len -- )
[ 2 + object tag-number ##set-slot-imm ] with with each ;
:: store-initial-element ( len reg elt class -- )
len [ [ elt reg ] dip 2 + class tag-number ##set-slot-imm ] each ;
: expand-<array>? ( obj -- ? )
dup integer? [ 0 8 between? ] [ drop f ] if ;
@ -42,8 +42,8 @@ IN: compiler.cfg.intrinsics.allot
[let | elt [ ds-pop ]
reg [ len ^^allot-array ] |
ds-drop
len reg store-length
elt reg len store-initial-element
len reg array store-length
len reg elt array store-initial-element
reg ds-push
]
] [ node emit-primitive ] if
@ -57,16 +57,16 @@ IN: compiler.cfg.intrinsics.allot
: emit-allot-byte-array ( len -- dst )
ds-drop
dup ^^allot-byte-array
[ store-length ] [ ds-push ] [ ] tri ;
[ byte-array store-length ] [ ds-push ] [ ] tri ;
: emit-(byte-array) ( node -- )
dup node-input-infos first literal>> dup expand-<byte-array>?
[ nip emit-allot-byte-array drop ] [ drop emit-primitive ] if ;
: emit-<byte-array> ( node -- )
dup node-input-infos first literal>> dup expand-<byte-array>? [
nip
[ 0 ^^load-literal ] dip
[ emit-allot-byte-array ] keep
bytes>cells store-initial-element
] [ drop emit-primitive ] if ;
:: emit-<byte-array> ( node -- )
node node-input-infos first literal>> dup expand-<byte-array>? [
:> len
0 ^^load-literal :> elt
len emit-allot-byte-array :> reg
len reg elt byte-array store-initial-element
] [ drop node emit-primitive ] if ;

View File

@ -52,8 +52,6 @@ IN: compiler.cfg.intrinsics
arrays:<array>
byte-arrays:<byte-array>
byte-arrays:(byte-array)
math.private:<complex>
math.private:<ratio>
kernel:<wrapper>
alien.accessors:alien-unsigned-1
alien.accessors:set-alien-unsigned-1
@ -140,8 +138,6 @@ IN: compiler.cfg.intrinsics
{ \ arrays:<array> [ emit-<array> iterate-next ] }
{ \ byte-arrays:<byte-array> [ emit-<byte-array> iterate-next ] }
{ \ byte-arrays:(byte-array) [ emit-(byte-array) iterate-next ] }
{ \ math.private:<complex> [ emit-simple-allot iterate-next ] }
{ \ math.private:<ratio> [ emit-simple-allot iterate-next ] }
{ \ kernel:<wrapper> [ emit-simple-allot iterate-next ] }
{ \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter iterate-next ] }
{ \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter iterate-next ] }

View File

@ -342,12 +342,12 @@ cell 8 = [
] unit-test
[ 1 2 ] [
1 2 [ <complex> ] compile-call
1 2 [ complex boa ] compile-call
dup real-part swap imaginary-part
] unit-test
[ 1 2 ] [
1 2 [ <ratio> ] compile-call dup numerator swap denominator
1 2 [ ratio boa ] compile-call dup numerator swap denominator
] unit-test
[ \ + ] [ \ + [ <wrapper> ] compile-call ] unit-test

View File

@ -12,7 +12,6 @@ M: #push run-escape-analysis*
M: #call run-escape-analysis*
{
{ [ dup word>> \ <complex> eq? ] [ t ] }
{ [ dup immutable-tuple-boa? ] [ t ] }
[ f ]
} cond nip ;

View File

@ -17,7 +17,7 @@ GENERIC: count-unboxed-allocations* ( m node -- n )
out-d>> first escaping-allocation? [ 1+ ] unless ;
M: #call count-unboxed-allocations*
dup [ immutable-tuple-boa? ] [ word>> \ <complex> eq? ] bi or
dup immutable-tuple-boa?
[ (count-unboxed-allocations) ] [ drop ] if ;
M: #push count-unboxed-allocations*
@ -291,7 +291,7 @@ C: <ro-box> ro-box
[ 0 ] [ [ bad-tuple-fib-3 i>> ] count-unboxed-allocations ] unit-test
[ 1 ] [ [ <complex> >rect ] count-unboxed-allocations ] unit-test
[ 1 ] [ [ complex boa >rect ] count-unboxed-allocations ] unit-test
[ 0 ] [ [ 1 cons boa 2 cons boa ] count-unboxed-allocations ] unit-test

View File

@ -47,9 +47,6 @@ M: #push escape-analysis*
[ record-unknown-allocation ]
if ;
: record-complex-allocation ( #call -- )
[ in-d>> ] [ out-d>> first ] bi record-allocation ;
: slot-offset ( #call -- n/f )
dup in-d>>
[ first node-value-info class>> ]
@ -71,7 +68,6 @@ M: #push escape-analysis*
M: #call escape-analysis*
dup word>> {
{ \ <tuple-boa> [ record-tuple-allocation ] }
{ \ <complex> [ record-complex-allocation ] }
{ \ slot [ record-slot-call ] }
[ drop record-unknown-allocation ]
} case ;

View File

@ -357,7 +357,7 @@ TUPLE: immutable-prop-test-tuple { x sequence read-only } ;
] unit-test
[ V{ complex } ] [
[ <complex> ] final-classes
[ complex boa ] final-classes
] unit-test
[ V{ complex } ] [
@ -375,7 +375,7 @@ TUPLE: immutable-prop-test-tuple { x sequence read-only } ;
[ V{ complex } ] [
[
{ float float object } declare
[ "Oops" throw ] [ <complex> ] if
[ "Oops" throw ] [ complex boa ] if
] final-classes
] unit-test
@ -590,7 +590,7 @@ MIXIN: empty-mixin
[ V{ float } ] [
[
[ { float float } declare <complex> ]
[ { float float } declare complex boa ]
[ 2drop C{ 0.0 0.0 } ]
if real-part
] final-classes

View File

@ -109,7 +109,7 @@ M: #declare propagate-before
: output-value-infos ( #call word -- infos )
{
{ [ dup tuple-constructor? ] [ propagate-tuple-constructor ] }
{ [ dup \ <tuple-boa> eq? ] [ drop propagate-<tuple-boa> ] }
{ [ dup sequence-constructor? ] [ propagate-sequence-constructor ] }
{ [ dup predicate? ] [ propagate-predicate ] }
{ [ dup "outputs" word-prop ] [ call-outputs-quot ] }

View File

@ -29,9 +29,6 @@ UNION: fixed-length-sequence array byte-array string ;
[ constructor-output-class <class-info> ]
bi* value-info-intersect 1array ;
: tuple-constructor? ( word -- ? )
{ <tuple-boa> <complex> } memq? ;
: fold-<tuple-boa> ( values class -- info )
[ [ literal>> ] map ] dip prefix >tuple
<literal-info> ;
@ -44,18 +41,9 @@ UNION: fixed-length-sequence array byte-array string ;
<tuple-info>
] if ;
: propagate-<tuple-boa> ( #call -- info )
: propagate-<tuple-boa> ( #call -- infos )
in-d>> unclip-last
value-info literal>> first (propagate-tuple-constructor) ;
: propagate-<complex> ( #call -- info )
in-d>> [ value-info ] map complex <tuple-info> ;
: propagate-tuple-constructor ( #call word -- infos )
{
{ \ <tuple-boa> [ propagate-<tuple-boa> ] }
{ \ <complex> [ propagate-<complex> ] }
} case 1array ;
value-info literal>> first (propagate-tuple-constructor) 1array ;
: read-only-slot? ( n class -- ? )
all-slots [ offset>> = ] with find nip

View File

@ -32,7 +32,6 @@ TUPLE: empty-tuple ;
[ dup [ drop f ] [ "A" throw ] if ]
[ [ ] [ ] curry curry dup 2 slot swap 3 slot dup 2 slot swap 3 slot drop ]
[ [ ] [ ] curry curry call ]
[ <complex> <complex> dup 1 slot drop 2 slot drop ]
[ 1 cons boa over [ "A" throw ] when car>> ]
[ [ <=> ] sort ]
[ [ <=> ] with search ]

View File

@ -36,9 +36,6 @@ M: #push unbox-tuples* ( #push -- nodes )
: unbox-<tuple-boa> ( #call -- nodes )
dup unbox-output? [ in-d>> 1 tail* #drop ] when ;
: unbox-<complex> ( #call -- nodes )
dup unbox-output? [ drop { } ] when ;
: (flatten-values) ( values accum -- )
dup '[
dup unboxed-allocation
@ -70,7 +67,6 @@ M: #push unbox-tuples* ( #push -- nodes )
M: #call unbox-tuples*
dup word>> {
{ \ <tuple-boa> [ unbox-<tuple-boa> ] }
{ \ <complex> [ unbox-<complex> ] }
{ \ slot [ unbox-slot-access ] }
[ drop ]
} case ;

View File

@ -25,7 +25,3 @@ HELP: complex
{ $class-description "The class of complex numbers with non-zero imaginary part." } ;
ABOUT: "complex-numbers"
HELP: <complex> ( x y -- z )
{ $values { "x" "a real number" } { "y" "a real number" } { "z" "a complex number" } }
{ $description "Low-level complex number constructor. User code should call " { $link rect> } " instead." } ;

View File

@ -15,14 +15,14 @@ M: complex hashcode* nip >rect [ hashcode ] bi@ bitxor ;
: complex= ( x y quot -- ? ) componentwise and ; inline
M: complex equal? over complex? [ [ = ] complex= ] [ 2drop f ] if ;
M: complex number= [ number= ] complex= ;
: complex-op ( x y quot -- z ) componentwise (rect>) ; inline
: complex-op ( x y quot -- z ) componentwise rect> ; inline
M: complex + [ + ] complex-op ;
M: complex - [ - ] complex-op ;
: *re ( x y -- xr*yr xi*yi ) [ >rect ] bi@ [ * ] bi-curry@ bi* ; inline
: *im ( x y -- xi*yr xr*yi ) swap [ >rect ] bi@ swap [ * ] bi-curry@ bi* ; inline
M: complex * [ *re - ] [ *im + ] 2bi (rect>) ;
M: complex * [ *re - ] [ *im + ] 2bi rect> ;
: (complex/) ( x y -- r i m ) [ [ *re + ] [ *im - ] 2bi ] keep absq ; inline
: complex/ ( x y quot -- z ) [ (complex/) ] dip curry bi@ (rect>) ; inline
: complex/ ( x y quot -- z ) [ (complex/) ] dip curry bi@ rect> ; inline
M: complex / [ / ] complex/ ;
M: complex /f [ /f ] complex/ ;
M: complex /i [ /i ] complex/ ;

View File

@ -100,11 +100,6 @@ ARTICLE: "math-functions" "Mathematical functions"
ABOUT: "math-functions"
HELP: (rect>)
{ $values { "x" real } { "y" real } { "z" number } }
{ $description "Creates a complex number from real and imaginary components." }
{ $warning "This word does not check that the arguments are real numbers, which can have undefined consequences. Use the " { $link rect> } " word instead." } ;
HELP: rect>
{ $values { "x" real } { "y" real } { "z" number } }
{ $description "Creates a complex number from real and imaginary components. If " { $snippet "z" } " is an integer zero, this will simply output " { $snippet "x" } "." } ;

View File

@ -7,19 +7,8 @@ IN: math.functions
: >fraction ( a/b -- a b )
[ numerator ] [ denominator ] bi ; inline
<PRIVATE
: (rect>) ( x y -- z )
dup 0 = [ drop ] [ <complex> ] if ; inline
PRIVATE>
: rect> ( x y -- z )
2dup [ real? ] both? [
(rect>)
] [
"Complex number must have real components" throw
] if ; inline
dup 0 = [ drop ] [ complex boa ] if ; inline
GENERIC: sqrt ( x -- y ) foldable

View File

@ -47,6 +47,3 @@ HELP: 2>fraction
{ $values { "a/b" rational } { "c/d" rational } { "a" integer } { "c" integer } { "b" "a positive integer" } { "d" "a positive integer" } }
{ $description "Extracts the numerator and denominator of two rational numbers at once." } ;
HELP: <ratio> ( a b -- a/b )
{ $values { "a" integer } { "b" integer } { "a/b" "a ratio" } }
{ $description "Primitive ratio constructor. User code should call " { $link / } " to create ratios instead." } ;

View File

@ -9,7 +9,7 @@ IN: math.ratios
<PRIVATE
: fraction> ( a b -- a/b )
dup 1 number= [ drop ] [ <ratio> ] if ; inline
dup 1 number= [ drop ] [ ratio boa ] if ; inline
: scale ( a/b c/d -- a*d b*c )
2>fraction [ * swap ] dip * swap ; inline

View File

@ -286,9 +286,6 @@ M: object infer-call*
\ bignum>float { bignum } { float } define-primitive
\ bignum>float make-foldable
\ <ratio> { integer integer } { ratio } define-primitive
\ <ratio> make-foldable
\ string>float { string } { float } define-primitive
\ string>float make-foldable
@ -307,9 +304,6 @@ M: object infer-call*
\ bits>double { integer } { float } define-primitive
\ bits>double make-foldable
\ <complex> { real real } { complex } define-primitive
\ <complex> make-foldable
\ both-fixnums? { object object } { object } define-primitive
\ fixnum+ { fixnum fixnum } { integer } define-primitive

View File

@ -1,4 +1,4 @@
! Copyright (C) 2007, 2008 Slava Pestov.
! Copyright (C) 2007, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces math words kernel alien byte-arrays
hashtables vectors strings sbufs arrays
@ -9,14 +9,14 @@ BIN: 111 tag-mask set
8 num-tags set
3 tag-bits set
17 num-types set
15 num-types set
H{
{ fixnum BIN: 000 }
{ bignum BIN: 001 }
{ ratio BIN: 010 }
{ array BIN: 010 }
{ float BIN: 011 }
{ complex BIN: 100 }
{ quotation BIN: 100 }
{ POSTPONE: f BIN: 101 }
{ object BIN: 110 }
{ hi-tag BIN: 110 }
@ -24,13 +24,11 @@ H{
} tag-numbers set
tag-numbers get H{
{ array 8 }
{ wrapper 9 }
{ byte-array 10 }
{ callstack 11 }
{ string 12 }
{ word 13 }
{ quotation 14 }
{ dll 15 }
{ alien 16 }
{ wrapper 8 }
{ byte-array 9 }
{ callstack 10 }
{ string 11 }
{ word 12 }
{ dll 13 }
{ alien 14 }
} assoc-union type-numbers set

View File

@ -126,9 +126,7 @@ bootstrapping? on
"fixnum" "math" create register-builtin
"bignum" "math" create register-builtin
"tuple" "kernel" create register-builtin
"ratio" "math" create register-builtin
"float" "math" create register-builtin
"complex" "math" create register-builtin
"f" "syntax" lookup register-builtin
"array" "arrays" create register-builtin
"wrapper" "kernel" create register-builtin
@ -147,24 +145,6 @@ bootstrapping? on
"f?" "syntax" vocab-words delete-at
! Some unions
"integer" "math" create
"fixnum" "math" lookup
"bignum" "math" lookup
2array
define-union-class
"rational" "math" create
"integer" "math" lookup
"ratio" "math" lookup
2array
define-union-class
"real" "math" create
"rational" "math" lookup
"float" "math" lookup
2array
define-union-class
"c-ptr" "alien" create [
"alien" "alien" lookup ,
"f" "syntax" lookup ,
@ -211,19 +191,9 @@ bi
"bignum" "math" create { } define-builtin
"bignum" "math" create ">bignum" "math" create 1quotation "coercer" set-word-prop
"ratio" "math" create {
{ "numerator" { "integer" "math" } read-only }
{ "denominator" { "integer" "math" } read-only }
} define-builtin
"float" "math" create { } define-builtin
"float" "math" create ">float" "math" create 1quotation "coercer" set-word-prop
"complex" "math" create {
{ "real" { "real" "math" } read-only }
{ "imaginary" { "real" "math" } read-only }
} define-builtin
"array" "arrays" create {
{ "length" { "array-capacity" "sequences.private" } read-only }
} define-builtin
@ -395,14 +365,12 @@ tuple
{ "float>bignum" "math.private" (( x -- y )) }
{ "fixnum>float" "math.private" (( x -- y )) }
{ "bignum>float" "math.private" (( x -- y )) }
{ "<ratio>" "math.private" (( a b -- a/b )) }
{ "string>float" "math.private" (( str -- n/f )) }
{ "float>string" "math.private" (( n -- str )) }
{ "float>bits" "math" (( x -- n )) }
{ "double>bits" "math" (( x -- n )) }
{ "bits>float" "math" (( n -- x )) }
{ "bits>double" "math" (( n -- x )) }
{ "<complex>" "math.private" (( x y -- z )) }
{ "fixnum+" "math.private" (( x y -- z )) }
{ "fixnum-" "math.private" (( x y -- z )) }
{ "fixnum*" "math.private" (( x y -- z )) }

View File

@ -1,5 +1,5 @@
USING: kernel generic help.markup help.syntax math classes
sequences quotations ;
sequences quotations generic.math.private ;
IN: generic.math
HELP: math-upgrade

View File

@ -1,9 +1,9 @@
! Copyright (C) 2005, 2008 Slava Pestov.
! Copyright (C) 2005, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays generic hashtables kernel kernel.private math
namespaces make sequences words quotations layouts combinators
namespaces sequences words quotations layouts combinators
sequences.private classes classes.builtin classes.algebra
definitions math.order math.private ;
definitions math.order math.private assocs ;
IN: generic.math
PREDICATE: math-class < class
@ -13,24 +13,30 @@ PREDICATE: math-class < class
number bootstrap-word class<=
] if ;
<PRIVATE
: last/first ( seq -- pair ) [ peek ] [ first ] bi 2array ;
: math-precedence ( class -- pair )
{
{ [ dup null class<= ] [ drop { -1 -1 } ] }
{ [ dup math-class? ] [ class-types last/first ] }
[ drop { 100 100 } ]
} cond ;
: math-class<=> ( class1 class2 -- class )
[ math-precedence ] compare +gt+ eq? ;
: bootstrap-words ( classes -- classes' )
[ bootstrap-word ] map ;
: math-class-max ( class1 class2 -- class )
[ math-class<=> ] most ;
: math-precedence ( class -- pair )
[
{ null fixnum bignum ratio float complex object } bootstrap-words
swap [ class<= ] curry find drop
] [
{ null fixnum integer rational real number object } bootstrap-words
swap [ swap class<= ] curry find drop
] bi 2array ;
: (math-upgrade) ( max class -- quot )
dupd = [ drop [ ] ] [ "coercer" word-prop [ ] or ] if ;
PRIVATE>
: math-class-max ( class1 class2 -- class )
[ [ math-precedence ] bi@ after? ] most ;
: math-upgrade ( class1 class2 -- quot )
[ math-class-max ] 2keep
[
@ -44,33 +50,57 @@ ERROR: no-math-method left right generic ;
: default-math-method ( generic -- quot )
[ no-math-method ] curry [ ] like ;
<PRIVATE
: applicable-method ( generic class -- quot )
over method
[ 1quotation ]
[ default-math-method ] ?if ;
PRIVATE>
: object-method ( generic -- quot )
object bootstrap-word applicable-method ;
: math-method ( word class1 class2 -- quot )
2dup and [
[
2dup 2array , \ declare ,
2dup math-upgrade %
math-class-max over order min-class applicable-method %
] [ ] make
[ 2array [ declare ] curry nip ]
[ math-upgrade nip ]
[ math-class-max over order min-class applicable-method ]
3tri 3append
] [
2drop object-method
] if ;
SYMBOL: picker
<PRIVATE
: math-vtable ( picker quot -- quot )
[
[ , \ tag , ]
[ num-tags get swap [ bootstrap-type>class ] prepose map , ] bi*
\ dispatch ,
] [ ] make ; inline
SYMBOL: generic-word
: make-math-method-table ( classes quot: ( class -- quot ) -- alist )
[ bootstrap-words ] dip
[ [ drop ] [ call ] 2bi ] curry { } map>assoc ; inline
: math-alist>quot ( alist -- quot )
[ generic-word get object-method ] dip alist>quot ;
: tag-dispatch-entry ( tag picker -- quot )
[ "type" word-prop 1quotation [ tag ] [ eq? ] surround ] dip prepend ;
: tag-dispatch ( picker alist -- alist' )
swap [ [ tag-dispatch-entry ] curry dip ] curry assoc-map math-alist>quot ;
: tuple-dispatch-entry ( class picker -- quot )
[ 1quotation [ { tuple } declare class ] [ eq? ] surround ] dip prepend ;
: tuple-dispatch ( picker alist -- alist' )
swap [ [ tuple-dispatch-entry ] curry dip ] curry assoc-map math-alist>quot ;
: math-dispatch-step ( picker quot: ( class -- quot ) -- quot )
[ [ { bignum float fixnum } ] dip make-math-method-table ]
[ [ { ratio complex } ] dip make-math-method-table tuple-dispatch ] 2bi
tuple swap 2array prefix tag-dispatch ; inline
PRIVATE>
SINGLETON: math-combination
@ -78,20 +108,21 @@ M: math-combination make-default-method
drop default-math-method ;
M: math-combination perform-combination
drop
dup
[
[ 2dup both-fixnums? ] %
dup fixnum bootstrap-word dup math-method ,
\ over [
dup math-class? [
\ dup [ [ 2dup ] dip math-method ] math-vtable
] [
over object-method
] if nip
] math-vtable nip ,
\ if ,
] [ ] make define ;
drop dup generic-word [
dup
[ fixnum bootstrap-word dup math-method ]
[
[ over ] [
dup math-class? [
[ dup ] [ math-method ] with with math-dispatch-step
] [
drop object-method
] if
] with math-dispatch-step
] bi
[ if ] 2curry [ 2dup both-fixnums? ] prepend
define
] with-variable ;
PREDICATE: math-generic < generic ( word -- ? )
"combination" word-prop math-combination? ;

View File

@ -1,4 +1,4 @@
! Copyright (C) 2003, 2008 Slava Pestov.
! Copyright (C) 2003, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math.private ;
IN: math
@ -63,23 +63,22 @@ PRIVATE>
: neg ( x -- -x ) 0 swap - ; inline
: recip ( x -- y ) 1 swap / ; inline
: sgn ( x -- n ) dup 0 < [ drop -1 ] [ 0 > 1 0 ? ] if ; inline
: ?1+ ( x -- y ) [ 1+ ] [ 0 ] if* ; inline
: rem ( x y -- z ) abs [ mod ] [ + ] [ mod ] tri ; foldable
: 2^ ( n -- 2^n ) 1 swap shift ; inline
: even? ( n -- ? ) 1 bitand zero? ;
: odd? ( n -- ? ) 1 bitand 1 number= ;
UNION: integer fixnum bignum ;
TUPLE: ratio { numerator integer read-only } { denominator integer read-only } ;
UNION: rational integer ratio ;
UNION: real rational float ;
TUPLE: complex { real real read-only } { imaginary real read-only } ;
UNION: number real complex ;
GENERIC: fp-nan? ( x -- ? )

View File

@ -34,7 +34,7 @@ void primitive_array(void)
{
CELL initial = dpop();
CELL size = unbox_array_size();
dpush(tag_object(allot_array(ARRAY_TYPE,size,initial)));
dpush(tag_array(allot_array(ARRAY_TYPE,size,initial)));
}
CELL allot_array_1(CELL obj)
@ -43,7 +43,7 @@ CELL allot_array_1(CELL obj)
F_ARRAY *a = allot_array_internal(ARRAY_TYPE,1);
UNREGISTER_ROOT(obj);
set_array_nth(a,0,obj);
return tag_object(a);
return tag_array(a);
}
CELL allot_array_2(CELL v1, CELL v2)
@ -55,7 +55,7 @@ CELL allot_array_2(CELL v1, CELL v2)
UNREGISTER_ROOT(v1);
set_array_nth(a,0,v1);
set_array_nth(a,1,v2);
return tag_object(a);
return tag_array(a);
}
CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4)
@ -73,35 +73,48 @@ CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4)
set_array_nth(a,1,v2);
set_array_nth(a,2,v3);
set_array_nth(a,3,v4);
return tag_object(a);
return tag_array(a);
}
F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity)
static bool reallot_array_in_place_p(F_ARRAY *array, CELL capacity)
{
return in_zone(&nursery,(CELL)array) && capacity <= array_capacity(array);
}
F_ARRAY *reallot_array(F_ARRAY *array, CELL capacity)
{
#ifdef FACTOR_DEBUG
CELL header = untag_header(array->header);
assert(header == ARRAY_TYPE || header == BIGNUM_TYPE);
#endif
CELL to_copy = array_capacity(array);
if(capacity < to_copy)
if(reallot_array_in_place_p(array,capacity))
{
array->capacity = tag_fixnum(capacity);
return array;
}
else
{
CELL to_copy = array_capacity(array);
if(capacity < to_copy)
to_copy = capacity;
REGISTER_UNTAGGED(array);
F_ARRAY* new_array = allot_array_internal(untag_header(array->header),capacity);
UNREGISTER_UNTAGGED(array);
REGISTER_UNTAGGED(array);
F_ARRAY* new_array = allot_array_internal(untag_header(array->header),capacity);
UNREGISTER_UNTAGGED(array);
memcpy(new_array + 1,array + 1,to_copy * CELLS);
memset((char *)AREF(new_array,to_copy),'\0',(capacity - to_copy) * CELLS);
memcpy(new_array + 1,array + 1,to_copy * CELLS);
memset((char *)AREF(new_array,to_copy),'\0',(capacity - to_copy) * CELLS);
return new_array;
return new_array;
}
}
void primitive_resize_array(void)
{
F_ARRAY* array = untag_array(dpop());
CELL capacity = unbox_array_size();
dpush(tag_object(reallot_array(array,capacity)));
dpush(tag_array(reallot_array(array,capacity)));
}
void growable_array_add(F_GROWABLE_ARRAY *array, CELL elt)
@ -112,7 +125,7 @@ void growable_array_add(F_GROWABLE_ARRAY *array, CELL elt)
if(array->count == array_capacity(underlying))
{
underlying = reallot_array(underlying,array->count * 2);
array->array = tag_object(underlying);
array->array = tag_array(underlying);
}
UNREGISTER_ROOT(elt);
@ -131,7 +144,7 @@ void growable_array_append(F_GROWABLE_ARRAY *array, F_ARRAY *elts)
if(new_size >= array_capacity(underlying))
{
underlying = reallot_array(underlying,new_size * 2);
array->array = tag_object(underlying);
array->array = tag_array(underlying);
}
UNREGISTER_UNTAGGED(elts);

View File

@ -1,5 +1,10 @@
DEFINE_UNTAG(F_ARRAY,ARRAY_TYPE,array)
INLINE CELL tag_array(F_ARRAY *array)
{
return RETAG(array,ARRAY_TYPE);
}
/* Inline functions */
INLINE CELL array_size(CELL size)
{
@ -61,7 +66,7 @@ INLINE F_GROWABLE_ARRAY make_growable_array(void)
{
F_GROWABLE_ARRAY result;
result.count = 0;
result.array = tag_object(allot_array(ARRAY_TYPE,100,F));
result.array = tag_array(allot_array(ARRAY_TYPE,100,F));
return result;
}
@ -80,7 +85,7 @@ void growable_array_append(F_GROWABLE_ARRAY *result, F_ARRAY *elts);
INLINE void growable_array_trim(F_GROWABLE_ARRAY *array)
{
array->array = tag_object(reallot_array(untag_object(array->array),array->count));
array->array = tag_array(reallot_array(untag_object(array->array),array->count));
}
#define GROWABLE_ARRAY_TRIM(result) growable_array_trim(&result##_g)

View File

@ -30,23 +30,35 @@ void primitive_uninitialized_byte_array(void)
dpush(tag_object(allot_byte_array_internal(size)));
}
static bool reallot_byte_array_in_place_p(F_BYTE_ARRAY *array, CELL capacity)
{
return in_zone(&nursery,(CELL)array) && capacity <= array_capacity(array);
}
F_BYTE_ARRAY *reallot_byte_array(F_BYTE_ARRAY *array, CELL capacity)
{
#ifdef FACTOR_DEBUG
assert(untag_header(array->header) == BYTE_ARRAY_TYPE);
#endif
CELL to_copy = array_capacity(array);
if(capacity < to_copy)
if(reallot_byte_array_in_place_p(array,capacity))
{
array->capacity = tag_fixnum(capacity);
return array;
}
else
{
CELL to_copy = array_capacity(array);
if(capacity < to_copy)
to_copy = capacity;
REGISTER_UNTAGGED(array);
F_BYTE_ARRAY *new_array = allot_byte_array_internal(capacity);
UNREGISTER_UNTAGGED(array);
REGISTER_UNTAGGED(array);
F_BYTE_ARRAY *new_array = allot_byte_array_internal(capacity);
UNREGISTER_UNTAGGED(array);
memcpy(new_array + 1,array + 1,to_copy);
memcpy(new_array + 1,array + 1,to_copy);
return new_array;
return new_array;
}
}
void primitive_resize_byte_array(void)

View File

@ -170,7 +170,7 @@ void primitive_callstack_to_array(void)
frame_index = 0;
iterate_callstack_object(stack,stack_frame_to_array);
dpush(tag_object(array));
dpush(tag_array(array));
}
F_STACK_FRAME *innermost_stack_frame(F_CALLSTACK *callstack)
@ -214,7 +214,7 @@ void primitive_set_innermost_stack_frame_quot(void)
REGISTER_UNTAGGED(callstack);
REGISTER_UNTAGGED(quot);
jit_compile(tag_object(quot),true);
jit_compile(tag_quotation(quot),true);
UNREGISTER_UNTAGGED(quot);
UNREGISTER_UNTAGGED(callstack);

View File

@ -29,7 +29,7 @@ and the callstack top is passed in EDX */
pop %ebp ; \
pop %ebx
#define QUOT_XT_OFFSET 14
#define QUOT_XT_OFFSET 16
#define WORD_XT_OFFSET 30
/* We pass a function pointer to memcpy to work around a Mac OS X

View File

@ -61,7 +61,7 @@
#endif
#define QUOT_XT_OFFSET 34
#define QUOT_XT_OFFSET 36
#define WORD_XT_OFFSET 66
/* We pass a function pointer to memcpy to work around a Mac OS X

View File

@ -216,12 +216,8 @@ CELL unaligned_object_size(CELL pointer)
return sizeof(F_QUOTATION);
case WORD_TYPE:
return sizeof(F_WORD);
case RATIO_TYPE:
return sizeof(F_RATIO);
case FLOAT_TYPE:
return sizeof(F_FLOAT);
case COMPLEX_TYPE:
return sizeof(F_COMPLEX);
case DLL_TYPE:
return sizeof(F_DLL);
case ALIEN_TYPE:
@ -276,10 +272,6 @@ CELL binary_payload_start(CELL pointer)
tuple = untag_object(pointer);
layout = untag_object(tuple->layout);
return tuple_size(layout);
case RATIO_TYPE:
return sizeof(F_RATIO);
case COMPLEX_TYPE:
return sizeof(F_COMPLEX);
case WRAPPER_TYPE:
return sizeof(F_WRAPPER);
default:
@ -291,20 +283,22 @@ CELL binary_payload_start(CELL pointer)
/* Push memory usage statistics in data heap */
void primitive_data_room(void)
{
F_ARRAY *a = allot_array(ARRAY_TYPE,data_heap->gen_count * 2,F);
int gen;
dpush(tag_fixnum((data_heap->cards_end - data_heap->cards) >> 10));
dpush(tag_fixnum((data_heap->decks_end - data_heap->decks) >> 10));
GROWABLE_ARRAY(a);
int gen;
for(gen = 0; gen < data_heap->gen_count; gen++)
{
F_ZONE *z = (gen == NURSERY ? &nursery : &data_heap->generations[gen]);
set_array_nth(a,gen * 2,tag_fixnum((z->end - z->here) >> 10));
set_array_nth(a,gen * 2 + 1,tag_fixnum((z->size) >> 10));
GROWABLE_ARRAY_ADD(a,tag_fixnum((z->end - z->here) >> 10));
GROWABLE_ARRAY_ADD(a,tag_fixnum((z->size) >> 10));
}
dpush(tag_object(a));
GROWABLE_ARRAY_TRIM(a);
GROWABLE_ARRAY_DONE(a);
dpush(a);
}
/* Disables GC and activates next-object ( -- obj ) primitive */

View File

@ -74,7 +74,11 @@ static CELL lookup_tuple_method(CELL object, CELL methods)
static CELL lookup_hi_tag_method(CELL object, CELL methods)
{
F_ARRAY *hi_tag_methods = untag_object(methods);
return array_nth(hi_tag_methods,hi_tag(object) - HEADER_TYPE);
CELL tag = hi_tag(object) - HEADER_TYPE;
#ifdef FACTOR_DEBUG
assert(tag < TYPE_COUNT - HEADER_TYPE);
#endif
return array_nth(hi_tag_methods,tag);
}
static CELL method_cache_hashcode(CELL key, F_ARRAY *array)

View File

@ -167,7 +167,7 @@ void pass_args_to_factor(int argc, F_CHAR **argv)
set_array_nth(args,i,arg);
}
userenv[ARGS_ENV] = tag_object(args);
userenv[ARGS_ENV] = tag_array(args);
}
void start_factor(F_PARAMETERS *p)

View File

@ -144,7 +144,7 @@ static CELL add_inline_cache_entry(CELL cache_entries, CELL class, CELL method)
cache_entries_array = reallot_array(cache_entries_array,pic_size + 2);
set_array_nth(cache_entries_array,pic_size,class);
set_array_nth(cache_entries_array,pic_size + 1,method);
return tag_object(cache_entries_array);
return tag_array(cache_entries_array);
}
}

View File

@ -32,9 +32,9 @@ typedef signed long long s64;
/*** Tags ***/
#define FIXNUM_TYPE 0
#define BIGNUM_TYPE 1
#define RATIO_TYPE 2
#define ARRAY_TYPE 2
#define FLOAT_TYPE 3
#define COMPLEX_TYPE 4
#define QUOTATION_TYPE 4
#define F_TYPE 5
#define OBJECT_TYPE 6
#define TUPLE_TYPE 7
@ -50,17 +50,15 @@ typedef signed long long s64;
#define GC_COLLECTED 5 /* See gc.c */
/*** Header types ***/
#define ARRAY_TYPE 8
#define WRAPPER_TYPE 9
#define BYTE_ARRAY_TYPE 10
#define CALLSTACK_TYPE 11
#define STRING_TYPE 12
#define WORD_TYPE 13
#define QUOTATION_TYPE 14
#define DLL_TYPE 15
#define ALIEN_TYPE 16
#define WRAPPER_TYPE 8
#define BYTE_ARRAY_TYPE 9
#define CALLSTACK_TYPE 10
#define STRING_TYPE 11
#define WORD_TYPE 12
#define DLL_TYPE 13
#define ALIEN_TYPE 14
#define TYPE_COUNT 17
#define TYPE_COUNT 15
INLINE bool immediate_p(CELL obj)
{
@ -175,13 +173,6 @@ typedef struct {
CELL object;
} F_WRAPPER;
/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
CELL numerator;
CELL denominator;
} F_RATIO;
/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
/* We use a union here to force the float value to be aligned on an
@ -210,13 +201,6 @@ typedef struct {
F_CODE_BLOCK *code;
} F_QUOTATION;
/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
CELL real;
CELL imaginary;
} F_COMPLEX;
/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;

View File

@ -38,7 +38,7 @@ CELL extra_roots;
DEFPUSHPOP(root_,extra_roots)
#define REGISTER_UNTAGGED(obj) root_push(obj ? tag_object(obj) : 0)
#define REGISTER_UNTAGGED(obj) root_push(obj ? RETAG(obj,OBJECT_TYPE) : 0)
#define UNREGISTER_UNTAGGED(obj) obj = untag_object(root_pop())
/* We ignore strings which point outside the data heap, but we might be given

View File

@ -375,18 +375,6 @@ CELL unbox_array_size(void)
return 0; /* can't happen */
}
/* Ratios */
/* Does not reduce to lowest terms, so should only be used by math
library implementation, to avoid breaking invariants. */
void primitive_from_fraction(void)
{
F_RATIO* ratio = allot_object(RATIO_TYPE,sizeof(F_RATIO));
ratio->denominator = dpop();
ratio->numerator = dpop();
dpush(RETAG(ratio,RATIO_TYPE));
}
/* Floats */
void primitive_fixnum_to_float(void)
{
@ -525,13 +513,3 @@ void box_double(double flo)
{
dpush(allot_float(flo));
}
/* Complex numbers */
void primitive_from_rect(void)
{
F_COMPLEX* z = allot_object(COMPLEX_TYPE,sizeof(F_COMPLEX));
z->imaginary = dpop();
z->real = dpop();
dpush(RETAG(z,COMPLEX_TYPE));
}

View File

@ -85,8 +85,6 @@ DLLEXPORT u64 to_unsigned_8(CELL obj);
CELL unbox_array_size(void);
void primitive_from_fraction(void);
INLINE double untag_float_fast(CELL tagged)
{
return ((F_FLOAT*)UNTAG(tagged))->n;
@ -151,5 +149,3 @@ void primitive_float_bits(void);
void primitive_bits_float(void);
void primitive_double_bits(void);
void primitive_bits_double(void);
void primitive_from_rect(void);

View File

@ -7,14 +7,12 @@ void *primitives[] = {
primitive_float_to_bignum,
primitive_fixnum_to_float,
primitive_bignum_to_float,
primitive_from_fraction,
primitive_str_to_float,
primitive_float_to_str,
primitive_float_bits,
primitive_double_bits,
primitive_bits_float,
primitive_bits_double,
primitive_from_rect,
primitive_fixnum_add,
primitive_fixnum_subtract,
primitive_fixnum_multiply,

View File

@ -439,7 +439,7 @@ void primitive_array_to_quotation(void)
quot->compiledp = F;
quot->cached_effect = F;
quot->cache_counter = F;
drepl(tag_object(quot));
drepl(tag_quotation(quot));
}
void primitive_quotation_xt(void)

View File

@ -1,5 +1,10 @@
DEFINE_UNTAG(F_QUOTATION,QUOTATION_TYPE,quotation)
INLINE CELL tag_quotation(F_QUOTATION *quotation)
{
return RETAG(quotation,QUOTATION_TYPE);
}
void set_quot_xt(F_QUOTATION *quot, F_CODE_BLOCK *code);
void jit_compile(CELL quot, bool relocate);
F_FASTCALL CELL lazy_jit_compile_impl(CELL quot, F_STACK_FRAME *stack);

View File

@ -120,7 +120,7 @@ bool stack_to_array(CELL bottom, CELL top)
{
F_ARRAY *a = allot_array_internal(ARRAY_TYPE,depth / CELLS);
memcpy(a + 1,(void*)bottom,depth);
dpush(tag_object(a));
dpush(tag_array(a));
return true;
}
}

View File

@ -153,16 +153,19 @@ INLINE CELL untag_header(CELL cell)
return cell >> TAG_BITS;
}
INLINE CELL tag_object(void* cell)
{
return RETAG(cell,OBJECT_TYPE);
}
INLINE CELL hi_tag(CELL tagged)
{
return untag_header(get(UNTAG(tagged)));
}
INLINE CELL tag_object(void *cell)
{
#ifdef FACTOR_DEBUG
assert(hi_tag((CELL)cell) >= HEADER_TYPE);
#endif
return RETAG(cell,OBJECT_TYPE);
}
INLINE CELL type_of(CELL tagged)
{
CELL tag = TAG(tagged);

View File

@ -107,40 +107,60 @@ void primitive_string(void)
dpush(tag_object(allot_string(length,initial)));
}
static bool reallot_string_in_place_p(F_STRING *string, CELL capacity)
{
return in_zone(&nursery,(CELL)string) && capacity <= string_capacity(string);
}
F_STRING* reallot_string(F_STRING* string, CELL capacity)
{
CELL to_copy = string_capacity(string);
if(capacity < to_copy)
to_copy = capacity;
REGISTER_UNTAGGED(string);
F_STRING *new_string = allot_string_internal(capacity);
UNREGISTER_UNTAGGED(string);
memcpy(new_string + 1,string + 1,to_copy);
if(string->aux != F)
if(reallot_string_in_place_p(string,capacity))
{
string->length = tag_fixnum(capacity);
if(string->aux != F)
{
F_BYTE_ARRAY *aux = untag_object(string->aux);
aux->capacity = tag_fixnum(capacity * 2);
}
return string;
}
else
{
CELL to_copy = string_capacity(string);
if(capacity < to_copy)
to_copy = capacity;
REGISTER_UNTAGGED(string);
F_STRING *new_string = allot_string_internal(capacity);
UNREGISTER_UNTAGGED(string);
memcpy(new_string + 1,string + 1,to_copy);
if(string->aux != F)
{
REGISTER_UNTAGGED(string);
REGISTER_UNTAGGED(new_string);
F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16));
UNREGISTER_UNTAGGED(new_string);
UNREGISTER_UNTAGGED(string);
write_barrier((CELL)new_string);
new_string->aux = tag_object(new_aux);
F_BYTE_ARRAY *aux = untag_object(string->aux);
memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16));
}
REGISTER_UNTAGGED(string);
REGISTER_UNTAGGED(new_string);
F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16));
fill_string(new_string,to_copy,capacity,'\0');
UNREGISTER_UNTAGGED(new_string);
UNREGISTER_UNTAGGED(string);
write_barrier((CELL)new_string);
new_string->aux = tag_object(new_aux);
F_BYTE_ARRAY *aux = untag_object(string->aux);
memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16));
return new_string;
}
REGISTER_UNTAGGED(string);
REGISTER_UNTAGGED(new_string);
fill_string(new_string,to_copy,capacity,'\0');
UNREGISTER_UNTAGGED(new_string);
UNREGISTER_UNTAGGED(string);
return new_string;
}
void primitive_resize_string(void)

View File

@ -6,7 +6,7 @@ F_TUPLE *allot_tuple(F_TUPLE_LAYOUT *layout)
REGISTER_UNTAGGED(layout);
F_TUPLE *tuple = allot_object(TUPLE_TYPE,tuple_size(layout));
UNREGISTER_UNTAGGED(layout);
tuple->layout = tag_object(layout);
tuple->layout = tag_array((F_ARRAY *)layout);
return tuple;
}