disallowd a non-pointer object to inherit a pointer object with instance variables

This commit is contained in:
hyunghwan.chung 2018-01-06 17:42:42 +00:00
parent de1f8c9551
commit e9b33016a4
2 changed files with 47 additions and 14 deletions

View File

@ -223,6 +223,17 @@ class SocketAddress(Object) from 'sck.addr'
} }
} }
class X(Object)
{
var tt,yy.
method x {
self.yy := 9.
}
}
class(#byte(3)) Y(X)
{
}
##class InetSocketAddress(SocketAddress) ##class InetSocketAddress(SocketAddress)
##{ ##{
@ -367,6 +378,10 @@ class MyObject(Object)
{ {
| s conact inact outact | | s conact inact outact |
s := Y new.
s x.
s basicSize dump.
'****************************' dump.
s := ByteArray new: 100. s := ByteArray new: 100.
s basicFillFrom: 0 with: ($a asInteger) count: 100. s basicFillFrom: 0 with: ($a asInteger) count: 100.

View File

@ -3246,7 +3246,8 @@ if super is variable-nonpointer, no instance variable is allowed.
*/ */
if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)) if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP))
{ {
set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); /* a non-pointer object cannot have instance variables */
set_syntax_error (moo, MOO_SYNERR_VARDCLBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; return -1;
} }
@ -3388,7 +3389,8 @@ if super is variable-nonpointer, no instance variable is allowed.
*/ */
if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)) if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP))
{ {
set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); /* a non-pointer object cannot have instance variables */
set_syntax_error (moo, MOO_SYNERR_VARDCLBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; return -1;
} }
@ -6932,8 +6934,8 @@ static int make_defined_class (moo_t* moo)
if (moo->c->cls.type_size > 0) if (moo->c->cls.type_size > 0)
{ {
/* class(#byte(N)), class(#word(N)), etc */ /* class(#byte(N)), class(#word(N)), etc */
/* TODO: ensure that this size is equal to greater than the type size of the parent */
MOO_ASSERT (moo, moo->c->cls.var[VAR_INSTANCE].total_count == 0); MOO_ASSERT (moo, moo->c->cls.var[VAR_INSTANCE].total_count == 0);
MOO_ASSERT (moo, moo->c->cls.flags & CLASS_INDEXED);
MOO_ASSERT (moo, moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP); MOO_ASSERT (moo, moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP);
spec = MOO_CLASS_SPEC_MAKE (moo->c->cls.type_size, flags, moo->c->cls.indexed_type); spec = MOO_CLASS_SPEC_MAKE (moo->c->cls.type_size, flags, moo->c->cls.indexed_type);
} }
@ -7131,6 +7133,8 @@ static int __compile_class_definition (moo_t* moo, int extend)
* NOTE: when extending a class, class-module-import and variable-definition are not allowed. * NOTE: when extending a class, class-module-import and variable-definition are not allowed.
*/ */
moo_oop_association_t ass; moo_oop_association_t ass;
moo_ioloc_t type_size_loc;
if (!extend && TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) if (!extend && TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN)
{ {
@ -7148,28 +7152,28 @@ static int __compile_class_definition (moo_t* moo, int extend)
if (is_token_symbol(moo, VOCA_BYTE_S)) if (is_token_symbol(moo, VOCA_BYTE_S))
{ {
/* class(#byte) */ /* class(#byte) */
if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_BYTE) <= -1) return -1; if (_set_class_indexed_type(moo, MOO_OBJ_TYPE_BYTE) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
permit_type_size = 1; permit_type_size = 1;
} }
else if (is_token_symbol(moo, VOCA_CHARACTER_S)) else if (is_token_symbol(moo, VOCA_CHARACTER_S))
{ {
/* class(#character) */ /* class(#character) */
if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_CHAR) <= -1) return -1; if (_set_class_indexed_type(moo, MOO_OBJ_TYPE_CHAR) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
permit_type_size = 1; permit_type_size = 1;
} }
else if (is_token_symbol(moo, VOCA_HALFWORD_S)) else if (is_token_symbol(moo, VOCA_HALFWORD_S))
{ {
/* class(#halfword) */ /* class(#halfword) */
if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_HALFWORD) <= -1) return -1; if (_set_class_indexed_type(moo, MOO_OBJ_TYPE_HALFWORD) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
permit_type_size = 1; permit_type_size = 1;
} }
else if (is_token_symbol(moo, VOCA_WORD_S)) else if (is_token_symbol(moo, VOCA_WORD_S))
{ {
/* class(#word) */ /* class(#word) */
if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_WORD) <= -1) return -1; if (_set_class_indexed_type(moo, MOO_OBJ_TYPE_WORD) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
permit_type_size = 1; permit_type_size = 1;
} }
@ -7178,14 +7182,14 @@ static int __compile_class_definition (moo_t* moo, int extend)
/* class(#liword) - /* class(#liword) -
* the liword type maps to one of word or halfword. * the liword type maps to one of word or halfword.
* see the definiton of MOO_OBJ_TYPE_LIWORD in moo.h */ * see the definiton of MOO_OBJ_TYPE_LIWORD in moo.h */
if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_LIWORD) <= -1) return -1; if (_set_class_indexed_type(moo, MOO_OBJ_TYPE_LIWORD) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
permit_type_size = 1; permit_type_size = 1;
} }
else if (is_token_symbol(moo, VOCA_POINTER_S)) else if (is_token_symbol(moo, VOCA_POINTER_S))
{ {
/* class(#pointer) */ /* class(#pointer) */
if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_OOP) <= -1) return -1; if (_set_class_indexed_type(moo, MOO_OBJ_TYPE_OOP) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
} }
else if (is_token_symbol(moo, VOCA_FINAL_S)) else if (is_token_symbol(moo, VOCA_FINAL_S))
@ -7258,6 +7262,7 @@ static int __compile_class_definition (moo_t* moo, int extend)
return -1; return -1;
} }
type_size_loc = moo->c->tok.loc;
GET_TOKEN (moo); GET_TOKEN (moo);
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
@ -7423,7 +7428,7 @@ static int __compile_class_definition (moo_t* moo, int extend)
{ {
var_info_t var; var_info_t var;
if (get_variable_info (moo, &moo->c->cls.superfqn, &moo->c->cls.superfqn_loc, superfqn_is_dotted, &var) <= -1) return -1; if (get_variable_info(moo, &moo->c->cls.superfqn, &moo->c->cls.superfqn_loc, superfqn_is_dotted, &var) <= -1) return -1;
if (var.type != VAR_GLOBAL) goto unknown_superclass; if (var.type != VAR_GLOBAL) goto unknown_superclass;
if (MOO_CLASSOF(moo, var.u.gbl->value) == moo->_class && MOO_OBJ_GET_FLAGS_KERNEL(var.u.gbl->value) != 1) if (MOO_CLASSOF(moo, var.u.gbl->value) == moo->_class && MOO_OBJ_GET_FLAGS_KERNEL(var.u.gbl->value) != 1)
@ -7517,18 +7522,31 @@ static int __compile_class_definition (moo_t* moo, int extend)
/* [NOTE] class variables are not inherited. /* [NOTE] class variables are not inherited.
* so no data about them are not transferred over */ * so no data about them are not transferred over */
if ((moo->c->cls.flags & CLASS_INDEXED) && moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP) if ((moo->c->cls.flags & CLASS_INDEXED) && moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)
{ {
/* TODO: do i need to check if the parent class and the current class have the same indexed type? */ /* the class defined is a non-pointer object. */
if (MOO_CLASS_SPEC_INDEXED_TYPE(spec) == MOO_OBJ_TYPE_OOP && MOO_CLASS_SPEC_NAMED_INSTVARS(spec) > 0)
{
/* a non-pointer object cannot inherit from a pointer object with instance variables */
set_syntax_error (moo, MOO_SYNERR_CLASSTSIZEINVAL, &moo->c->cls.fqn_loc, &moo->c->cls.fqn); /* TODO: enhance error message */
return -1;
}
/* NOTE: I don't mandate that the parent and the child be of the same type.
* Say, for a parent class(#byte(4)), a child can be defined to be
* class(#word(4)). */
if (moo->c->cls.type_size < MOO_CLASS_SPEC_NAMED_INSTVARS(spec)) if (moo->c->cls.type_size < MOO_CLASS_SPEC_NAMED_INSTVARS(spec))
{ {
set_syntax_error (moo, MOO_SYNERR_CLASSTSIZEINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); /* TODO: change error location... */ //set_syntax_error (moo, MOO_SYNERR_CLASSTSIZEINVAL, &type_size_loc, MOO_NULL); /* TODO: enhance error message */
set_syntax_error (moo, MOO_SYNERR_CLASSTSIZEINVAL, MOO_NULL, MOO_NULL); /* TODO: enhance error message */
return -1; return -1;
} }
} }
else else
{ {
/* the class defined is a pointer object or a variable-pointer object */
MOO_ASSERT (moo, moo->c->cls.type_size == 0); /* no such thing as class(#pointer(N)). so it must be 0 */ MOO_ASSERT (moo, moo->c->cls.type_size == 0); /* no such thing as class(#pointer(N)). so it must be 0 */
moo->c->cls.var[VAR_INSTANCE].total_count = MOO_CLASS_SPEC_NAMED_INSTVARS(spec); moo->c->cls.var[VAR_INSTANCE].total_count = MOO_CLASS_SPEC_NAMED_INSTVARS(spec);
} }
@ -7697,7 +7715,7 @@ static int compile_class_definition (moo_t* moo, int extend)
/* reset the structure to hold information about a class to be compiled */ /* reset the structure to hold information about a class to be compiled */
moo->c->cls.flags = 0; moo->c->cls.flags = 0;
moo->c->cls.indexed_type = MOO_OBJ_TYPE_OOP; moo->c->cls.indexed_type = MOO_OBJ_TYPE_OOP; /* whether indexed or not, it's the pointer type by default */
moo->c->cls.type_size = 0; moo->c->cls.type_size = 0;
moo->c->cls.name.len = 0; moo->c->cls.name.len = 0;