1
0
forked from Mirror/wren

Better error message on too many inherited fields.

This commit is contained in:
Bob Nystrom
2014-04-22 07:06:26 -07:00
parent f1c3bb0f37
commit 80a4eb8c9c
8 changed files with 37 additions and 23 deletions

View File

@ -158,13 +158,13 @@ nav {
}
h2 {
font: normal 24px $header;
font: normal 30px $header;
margin: 24px 0 0 0;
color: $blue;
}
h3 {
font: normal 20px $header;
font: normal 24px $header;
margin: 24px 0 0 0;
color: $blue;
}

View File

@ -62,28 +62,32 @@
// The maximum number of globals that may be defined at one time. This
// limitation comes from the 16 bits used for the arguments to
// `CODE_LOAD_GLOBAL` and `CODE_STORE_GLOBAL`.
#define MAX_GLOBALS (65536)
#define MAX_GLOBALS 65536
// The maximum number of arguments that can be passed to a method. Note that
// this limitation is hardcoded in other places in the VM, in particular, the
// `CODE_CALL_XX` instructions assume a certain maximum number.
#define MAX_PARAMETERS (16)
#define MAX_PARAMETERS 16
// The maximum name of a method, not including the signature. This is an
// arbitrary but enforced maximum just so we know how long the method name
// strings need to be in the parser.
#define MAX_METHOD_NAME (64)
#define MAX_METHOD_NAME 64
// The maximum length of a method signature. This includes the name, and the
// extra spaces added to handle arity, and another byte to terminate the string.
#define MAX_METHOD_SIGNATURE (MAX_METHOD_NAME + MAX_PARAMETERS + 1)
// The maximum length of an identifier. The only real reason for this limitation
// is so that error messages mentioning variables can be stack allocated.
#define MAX_VARIABLE_NAME 64
// The maximum number of fields a class can have, including inherited fields.
// This is explicit in the bytecode since `CODE_CLASS` and `CODE_SUBCLASS` take
// a single byte for the number of fields. Note that it's 255 and not 256
// because creating a class takes the *number* of fields, not the *highest
// field index*.
#define MAX_FIELDS (255)
#define MAX_FIELDS 255
// Assertions are used to validate program invariants. They indicate things the
// program expects to be true about its internal state during execution. If an

View File

@ -943,6 +943,12 @@ static int declareVariable(Compiler* compiler)
{
Token* token = &compiler->parser->previous;
if (token->length > MAX_VARIABLE_NAME)
{
error(compiler, "Variable name cannot be longer than %d characters.",
MAX_VARIABLE_NAME);
}
// Top-level global scope.
if (compiler->scopeDepth == -1)
{

View File

@ -950,20 +950,20 @@ static bool runInterpreter(WrenVM* vm)
}
int numFields = READ_BYTE();
ObjClass* classObj = wrenNewClass(vm, superclass, numFields, name);
// Now that we know the total number of fields, make sure we don't
// overflow.
if (superclass->numFields + numFields > MAX_FIELDS)
{
// TODO: Include class name in message. Mention inheritance.
char message[80];
snprintf(message, 80,
"A class may not have more than %d fields, including inherited "
"ones.", MAX_FIELDS);
char message[70 + MAX_VARIABLE_NAME];
snprintf(message, 70 + MAX_VARIABLE_NAME,
"Class '%s' may not have more than %d fields, including inherited "
"ones.", name->value, MAX_FIELDS);
RUNTIME_ERROR(message);
}
// Don't pop the superclass and name off the stack until the subclass is
// done being created, to make sure it doesn't get collected.
DROP();

View File

@ -0,0 +1,2 @@
var i234567890i234567890i234567890i234567890i234567890i234 = "value"
class c234567890c234567890c234567890c234567890c234567890c234567890c234 {}

View File

@ -136,7 +136,7 @@ class Foo {
}
}
class Bar is Foo { // expect runtime error: A class may not have more than 255 fields, including inherited ones.
class Bar is Foo {
new {
super
_field129 = 129
@ -266,15 +266,16 @@ class Bar is Foo { // expect runtime error: A class may not have more than 255 f
_field253 = 253
_field254 = 254
_field255 = 255
_field256 = 256
}
bar {
IO.print(_field129)
IO.print(_field256)
IO.print(_field255)
}
}
var bar = new Bar
bar.foo
bar.bar
bar.foo // expect: 1
// expect: 128
bar.bar // expect: 129
// expect: 255

View File

@ -136,7 +136,7 @@ class Foo {
}
}
class Bar is Foo {
class Bar is Foo { // expect runtime error: Class 'Bar' may not have more than 255 fields, including inherited ones.
new {
super
_field129 = 129
@ -266,16 +266,15 @@ class Bar is Foo {
_field253 = 253
_field254 = 254
_field255 = 255
_field256 = 256
}
bar {
IO.print(_field129)
IO.print(_field255)
IO.print(_field256)
}
}
var bar = new Bar
bar.foo // expect: 1
// expect: 128
bar.bar // expect: 129
// expect: 255
bar.foo
bar.bar

View File

@ -0,0 +1,2 @@
var i234567890i234567890i234567890i234567890i234567890i2345 = "value" // expect error
class c234567890c234567890c234567890c234567890c234567890c234567890c2345 {} // expect error