src/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Sun Aug 12 20:48:49 2012 -0700 (2012-08-12)
changeset 172 48cffae8c9e0
parent 169 0456a16c2a63
child 174 e718b56aba78
permissions -rw-r--r--
Implement switch.
dvander@30
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@30
     2
 *
dvander@0
     3
 * Copyright (C) 2012 David Anderson
dvander@0
     4
 *
dvander@0
     5
 * This file is part of JITCraft.
dvander@0
     6
 *
dvander@0
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@0
     8
 * the terms of the GNU General Public License as published by the Free
dvander@0
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@0
    10
 * any later version.
dvander@0
    11
 * 
dvander@0
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@0
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@0
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@0
    15
 *
dvander@0
    16
 * You should have received a copy of the GNU General Public License along with
dvander@0
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@0
    18
 */
danderson@92
    19
#include <string.h>
dvander@0
    20
#include "SemanticAnalysis.h"
dvander@0
    21
#include "Types.h"
dvander@11
    22
#include "Zone.h"
dvander@11
    23
#include "TypeManager.h"
dvander@12
    24
#include "Scopes.h"
dvander@85
    25
#include "NameBinding.h"
dvander@168
    26
#include "Strings.h"
dvander@168
    27
#include "Box.h"
dvander@169
    28
#include "Array.h"
dvander@28
    29
#include "Heap-inl.h"
dvander@0
    30
dvander@59
    31
using namespace ke;
dvander@0
    32
dvander@2
    33
static inline bool
dvander@2
    34
IsPrimitiveType(Type *type, PrimitiveType primitive)
dvander@2
    35
{
dvander@2
    36
    if (!type)
dvander@2
    37
        return false;
dvander@2
    38
dvander@2
    39
    if (!type->isPrimitive())
dvander@2
    40
        return false;
dvander@2
    41
dvander@2
    42
    return primitive == type->primitive();
dvander@2
    43
}
dvander@2
    44
dvander@2
    45
static inline bool
dvander@2
    46
EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
dvander@2
    47
                        BoxedPrimitive *out)
dvander@2
    48
{
dvander@2
    49
    switch (kind) {
dvander@2
    50
      case TOK_PLUS:
dvander@2
    51
        *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
dvander@2
    52
        return true;
dvander@2
    53
dvander@2
    54
      case TOK_SHL:
dvander@2
    55
        *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
dvander@2
    56
        return true;
dvander@28
    57
dvander@28
    58
      default:
dvander@47
    59
        return false;
dvander@2
    60
    }
dvander@2
    61
}
dvander@2
    62
dvander@144
    63
static inline bool
dvander@144
    64
EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
dvander@144
    65
{
dvander@144
    66
  switch (kind) {
dvander@144
    67
    case TOK_MINUS:
dvander@144
    68
      *out = BoxedPrimitive::Int(-inner.toInt());
dvander@144
    69
      return true;
dvander@144
    70
dvander@144
    71
    default:
dvander@144
    72
      return false;
dvander@144
    73
  }
dvander@144
    74
}
dvander@144
    75
dvander@2
    76
static bool
dvander@2
    77
EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
dvander@2
    78
{
dvander@2
    79
    switch (expression->kind()) {
dvander@2
    80
      case AstNode::kBinaryExpression:
dvander@2
    81
      {
dvander@2
    82
        BoxedPrimitive left;
dvander@2
    83
        BoxedPrimitive right;
dvander@2
    84
        BinaryExpression *b = expression->toBinaryExpression();
dvander@2
    85
        if (!EvaluateForConstant(b->left(), &left) ||
dvander@2
    86
            !EvaluateForConstant(b->right(), &right))
dvander@2
    87
        {
dvander@2
    88
            return false;
dvander@2
    89
        }
dvander@2
    90
        return EvaluateBinaryOperation(b->token(), left, right, out);
dvander@2
    91
      }
dvander@2
    92
dvander@144
    93
      case AstNode::kUnaryExpression:
dvander@144
    94
      {
dvander@144
    95
        BoxedPrimitive inner;
dvander@144
    96
        UnaryExpression *u = expression->toUnaryExpression();
dvander@144
    97
        if (!EvaluateForConstant(u->expression(), &inner))
dvander@144
    98
            return false;
dvander@144
    99
        return EvaluateUnaryOperation(u->token(), inner, out);
dvander@144
   100
      }
dvander@144
   101
dvander@2
   102
      case AstNode::kNameProxy:
dvander@2
   103
      {
dvander@2
   104
        NameProxy *proxy = expression->toNameProxy();
dvander@2
   105
        if (proxy->binding()->kind() != BoundName::CONSTANT)
dvander@2
   106
            return false;
dvander@2
   107
dvander@2
   108
        NamedConstant *c = proxy->binding()->toNamedConstant();
dvander@2
   109
        if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
dvander@2
   110
            return false;
dvander@2
   111
dvander@2
   112
        *out = c->value();
dvander@2
   113
        return true;
dvander@2
   114
      }
dvander@2
   115
dvander@168
   116
      case AstNode::kBooleanLiteral:
dvander@172
   117
        *out = BoxedPrimitive::Int(expression->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
dvander@168
   118
        return true;
dvander@168
   119
dvander@4
   120
      case AstNode::kIntegerLiteral:
dvander@4
   121
        *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
dvander@2
   122
        return true;
dvander@2
   123
dvander@2
   124
      default:
dvander@2
   125
        return false;
dvander@2
   126
    }
dvander@2
   127
}
dvander@2
   128
dvander@30
   129
SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
dvander@30
   130
  : zone_(zone),
dvander@30
   131
    cc_(cc),
dvander@25
   132
    tree_(tree),
dvander@71
   133
    scope_(NULL),
dvander@71
   134
    loop_(NULL)
dvander@0
   135
{
dvander@0
   136
}
dvander@0
   137
dvander@0
   138
bool
dvander@0
   139
SemanticAnalysis::analyze()
dvander@0
   140
{
dvander@25
   141
    if (cc_.failures())
dvander@25
   142
        return false;
dvander@25
   143
dvander@85
   144
    scope_ = tree_->scope();
dvander@85
   145
dvander@25
   146
    for (size_t i = 0; i < tree_->statements()->length(); i++) {
dvander@25
   147
        Statement *statement = tree_->statements()->at(i);
dvander@25
   148
        if (statement->isFunctionStatement()) {
dvander@25
   149
            FunctionStatement *funstmt = statement->toFunctionStatement();
dvander@25
   150
            if (!preanalyze(funstmt))
dvander@25
   151
                return false;
dvander@145
   152
        } else if (statement->isEnumStatement()) {
dvander@145
   153
            EnumStatement *enumstmt = statement->toEnumStatement();
dvander@145
   154
dvander@145
   155
            // We pre-fill global enum types, since they may occur in function
dvander@145
   156
            // signatures. This should probably be somewhere else...
dvander@172
   157
            enumstmt->accept(this);
dvander@146
   158
        } else if (statement->isStructureStatement()) {
dvander@147
   159
            StructureStatement *node = statement->toStructureStatement();
dvander@147
   160
            node->accept(this);
dvander@147
   161
            if (!node->decl()->type())
dvander@147
   162
                return false;
dvander@25
   163
        }
dvander@25
   164
    }
dvander@25
   165
dvander@0
   166
    for (size_t i = 0; i < tree_->statements()->length(); i++) {
dvander@0
   167
        Statement *statement = tree_->statements()->at(i);
dvander@172
   168
dvander@172
   169
        // We can't double-process these. Maybe put this check somewhere else.
dvander@172
   170
        if (statement->isEnumStatement())
dvander@172
   171
            continue;
dvander@172
   172
dvander@0
   173
        statement->accept(this);
dvander@0
   174
    }
dvander@0
   175
dvander@137
   176
    if (!determineLiveFunctions())
dvander@137
   177
        return false;
dvander@137
   178
dvander@25
   179
    return !cc_.failures();
dvander@0
   180
}
dvander@0
   181
dvander@137
   182
bool
dvander@137
   183
SemanticAnalysis::determineLiveFunctions()
dvander@137
   184
{
dvander@137
   185
    Vector<NamedFunction *> worklist;
dvander@137
   186
dvander@137
   187
    // Add the root set.
dvander@137
   188
    for (size_t i = 0; i < tree_->statements()->length(); i++) {
dvander@137
   189
        Statement *statement = tree_->statements()->at(i);
dvander@137
   190
        if (!statement->isFunctionStatement())
dvander@137
   191
            continue;
dvander@137
   192
dvander@137
   193
        FunctionStatement *stmt = statement->toFunctionStatement();
dvander@137
   194
        NamedFunction  *fun = stmt->fun();
dvander@137
   195
        if (!fun->used())
dvander@137
   196
            continue;
dvander@137
   197
dvander@137
   198
        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
dvander@137
   199
            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
dvander@137
   200
dvander@137
   201
            // Names in these lists are always unused, however, we mark them
dvander@137
   202
            // as used while inserting into the work queue, to avoid double-
dvander@137
   203
            // insertion.
dvander@137
   204
            if (name->used())
dvander@137
   205
                continue;
dvander@137
   206
dvander@137
   207
            if (!worklist.append(name))
dvander@137
   208
                return false;
dvander@137
   209
dvander@137
   210
            name->setUsed();
dvander@137
   211
        }
dvander@137
   212
    }
dvander@137
   213
dvander@137
   214
    while (!worklist.empty()) {
dvander@137
   215
        NamedFunction *fun = worklist.popCopy();
dvander@137
   216
dvander@137
   217
        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
dvander@137
   218
            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
dvander@137
   219
            if (name->used())
dvander@137
   220
                continue;
dvander@137
   221
            if (!worklist.append(name))
dvander@137
   222
                return false;
dvander@137
   223
            name->setUsed();
dvander@137
   224
        }
dvander@137
   225
    }
dvander@137
   226
dvander@137
   227
    return true;
dvander@137
   228
}
dvander@137
   229
dvander@145
   230
Type *
dvander@145
   231
SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
dvander@145
   232
{
dvander@145
   233
    if (!name)
dvander@145
   234
        return zone_->types()->getPrimitive(PrimitiveType_Int32);
dvander@145
   235
dvander@145
   236
    if (name->kind() == BoundName::UNBOUND) {
dvander@145
   237
        cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
dvander@145
   238
        return NULL;
dvander@145
   239
    }
dvander@145
   240
dvander@145
   241
    if (name->kind() != BoundName::TYPE) {
dvander@145
   242
        cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
dvander@145
   243
        return NULL;
dvander@145
   244
    }
dvander@145
   245
dvander@145
   246
    if (!name->type())
dvander@145
   247
        return NULL;
dvander@145
   248
dvander@145
   249
    return name->type();
dvander@145
   250
}
dvander@137
   251
dvander@25
   252
Type *
dvander@25
   253
SemanticAnalysis::visitAndApplyType(Expression *expression)
dvander@0
   254
{
dvander@25
   255
    expression->accept(this);
dvander@25
   256
    return expression->type();
dvander@0
   257
}
dvander@0
   258
dvander@7
   259
Type *
dvander@7
   260
SemanticAnalysis::visitForLoad(Expression *expression)
dvander@7
   261
{
dvander@40
   262
    Local<Type> type(zone_, visitAndApplyType(expression));
dvander@25
   263
    if (!type)
dvander@21
   264
        return NULL;
dvander@21
   265
dvander@21
   266
    if (type->isReference()) {
dvander@21
   267
        expression->setType(type->contained());
dvander@71
   268
    } else if (expression->isCallExpression()) {
dvander@71
   269
        if (type->isVoid()) {
dvander@71
   270
            CallExpression *call = expression->toCallExpression();
dvander@71
   271
            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
dvander@71
   272
            return NULL;
dvander@71
   273
        }
dvander@14
   274
    }
dvander@25
   275
dvander@7
   276
    return expression->type();
dvander@7
   277
}
dvander@7
   278
dvander@54
   279
// :TODO: this leaks an interior pointer.
dvander@145
   280
const char *
dvander@145
   281
ke::GetTypeName(Type *type)
dvander@4
   282
{
dvander@25
   283
    if (type->isArray())
dvander@25
   284
        return "array";
dvander@25
   285
    if (type->isFunction())
dvander@25
   286
        return "function";
dvander@129
   287
    if (type->isVoid())
dvander@129
   288
        return "void";
dvander@147
   289
    if (type->isEnum() || type->isStruct())
dvander@145
   290
        return type->name()->chars();
dvander@25
   291
    if (type->isReference())
dvander@25
   292
        type = type->contained();
dvander@145
   293
    switch (type->primitive()) {
dvander@145
   294
      case PrimitiveType_Bool:
dvander@145
   295
        return "bool";
dvander@145
   296
      case PrimitiveType_Char:
dvander@145
   297
        return "String";
dvander@145
   298
      case PrimitiveType_Int32:
dvander@145
   299
        return "int";
dvander@145
   300
      case PrimitiveType_Float:
dvander@148
   301
        return "Float";
dvander@145
   302
      default:
dvander@145
   303
        return "<unknown>";
dvander@145
   304
    }
dvander@4
   305
}
dvander@4
   306
dvander@25
   307
void
dvander@40
   308
SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
dvander@21
   309
{
dvander@25
   310
    const char *op = TokenNames[token];
dvander@25
   311
    const char *name = GetTypeName(type);
dvander@21
   312
dvander@25
   313
    cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
dvander@21
   314
}
dvander@21
   315
dvander@25
   316
void
dvander@40
   317
SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
dvander@22
   318
{
dvander@25
   319
    const char *op = TokenNames[token];
dvander@25
   320
    const char *leftName = GetTypeName(left);
dvander@25
   321
    const char *rightName = GetTypeName(right);
dvander@22
   322
dvander@25
   323
    cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
dvander@25
   324
}
dvander@25
   325
dvander@25
   326
Type *
dvander@40
   327
SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
dvander@25
   328
{
dvander@22
   329
    if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
dvander@22
   330
        (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
dvander@22
   331
    {
dvander@22
   332
        // If either side is a float, the other side must be a float or int.
dvander@22
   333
        if (left->isFloat() || right->isFloat()) {
dvander@25
   334
            Type *floatType = left->isFloat() ? left : right;
dvander@25
   335
            Type *other = left->isFloat() ? right : left;
dvander@145
   336
            if (other->isFloat() || other->isInt32())
dvander@28
   337
                return floatType;
dvander@22
   338
        }
dvander@22
   339
    }
dvander@22
   340
dvander@79
   341
    if (token == TOK_OR || token == TOK_AND) {
dvander@79
   342
        if (!canTest(node, left) || !canTest(node, right))
dvander@79
   343
            return NULL;
dvander@145
   344
        return zone_->types()->getPrimitive(PrimitiveType_Bool);
dvander@79
   345
    }
dvander@79
   346
dvander@79
   347
    if (token >= TOK_EQUALS && token <= TOK_GE) {
dvander@145
   348
        if ((left->isFloat() || left->isInt32()) &&
dvander@145
   349
            (right->isFloat() || right->isInt32()))
dvander@74
   350
        {
dvander@145
   351
            return zone_->types()->getPrimitive(PrimitiveType_Bool);
dvander@74
   352
        }
dvander@74
   353
        binaryTypeError(node, token, left, right);
dvander@74
   354
        return NULL;
dvander@74
   355
    }
dvander@74
   356
dvander@145
   357
    if (!left->isInt32() || !right->isInt32()) {
dvander@25
   358
        binaryTypeError(node, token, left, right);
dvander@25
   359
        return NULL;
dvander@25
   360
    }
dvander@25
   361
dvander@22
   362
    return left;
dvander@22
   363
}
dvander@22
   364
dvander@25
   365
bool
dvander@40
   366
SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
dvander@25
   367
{
dvander@145
   368
    if (!type->isPrimitive() && !type->isEnum()) {
dvander@25
   369
        cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
dvander@25
   370
        return false;
dvander@25
   371
    }
dvander@25
   372
    return true;
dvander@25
   373
}
dvander@25
   374
dvander@23
   375
Type *
dvander@23
   376
SemanticAnalysis::visitForLValue(Expression *expression)
dvander@23
   377
{
dvander@23
   378
    if (expression->isIndexExpression()) {
dvander@25
   379
        Type *type = visitAndApplyType(expression);
dvander@25
   380
        if (!type)
dvander@23
   381
            return NULL;
dvander@25
   382
dvander@154
   383
        // if (type->isConst()) {
dvander@154
   384
        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
dvander@154
   385
        //     return NULL;
dvander@154
   386
        // }
dvander@67
   387
dvander@150
   388
        return type;
dvander@23
   389
    }
dvander@23
   390
dvander@148
   391
    if (expression->isFieldExpression()) {
dvander@148
   392
        Type *type = visitAndApplyType(expression);
dvander@148
   393
        if (!type)
dvander@148
   394
            return NULL;
dvander@148
   395
dvander@148
   396
        // if (expression->toFieldExpression()->left()->type()->isConst()) {
dvander@148
   397
        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
dvander@148
   398
        //     return NULL;
dvander@148
   399
        // }
dvander@148
   400
dvander@148
   401
        return type;
dvander@148
   402
    }
dvander@148
   403
dvander@23
   404
    if (!expression->isNameProxy()) {
dvander@25
   405
        cc_.reportError(expression->pos(), Message_ExpectedLValue);
dvander@23
   406
        return NULL;
dvander@23
   407
    }
dvander@23
   408
dvander@23
   409
    NameProxy *proxy = expression->toNameProxy();
dvander@23
   410
    if (!proxy->binding()->kind() == BoundName::VARIABLE) {
dvander@25
   411
        cc_.reportError(expression->pos(), Message_ExpectedLValue);
dvander@23
   412
        return NULL;
dvander@23
   413
    }
dvander@23
   414
dvander@23
   415
    Variable *var = proxy->binding()->toVariable();
dvander@23
   416
    if (!var->type())
dvander@23
   417
        return NULL;
dvander@23
   418
dvander@67
   419
    if  (var->type()->isReference()) {
dvander@67
   420
        if (var->type()->isConst()) {
dvander@67
   421
            cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
dvander@67
   422
            return NULL;
dvander@67
   423
        }
dvander@23
   424
        return var->type()->contained();
dvander@67
   425
    }
dvander@23
   426
    return var->type();
dvander@23
   427
}
dvander@23
   428
dvander@71
   429
SemanticAnalysis::ControlStatus
dvander@71
   430
SemanticAnalysis::visitForControl(Statement *statement)
dvander@71
   431
{
dvander@71
   432
    ControlScope scope(&control_);
dvander@71
   433
    statement->accept(this);
dvander@71
   434
    return scope.status();
dvander@71
   435
}
dvander@71
   436
dvander@0
   437
void
dvander@25
   438
SemanticAnalysis::visit(NameProxy *name)
dvander@25
   439
{
dvander@137
   440
    BoundName *binding = name->binding();
dvander@137
   441
dvander@137
   442
    if (binding->scope()->kind() == Scope::GLOBAL) {
dvander@137
   443
        if (!function_ || function_->isPublic()) {
dvander@137
   444
            // Whatever we're referencing must be kept alive no matter what.
dvander@137
   445
            // As such, we simply mark it used, and don't do anything special.
dvander@137
   446
            binding->setUsed();
dvander@137
   447
        } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
dvander@137
   448
            // Otherwise, we're inside a normal stock or function. Since we
dvander@137
   449
            // don't really know if we've been used yet, we shouldn't
dvander@137
   450
            // prematurely references as alive. Instead, we keep a list of
dvander@137
   451
            // which names have been used, so we can mark them later if needed.
dvander@137
   452
            //
dvander@137
   453
            // Note that we skip this step if the binding is already in the
dvander@137
   454
            // root set.
dvander@137
   455
            if (!function_->addUsedGlobal(binding))
dvander@137
   456
                return;
dvander@137
   457
        }
dvander@137
   458
    }
dvander@137
   459
dvander@137
   460
    name->setType(binding->type());
dvander@25
   461
}
dvander@25
   462
dvander@25
   463
void
dvander@0
   464
SemanticAnalysis::visit(Assignment *node)
dvander@0
   465
{
dvander@40
   466
    Local<Type> exprType(zone_, visitForLoad(node->expression()));
dvander@25
   467
    if (!exprType)
dvander@25
   468
        return ;
dvander@0
   469
dvander@40
   470
    Local<Type> type(zone_, visitForLValue(node->lvalue()));
dvander@23
   471
    if (!type)
dvander@23
   472
        return;
dvander@4
   473
dvander@25
   474
    if (node->token() != TOK_ASSIGN) {
dvander@25
   475
        if (!typeCheckBinary(node, node->token(), type, exprType))
dvander@25
   476
            return;
dvander@25
   477
    }
dvander@22
   478
dvander@168
   479
    if (!typeCheckAssignment(node->pos(), exprType, type, true))
dvander@25
   480
        return;
dvander@25
   481
dvander@25
   482
    node->setType(type);
dvander@0
   483
}
dvander@0
   484
dvander@0
   485
void
dvander@23
   486
SemanticAnalysis::visit(IncDecExpression *node)
dvander@23
   487
{
dvander@40
   488
    Local<Type> type(zone_, visitForLValue(node->expression()));
dvander@23
   489
    if (!type)
dvander@23
   490
        return;
dvander@23
   491
dvander@23
   492
    assert(!type->isReference());
dvander@25
   493
dvander@145
   494
    if (!type->isInt32() && !type->isFloat()) {
dvander@25
   495
        unaryTypeError(node, node->token(), type);
dvander@23
   496
        return;
dvander@23
   497
    }
dvander@23
   498
dvander@23
   499
    node->setType(type);
dvander@23
   500
}
dvander@23
   501
dvander@23
   502
void
dvander@78
   503
SemanticAnalysis::visit(UnaryExpression *node)
dvander@78
   504
{
dvander@78
   505
    Local<Type> type(zone_, visitForLoad(node->expression()));
dvander@78
   506
    if (!type)
dvander@78
   507
        return;
dvander@78
   508
dvander@78
   509
    switch (node->token())
dvander@78
   510
    {
dvander@79
   511
      case TOK_NOT:
dvander@79
   512
        if (!canTest(node->expression(), type))
dvander@79
   513
            return;
dvander@79
   514
        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
dvander@79
   515
        if (!type)
dvander@79
   516
            return;
dvander@79
   517
        node->setType(type);
dvander@79
   518
        break;
dvander@79
   519
dvander@80
   520
      case TOK_MINUS:
dvander@145
   521
        if (!type->isFloat() && !type->isInt32()) {
dvander@80
   522
            unaryTypeError(node, node->token(), type);
dvander@80
   523
            return;
dvander@80
   524
        }
dvander@80
   525
        node->setType(type);
dvander@80
   526
        break;
dvander@80
   527
dvander@142
   528
      case TOK_LABEL:
dvander@142
   529
      {
dvander@145
   530
        Local<Type> to(zone_, bindType(node->pos(), node->type()));
dvander@142
   531
        if (!to)
dvander@142
   532
            return;
dvander@142
   533
dvander@145
   534
        if ((!type->isFloat() && !type->isInt32OrEnum()) ||
dvander@145
   535
            (!to->isFloat() && !to->isInt32OrEnum()))
dvander@142
   536
        {
dvander@142
   537
            unaryTypeError(node, node->token(), type);
dvander@142
   538
            return;
dvander@142
   539
        }
dvander@142
   540
dvander@142
   541
        node->setType(to);
dvander@142
   542
        break;
dvander@142
   543
      }
dvander@142
   544
dvander@78
   545
      default:
dvander@78
   546
        assert(node->token() == TOK_TILDE);
dvander@145
   547
        if (!type->isInt32()) {
dvander@78
   548
            unaryTypeError(node, node->token(), type);
dvander@78
   549
            return;
dvander@78
   550
        }
dvander@78
   551
        node->setType(type);
dvander@78
   552
        break;
dvander@78
   553
    }
dvander@78
   554
}
dvander@78
   555
dvander@78
   556
void
dvander@83
   557
SemanticAnalysis::visit(TernaryExpression *node)
dvander@83
   558
{
dvander@83
   559
    Local<Type> type(zone_, visitForLoad(node->condition()));
dvander@83
   560
    if (!type)
dvander@83
   561
        return;
dvander@83
   562
dvander@83
   563
    if (!canTest(node->condition(), type))
dvander@83
   564
        return;
dvander@83
   565
dvander@83
   566
    Local<Type> left(zone_, visitForLoad(node->left()));
dvander@83
   567
    Local<Type> right(zone_, visitForLoad(node->right()));
dvander@83
   568
    if (!left || !right)
dvander@83
   569
        return;
dvander@83
   570
dvander@83
   571
    if (left != right) {
dvander@83
   572
        binaryTypeError(node, TOK_QMARK, left, right);
dvander@83
   573
        return;
dvander@83
   574
    }
dvander@83
   575
}
dvander@83
   576
dvander@83
   577
void
dvander@0
   578
SemanticAnalysis::visit(BinaryExpression *node)
dvander@0
   579
{
dvander@40
   580
    Local<Type> left(zone_, visitForLoad(node->left()));
dvander@40
   581
    Local<Type> right(zone_, visitForLoad(node->right()));
dvander@25
   582
    if (!left || !right)
dvander@25
   583
        return;
dvander@4
   584
dvander@40
   585
    Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
dvander@25
   586
    if (!result)
dvander@25
   587
        return;
dvander@25
   588
dvander@22
   589
    node->setType(result);
dvander@0
   590
}
dvander@0
   591
dvander@0
   592
void
dvander@0
   593
SemanticAnalysis::visit(ReturnStatement *node)
dvander@0
   594
{
dvander@71
   595
    // Set this early, so if we error we don't get more errors.
dvander@71
   596
    control_->returns(Returns_Always);
dvander@71
   597
dvander@72
   598
    if (!node->expression()) {
dvander@137
   599
        if (!function_->type()->returnType()->isVoid())
dvander@72
   600
            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
dvander@72
   601
        return;
dvander@72
   602
    }
dvander@72
   603
dvander@40
   604
    Local<Type> type(zone_, visitForLoad(node->expression()));
dvander@25
   605
    if (!type)
dvander@25
   606
        return;
dvander@0
   607
dvander@137
   608
    Local<Type> returnType(zone_, function_->type()->returnType());
dvander@168
   609
    if (!typeCheckAssignment(node->pos(), type, returnType, true))
dvander@25
   610
        return;
dvander@0
   611
}
dvander@0
   612
dvander@0
   613
void
dvander@0
   614
SemanticAnalysis::visit(ForStatement *node)
dvander@0
   615
{
dvander@71
   616
    LoopScope loop(&loop_);
dvander@71
   617
dvander@12
   618
    if (node->scope())
dvander@12
   619
        scope_ = node->scope();
dvander@25
   620
dvander@22
   621
    if (node->initialization())
dvander@22
   622
        node->initialization()->accept(this);
dvander@25
   623
dvander@25
   624
    if (node->condition()) {
dvander@40
   625
        Local<Type> type(zone_, visitForLoad(node->condition()));
dvander@25
   626
        if (!type || !canTest(node->condition(), type)) {
dvander@25
   627
            return;
dvander@25
   628
        }
dvander@25
   629
    }
dvander@25
   630
dvander@0
   631
    if (node->update())
dvander@0
   632
        node->update()->accept(this);
dvander@25
   633
dvander@71
   634
    ControlStatus status = visitForControl(node->body());
dvander@71
   635
dvander@71
   636
    // If there is a condition, we treat this like a while loop. Otherwise,
dvander@71
   637
    // join point is only reachable if the loop contains a break. The
dvander@71
   638
    // termination status doesn't tell us anything yet.
dvander@71
   639
    if (node->condition() || loop.breaks())
dvander@71
   640
        control_->merge(status, ControlStatus(false, Returns_Never));
dvander@71
   641
    else
dvander@71
   642
        control_->terminate(status.returns());
dvander@25
   643
dvander@12
   644
    if (node->scope())
dvander@12
   645
        scope_ = scope_->enclosing();
dvander@0
   646
}
dvander@0
   647
dvander@9
   648
void 
dvander@9
   649
SemanticAnalysis::visit(WhileStatement *node)
dvander@9
   650
{
dvander@71
   651
    LoopScope loop(&loop_);
dvander@25
   652
dvander@40
   653
    Local<Type> type(zone_, visitForLoad(node->condition()));
dvander@25
   654
    if (!type || !canTest(node->condition(), type)) {
dvander@25
   655
        return;
dvander@25
   656
    }
dvander@25
   657
dvander@71
   658
    ControlStatus status = visitForControl(node->body());
dvander@71
   659
dvander@71
   660
    // Detect loops that will always have a fork in the control-flow graph.
dvander@71
   661
    // This will be a |while| loop, or a |do-while| loop whose body does
dvander@71
   662
    // not terminate.
dvander@71
   663
    //
dvander@71
   664
    // For now, we treat these as an |if| regardless of the direction the
dvander@71
   665
    // branch can take. That means the control-flow is always conditional.
dvander@71
   666
    if (node->token() == TOK_WHILE ||
dvander@71
   667
        !status.terminates() ||
dvander@71
   668
        loop.breaks())
dvander@71
   669
    {
dvander@71
   670
        control_->merge(status, ControlStatus(false, Returns_Never));
dvander@71
   671
    } else {
dvander@71
   672
        // At this point, we've got a do-while loop with a |return| or
dvander@71
   673
        // |continue|, meaning that the rest of the block is unreachable.
dvander@71
   674
        control_->terminate(status.returns());
dvander@71
   675
    }
dvander@9
   676
}
dvander@9
   677
dvander@0
   678
void
dvander@0
   679
SemanticAnalysis::visit(BlockStatement *node)
dvander@0
   680
{
dvander@12
   681
    if (node->scope())
dvander@12
   682
        scope_ = node->scope();
dvander@0
   683
    for (size_t i = 0; i < node->statements()->length(); i++) {
dvander@0
   684
        Statement *statement = node->statements()->at(i);
dvander@0
   685
        statement->accept(this);
dvander@0
   686
    }
dvander@12
   687
    if (node->scope())
dvander@12
   688
        scope_ = scope_->enclosing();
dvander@0
   689
}
dvander@0
   690
dvander@145
   691
static inline bool
dvander@145
   692
IsScalarString(Type *type)
dvander@145
   693
{
dvander@145
   694
    if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
dvander@145
   695
        return true;
dvander@145
   696
    if (type->isReference())
dvander@145
   697
        return IsScalarString(type->contained());
dvander@145
   698
    return false;
dvander@145
   699
}
dvander@145
   700
dvander@0
   701
void
dvander@0
   702
SemanticAnalysis::visit(VariableDeclaration *node)
dvander@0
   703
{
dvander@145
   704
    Local<Type> type(zone_, bindType(node->pos(), node->type()));
dvander@0
   705
    if (!type)
dvander@0
   706
        return;
dvander@0
   707
dvander@0
   708
    if (node->postDimensions()) {
dvander@37
   709
        Local<Type> init(zone_);
dvander@21
   710
        if (node->initialization()) {
dvander@71
   711
            if ((init = visitForLoad(node->initialization())) == NULL)
dvander@21
   712
                return;
dvander@21
   713
        }
dvander@21
   714
dvander@55
   715
        if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
dvander@25
   716
            cc_.reportError(node->pos(), Message_MaximumArrayDepth);
dvander@0
   717
            return;
dvander@0
   718
        }
dvander@0
   719
dvander@21
   720
        // If we have an initializer, make sure it's the same type.
dvander@55
   721
        if (init && node->postDimensions()->length() != init->levels()) {
dvander@25
   722
            cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
dvander@25
   723
            return;
dvander@21
   724
        }
dvander@21
   725
dvander@37
   726
        Local<Type> check(zone_, init);
dvander@55
   727
        for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
dvander@0
   728
            Expression *expr = node->postDimensions()->at(i);
dvander@25
   729
            int size = -1;
dvander@0
   730
dvander@25
   731
            if (expr) {
dvander@37
   732
                Local<Type> exprType(zone_, visitForLoad(expr));
dvander@25
   733
                if (!exprType)
dvander@25
   734
                    return;
dvander@0
   735
dvander@25
   736
                if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
dvander@25
   737
                    cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
dvander@0
   738
                    return;
dvander@0
   739
                }
dvander@25
   740
dvander@25
   741
                BoxedPrimitive box;
dvander@25
   742
                if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
dvander@25
   743
                    size = box.toInt();
dvander@25
   744
                    if (size <= 0) {
dvander@25
   745
                        cc_.reportError(expr->pos(), Message_BadArraySize);
dvander@25
   746
                        return;
dvander@25
   747
                    }
danderson@92
   748
                    if (size >= int(INT_MAX / sizeof(int))) {
dvander@25
   749
                        cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
dvander@25
   750
                        return;
dvander@25
   751
                    }
dvander@25
   752
dvander@25
   753
                    if (check) {
dvander@25
   754
                        if (check->elements() == -1) {
dvander@25
   755
                            cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
dvander@25
   756
                            return;
dvander@25
   757
                        }
dvander@25
   758
dvander@25
   759
                        if (check->isCharArray()) {
dvander@25
   760
                            if (check->elements() > size) {
dvander@25
   761
                                cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
dvander@25
   762
                                return;
dvander@25
   763
                            }
dvander@25
   764
                        } else if (check->elements() != size) {
dvander@25
   765
                            cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
dvander@25
   766
                            return;
dvander@25
   767
                        }
dvander@25
   768
                    }
dvander@25
   769
                } else {
dvander@25
   770
                    if (init) {
dvander@25
   771
                        cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
dvander@25
   772
                        return;
dvander@25
   773
                    }
dvander@25
   774
dvander@25
   775
                    // here until we get dynamic array support.
dvander@25
   776
                    cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
dvander@0
   777
                    return;
dvander@0
   778
                }
dvander@21
   779
            } else {
dvander@25
   780
                // Infer the size from the initializer.
dvander@25
   781
                if (!init) {
dvander@25
   782
                    cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
dvander@25
   783
                    return;
dvander@25
   784
                }
dvander@25
   785
                if (init->elements() == -1) {
dvander@25
   786
                    cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
dvander@25
   787
                    return;
dvander@25
   788
                }
dvander@25
   789
                size = init->elements();
dvander@0
   790
            }
dvander@0
   791
dvander@67
   792
            type = zone_->types()->unsafeArray(type, size, false);
dvander@25
   793
            if (!type)
dvander@25
   794
                return;
dvander@21
   795
dvander@21
   796
            if (check)
dvander@21
   797
                check = check->contained();
dvander@0
   798
        }
dvander@8
   799
    } else {
dvander@10
   800
        if (node->initialization()) {
dvander@40
   801
            Local<Type> right(zone_, visitForLoad(node->initialization()));
dvander@25
   802
            if (!right)
dvander@25
   803
                return;
dvander@168
   804
            if (!typeCheckAssignment(node->pos(), type, right, true))
dvander@25
   805
                return;
dvander@10
   806
        }
dvander@147
   807
dvander@147
   808
        if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
dvander@25
   809
            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
dvander@21
   810
            return;
dvander@21
   811
        }
dvander@0
   812
    }
dvander@0
   813
dvander@147
   814
    // If this variable is stack allocated, we could use the LIFO heap
dvander@147
   815
    // to allocate it. If that's the case, make sure to reserve a slot
dvander@147
   816
    // so we can unwind the LIFO heap at the end of this scope.
dvander@147
   817
    if (!node->variable()->needsHeapAllocation()) {
dvander@147
   818
        if (type->isArray() || type->isStruct())
dvander@147
   819
            scope_->setUsesLifoHeap();
dvander@147
   820
    }
dvander@147
   821
dvander@0
   822
    node->variable()->setType(type);
dvander@0
   823
}
dvander@0
   824
dvander@0
   825
void
dvander@4
   826
SemanticAnalysis::visit(IntegerLiteral *node)
dvander@0
   827
{
dvander@30
   828
    node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
dvander@0
   829
}
dvander@0
   830
dvander@0
   831
void
dvander@143
   832
SemanticAnalysis::visit(BooleanLiteral *node)
dvander@143
   833
{
dvander@143
   834
    node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
dvander@143
   835
}
dvander@143
   836
dvander@143
   837
void
dvander@0
   838
SemanticAnalysis::visit(ExpressionStatement *node)
dvander@0
   839
{
dvander@71
   840
    visitAndApplyType(node->expression());
dvander@0
   841
}
dvander@0
   842
dvander@168
   843
Box *
dvander@168
   844
SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
dvander@168
   845
{
dvander@172
   846
    Local<Type> given(zone_, visitForLoad(parameter->initializer()));
dvander@172
   847
dvander@168
   848
    BoxedPrimitive prim;
dvander@168
   849
    if (EvaluateForConstant(parameter->initializer(), &prim)) {
dvander@168
   850
        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
dvander@168
   851
            return NULL;
dvander@168
   852
dvander@168
   853
        if (prim.type() == PrimitiveType_Int32)
dvander@172
   854
            return Box::New(zone_, given, prim.toInt());
dvander@172
   855
        return Box::New(zone_, given, prim.toFloat());
dvander@169
   856
    } else if (parameter->initializer()->isStringLiteral()) {
dvander@169
   857
        StringLiteral *literal = parameter->initializer()->toStringLiteral();
dvander@169
   858
dvander@169
   859
        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
dvander@169
   860
            return NULL;
dvander@169
   861
dvander@169
   862
        Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
dvander@169
   863
        if (!map)
dvander@169
   864
            return NULL;
dvander@169
   865
dvander@169
   866
        Local<Array> array(zone_,
dvander@169
   867
            Array::NewString(zone_,
dvander@169
   868
                             map,
dvander@169
   869
                             literal->string()->raw(),
dvander@169
   870
                             literal->string()->length(),
dvander@169
   871
                             Heap::Tenure_Old));
dvander@169
   872
        if (!array)
dvander@169
   873
            return NULL;
dvander@169
   874
dvander@169
   875
        return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
dvander@168
   876
    }
dvander@168
   877
dvander@168
   878
    cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
dvander@168
   879
    return NULL;
dvander@168
   880
}
dvander@168
   881
dvander@14
   882
bool
dvander@14
   883
SemanticAnalysis::preanalyze(FunctionStatement *node)
dvander@14
   884
{
dvander@57
   885
    Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
dvander@14
   886
    if (!args)
dvander@14
   887
        return false;
dvander@14
   888
dvander@168
   889
    Local<FixedArray> defaults(zone_);
dvander@168
   890
dvander@14
   891
    // Apply types to arguments.
dvander@57
   892
    for (size_t i = 0; i < node->parameters()->length(); i++) {
dvander@14
   893
        Parameter *parameter = node->parameters()->at(i);
dvander@14
   894
        
dvander@145
   895
        Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
dvander@14
   896
        if (!type)
dvander@14
   897
            return false;
dvander@14
   898
dvander@14
   899
        if (parameter->reference()) {
dvander@66
   900
            if (parameter->dimensions()) {
dvander@66
   901
                cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
dvander@168
   902
                return false;
dvander@66
   903
            }
dvander@66
   904
dvander@164
   905
            if (type->isStruct()) {
dvander@164
   906
                cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
dvander@168
   907
                return false;
dvander@164
   908
            }
dvander@164
   909
dvander@67
   910
            type = zone_->types()->getReference(type, parameter->isConst());
dvander@14
   911
            if (!type)
dvander@14
   912
                return false;
dvander@66
   913
        } else if (parameter->dimensions()) {
dvander@66
   914
            if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
dvander@68
   915
                cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
dvander@68
   916
                return false;
dvander@68
   917
            }
dvander@68
   918
dvander@68
   919
            if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
dvander@68
   920
                cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
dvander@66
   921
                return false;
dvander@66
   922
            }
dvander@66
   923
dvander@66
   924
            for (size_t i = parameter->dimensions()->length() - 1;
dvander@66
   925
                 i < parameter->dimensions()->length();
dvander@66
   926
                 i++)
dvander@66
   927
            {
dvander@66
   928
                int size = Type::UNKNOWN_SIZE;
dvander@66
   929
                if (Expression *expr = parameter->dimensions()->at(i)) {
dvander@66
   930
                    BoxedPrimitive box;
dvander@168
   931
                    if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
dvander@66
   932
                        cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
dvander@66
   933
                        return false;
dvander@66
   934
                    }
dvander@66
   935
                    size = box.toInt();
dvander@66
   936
                }
dvander@66
   937
dvander@67
   938
                type = zone_->types()->unsafeArray(type, size, parameter->isConst());
dvander@66
   939
                if (!type)
dvander@66
   940
                    return false;
dvander@66
   941
            }
dvander@14
   942
        }
dvander@14
   943
dvander@145
   944
        if (IsScalarString(type)) {
dvander@68
   945
            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
dvander@68
   946
            return false;
dvander@68
   947
        }
dvander@68
   948
dvander@30
   949
        args->set(zone_, i, type);
dvander@14
   950
        parameter->variable()->setType(type);
dvander@169
   951
dvander@169
   952
        if (parameter->initializer()) {
dvander@169
   953
            if (!defaults) {
dvander@169
   954
                defaults = FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old);
dvander@169
   955
                if (!defaults)
dvander@169
   956
                    return false;
dvander@169
   957
            }
dvander@169
   958
dvander@169
   959
            Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
dvander@169
   960
            if (!box)
dvander@169
   961
                return false;
dvander@169
   962
dvander@169
   963
            defaults->set(zone_, i, box);
dvander@169
   964
        }
dvander@14
   965
    }
dvander@14
   966
dvander@71
   967
    Local<Type> returnType(zone_);
dvander@145
   968
    if (node->returnType() ||
dvander@145
   969
        node->hasExplicitReturn() ||
dvander@145
   970
        node->fun()->isNative())
dvander@145
   971
    {
dvander@145
   972
        returnType = bindType(node->pos(), node->returnType());
dvander@132
   973
    } else {
dvander@71
   974
        returnType = zone_->types()->getVoid();
dvander@132
   975
    }
dvander@14
   976
    if (!returnType)
dvander@14
   977
        return false;
dvander@14
   978
dvander@68
   979
    Local<Type> funtype(zone_);
dvander@68
   980
    if (node->fun()->isNative())
dvander@168
   981
        funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
dvander@68
   982
    else
dvander@168
   983
        funtype = zone_->types()->newFunction(returnType, args, defaults);
dvander@14
   984
    if (!funtype)
dvander@14
   985
        return false;
dvander@63
   986
    
dvander@63
   987
    // If the function already has a type, it was forward declared before, and
dvander@63
   988
    // now this is our chance to type check the second declaration.
dvander@63
   989
    if (node->fun()->type()) {
dvander@63
   990
        Local<Type> forward(zone_, node->fun()->type());
dvander@63
   991
        if (!Type::Compare(funtype, forward)) {
dvander@63
   992
            cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
dvander@63
   993
            return false;
dvander@63
   994
        }
dvander@63
   995
        node->fun()->setForwardType(forward);
dvander@63
   996
    }
dvander@14
   997
dvander@14
   998
    node->fun()->setType(funtype);
dvander@63
   999
dvander@14
  1000
    return true;
dvander@14
  1001
}
dvander@14
  1002
dvander@0
  1003
void
dvander@0
  1004
SemanticAnalysis::visit(FunctionStatement *node)
dvander@0
  1005
{
dvander@137
  1006
    function_ = node->fun();
dvander@12
  1007
    scope_ = node->scope();
dvander@71
  1008
dvander@71
  1009
    ControlScope control(&control_);
dvander@71
  1010
    if (node->body()) {
dvander@63
  1011
        node->body()->accept(this);
dvander@71
  1012
dvander@71
  1013
        ControlStatus status = control.status();
dvander@71
  1014
        if (status.returns() == Returns_Sometimes) {
dvander@71
  1015
            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
dvander@71
  1016
        } else if (status.returns() == Returns_Never) {
dvander@137
  1017
            if (!function_->type()->returnType()->isVoid())
dvander@71
  1018
                cc_.reportError(node->pos(), Message_MissingReturnValue);
dvander@71
  1019
        }
dvander@71
  1020
    }
dvander@71
  1021
dvander@12
  1022
    scope_ = NULL;
dvander@25
  1023
    function_ = NULL;
dvander@0
  1024
}
dvander@0
  1025
dvander@145
  1026
void
dvander@168
  1027
SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
dvander@145
  1028
{
dvander@168
  1029
    cc_.reportError(pos, Message_TypeMismatch,
dvander@145
  1030
                    GetTypeName(actual),
dvander@145
  1031
                    GetTypeName(given));
dvander@145
  1032
}
dvander@145
  1033
dvander@25
  1034
bool
dvander@168
  1035
SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
dvander@168
  1036
                                           Handle<Type> argActual, bool forAssign)
dvander@14
  1037
{
dvander@40
  1038
    Local<Type> actual(zone_, argActual);
dvander@40
  1039
    Local<Type> given(zone_, argGiven);
dvander@40
  1040
dvander@25
  1041
    if (!given->isArray()) {
dvander@168
  1042
        cc_.reportError(pos, Message_ExpectedArray);
dvander@25
  1043
        return false;
dvander@25
  1044
    }
dvander@25
  1045
    if (given->levels() != actual->levels()) {
dvander@168
  1046
        cc_.reportError(pos, Message_ArrayDimensionsMismatch);
dvander@25
  1047
        return false;
dvander@25
  1048
    }
dvander@25
  1049
dvander@25
  1050
    unsigned level = 0;
dvander@25
  1051
    while (given->isArray()) {
dvander@25
  1052
        if (actual->elements() != -1) {
dvander@25
  1053
            if (forAssign) {
dvander@25
  1054
                if (given->elements() == -1 || actual->elements() == -1) {
dvander@168
  1055
                    cc_.reportError(pos, Message_ArraySizeNotKnown);
dvander@25
  1056
                    return false;
dvander@25
  1057
                }
dvander@25
  1058
dvander@25
  1059
                if (actual->isCharArray()) {
dvander@25
  1060
                    // String assignment can have a truncated |given|.
dvander@25
  1061
                    if (given->elements() > actual->elements()) {
dvander@168
  1062
                        cc_.reportError(pos, Message_ArrayAssignmentTooBig);
dvander@25
  1063
                        return false;
dvander@25
  1064
                    }
dvander@25
  1065
                } else {
dvander@25
  1066
                    if (given->elements() != actual->elements()) {
dvander@168
  1067
                        cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
dvander@25
  1068
                        return false;
dvander@25
  1069
                    }
dvander@25
  1070
                }
dvander@25
  1071
            } else {
dvander@25
  1072
                if (actual->elements() != -1 && given->elements() != actual->elements()) {
dvander@168
  1073
                    cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
dvander@25
  1074
                    return false;
dvander@25
  1075
                }
dvander@25
  1076
            }
dvander@25
  1077
        }
dvander@25
  1078
        given = given->contained();
dvander@25
  1079
        actual = actual->contained();
dvander@14
  1080
    }
dvander@14
  1081
dvander@168
  1082
    return typeCheckAssignment(pos, given, actual, forAssign);
dvander@25
  1083
}
dvander@25
  1084
dvander@25
  1085
bool
dvander@168
  1086
SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
dvander@168
  1087
                                      Handle<Type> argActual, bool forAssign)
dvander@25
  1088
{
dvander@40
  1089
    Local<Type> actual(zone_, argActual);
dvander@40
  1090
    Local<Type> given(zone_, argGiven);
dvander@40
  1091
dvander@25
  1092
    if (actual->isArray())
dvander@168
  1093
        return typeCheckArrayAssignment(pos, given, actual, forAssign);
dvander@25
  1094
dvander@25
  1095
    if (given->isArray()) {
dvander@168
  1096
        cc_.reportError(pos, Message_CannotAssignArrayToScalar);
dvander@25
  1097
        return false;
dvander@25
  1098
    }
dvander@25
  1099
dvander@47
  1100
    // The given type may not have been dereferenced.
dvander@47
  1101
    if (given->isReference())
dvander@47
  1102
        given = given->contained();
dvander@47
  1103
    if (actual->isReference())
dvander@47
  1104
        actual = actual->contained();
dvander@47
  1105
dvander@168
  1106
    // We coerce unchecked to a few things.
dvander@168
  1107
    if (actual->isUnchecked() || given->isUnchecked()) {
dvander@168
  1108
        Type *check = actual->isUnchecked() ? given : actual;
dvander@168
  1109
        if (check->isUnchecked() ||
dvander@168
  1110
            check->isEnum() ||
dvander@168
  1111
            check->isInt32() ||
dvander@168
  1112
            check->isBool() ||
dvander@168
  1113
            check->isFloat())
dvander@168
  1114
        {
dvander@168
  1115
            return true;
dvander@168
  1116
        }
dvander@168
  1117
        typeMismatch(pos, actual, given);
dvander@168
  1118
        return false;
dvander@168
  1119
    }
dvander@168
  1120
dvander@145
  1121
    if (actual->isEnum()) {
dvander@145
  1122
        if (!given->isEnum() || actual != given) {
dvander@168
  1123
            typeMismatch(pos, actual, given);
dvander@145
  1124
            return false;
dvander@145
  1125
        }
dvander@145
  1126
        return true;
dvander@145
  1127
    }
dvander@145
  1128
dvander@149
  1129
    if (actual->isStruct()) {
dvander@149
  1130
        if (!given->isStruct() || actual != given) {
dvander@168
  1131
            typeMismatch(pos, actual, given);
dvander@149
  1132
            return false;
dvander@149
  1133
        }
dvander@149
  1134
        return true;
dvander@149
  1135
    }
dvander@149
  1136
dvander@149
  1137
    if (given->isEnum() || given->isFunction() || given->isStruct()) {
dvander@168
  1138
        typeMismatch(pos, actual, given);
dvander@25
  1139
        return false;
dvander@25
  1140
    }
dvander@145
  1141
dvander@168
  1142
    // This coercion is trivial.
dvander@168
  1143
    if (given->isBool() && actual->isInt32())
dvander@168
  1144
        return true;
dvander@168
  1145
dvander@25
  1146
    if (given->primitive() != actual->primitive()) {
dvander@168
  1147
        typeMismatch(pos, actual, given);
dvander@25
  1148
        return false;
dvander@25
  1149
    }
dvander@25
  1150
dvander@25
  1151
    return true;
dvander@25
  1152
}
dvander@25
  1153
dvander@25
  1154
bool
dvander@40
  1155
SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
dvander@25
  1156
{
dvander@168
  1157
    return typeCheckAssignment(node->pos(), given, actual, false);
dvander@168
  1158
}
dvander@168
  1159
dvander@168
  1160
bool
dvander@168
  1161
SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
dvander@168
  1162
{
dvander@168
  1163
    if (type->parameters()->length() == actual)
dvander@168
  1164
        return true;
dvander@168
  1165
dvander@168
  1166
    if (actual > type->parameters()->length()) {
dvander@168
  1167
        if (!type->isNative() || !type->isNativeVariadic())
dvander@168
  1168
            return false;
dvander@168
  1169
        return true;
dvander@168
  1170
    }
dvander@168
  1171
dvander@168
  1172
    if (!type->defaults())
dvander@168
  1173
        return false;
dvander@168
  1174
dvander@168
  1175
    // Missing arguments. See if there's a default argument for each missing
dvander@168
  1176
    // actual.
dvander@168
  1177
    for (unsigned i = actual; i < type->parameters()->length(); i++) {
dvander@168
  1178
        if (!type->defaults()->at(i))
dvander@168
  1179
            return false;
dvander@168
  1180
    }
dvander@168
  1181
dvander@168
  1182
    return true;
dvander@14
  1183
}
dvander@14
  1184
dvander@0
  1185
void
dvander@0
  1186
SemanticAnalysis::visit(CallExpression *node)
dvander@0
  1187
{
dvander@40
  1188
    Local<Type> type(zone_, visitForLoad(node->callee()));
dvander@14
  1189
    if (!type)
dvander@14
  1190
        return;
dvander@14
  1191
dvander@25
  1192
    if (!type->isFunction()) {
dvander@25
  1193
        cc_.reportError(node->pos(), Message_CalleeNotFunction);
dvander@25
  1194
        return;
dvander@25
  1195
    }
dvander@168
  1196
dvander@168
  1197
    if (!checkArgumentCount(type, node->arguments()->length())) {
dvander@168
  1198
        cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
dvander@168
  1199
        return;
dvander@25
  1200
    }
dvander@14
  1201
dvander@63
  1202
    // Currently, only calls from a NameProxy are possible.
dvander@63
  1203
    NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
dvander@63
  1204
    if (fun->isForward()) {
dvander@63
  1205
        cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
dvander@63
  1206
        return;
dvander@63
  1207
    }
dvander@63
  1208
dvander@55
  1209
    for (unsigned i = 0; i < node->arguments()->length(); i++) {
dvander@17
  1210
        // Note: we don't compute references unless the callee needs a
dvander@17
  1211
        // reference type.
dvander@14
  1212
        Expression *expression = node->arguments()->at(i);
dvander@40
  1213
        Local<Type> given(zone_, visitAndApplyType(expression));
dvander@14
  1214
        if (!given)
dvander@14
  1215
            return;
dvander@14
  1216
dvander@71
  1217
        // Since we skip a load, check for a call expression that returns void.
dvander@71
  1218
        if (given->isVoid()) {
dvander@71
  1219
            assert(expression->isCallExpression());
dvander@71
  1220
            CallExpression *call = expression->toCallExpression();
dvander@71
  1221
            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
dvander@71
  1222
            return;
dvander@71
  1223
        }
dvander@71
  1224
        
dvander@68
  1225
        bool mustComputeReference;
dvander@68
  1226
        if (i >= type->parameters()->length()) {
dvander@68
  1227
            // Special handling for natives. Arguments past the formal must
dvander@68
  1228
            // always have references computed. However, arrays are already
dvander@68
  1229
            // references for natives.  
dvander@68
  1230
            assert(type->isNative() && type->isNativeVariadic());
dvander@68
  1231
            mustComputeReference = !given->isReference() && !given->isArray();
dvander@68
  1232
        } else {
dvander@68
  1233
            Local<Type> actual(zone_, type->parameterAt(i));
dvander@166
  1234
dvander@166
  1235
            if (expression->isIndexExpression() && actual->isArray()) {
dvander@166
  1236
                // We special case the ability to pass x[y] into x[], which
dvander@166
  1237
                // creates an array slice. We only do this if we know the
dvander@166
  1238
                // assignment would otherwise not type-check.
dvander@166
  1239
                IndexExpression *index = expression->toIndexExpression();
dvander@166
  1240
                if (index->left()->type()->levels() == actual->levels())
dvander@166
  1241
                    given = index->left()->type();
dvander@166
  1242
            }
dvander@166
  1243
dvander@68
  1244
            if (!typeCheckParameter(expression, given, actual))
dvander@68
  1245
                return;
dvander@68
  1246
            mustComputeReference = actual->isReference() && !given->isReference();
dvander@68
  1247
        }
dvander@14
  1248
dvander@14
  1249
        // If the actual is a reference, and the given is not, we'll need to
dvander@14
  1250
        // compute a reference, which may be allocated on the stack.
dvander@68
  1251
        if (mustComputeReference)
dvander@14
  1252
            scope_->setUsesLifoHeap();
dvander@14
  1253
    }
dvander@66
  1254
dvander@66
  1255
    node->setType(fun->type()->returnType());
dvander@0
  1256
}
dvander@0
  1257
dvander@0
  1258
void
dvander@172
  1259
SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
dvander@172
  1260
{
dvander@172
  1261
    if (other.returns() < status().returns())
dvander@172
  1262
        return;
dvander@172
  1263
dvander@172
  1264
    if (other.terminates())
dvander@172
  1265
        terminate(other.returns());
dvander@172
  1266
    else
dvander@172
  1267
        returns(other.returns());
dvander@172
  1268
}
dvander@172
  1269
dvander@172
  1270
void
dvander@71
  1271
SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
dvander@71
  1272
{
dvander@71
  1273
    // If both sides terminate in a return, we consider this a return as well.
dvander@71
  1274
    if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
dvander@71
  1275
        terminate(Returns_Always);
dvander@71
  1276
        return;
dvander@71
  1277
    }
dvander@71
  1278
dvander@71
  1279
    ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
dvander@71
  1280
                          ? Returns_Never
dvander@71
  1281
                          : Returns_Sometimes;
dvander@71
  1282
dvander@71
  1283
    if (left.terminates() && right.terminates())
dvander@71
  1284
        terminate(status);
dvander@71
  1285
    else
dvander@71
  1286
        returns(status);
dvander@71
  1287
}
dvander@71
  1288
dvander@71
  1289
void
dvander@0
  1290
SemanticAnalysis::visit(IfStatement *node)
dvander@0
  1291
{
dvander@40
  1292
    Local<Type> type(zone_, visitForLoad(node->condition()));
dvander@25
  1293
    if (!type)
dvander@25
  1294
        return;
dvander@25
  1295
dvander@25
  1296
    if (!canTest(node, type))
dvander@25
  1297
        return;
dvander@25
  1298
dvander@71
  1299
    ControlStatus trueBranch = visitForControl(node->ifTrue());
dvander@71
  1300
    ControlStatus falseBranch = ControlStatus(false, Returns_Never);
dvander@71
  1301
dvander@10
  1302
    if (node->ifFalse())
dvander@71
  1303
        falseBranch = visitForControl(node->ifFalse());
dvander@71
  1304
dvander@71
  1305
    control_->merge(trueBranch, falseBranch);
dvander@0
  1306
}
dvander@0
  1307
dvander@0
  1308
void
dvander@0
  1309
SemanticAnalysis::visit(IndexExpression *node)
dvander@0
  1310
{
dvander@71
  1311
    Local<Type> left(zone_, visitForLoad(node->left()));
dvander@40
  1312
    Local<Type> right(zone_, visitForLoad(node->right()));
dvander@0
  1313
dvander@25
  1314
    if (!left || !right)
dvander@25
  1315
        return;
dvander@25
  1316
dvander@145
  1317
    if (!right->isInt32() && !right->isEnum()) {
dvander@25
  1318
        cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
dvander@0
  1319
        return;
dvander@0
  1320
    }
dvander@25
  1321
    if (!left->isArray()) {
dvander@25
  1322
        cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
dvander@0
  1323
        return;
dvander@0
  1324
    }
dvander@160
  1325
dvander@160
  1326
    // Note: char arrays are automatically up-casted to return an int32.
dvander@160
  1327
    if (left->isCharArray())
dvander@160
  1328
        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
dvander@160
  1329
    else
dvander@160
  1330
        node->setType(left->contained());
dvander@0
  1331
}
dvander@2
  1332
dvander@2
  1333
void
dvander@148
  1334
SemanticAnalysis::visit(FieldExpression *node)
dvander@148
  1335
{
dvander@148
  1336
    Local<Type> left(zone_, visitForLoad(node->left()));
dvander@148
  1337
    if (!left)
dvander@148
  1338
        return;
dvander@148
  1339
dvander@148
  1340
    if (!left->isStruct()) {
dvander@148
  1341
        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
dvander@148
  1342
                        GetTypeName(left));
dvander@148
  1343
        return;
dvander@148
  1344
    }
dvander@148
  1345
dvander@148
  1346
    Local<String> field(zone_, node->field());
dvander@148
  1347
dvander@148
  1348
    unsigned offset;
dvander@148
  1349
    Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
dvander@148
  1350
    if (!desc) {
dvander@148
  1351
        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
dvander@148
  1352
                        GetTypeName(left));
dvander@148
  1353
        return;
dvander@148
  1354
    }
dvander@148
  1355
dvander@148
  1356
    node->setFieldIndex(offset);
dvander@148
  1357
    node->setType(desc->type());
dvander@148
  1358
}
dvander@148
  1359
dvander@148
  1360
void
dvander@2
  1361
SemanticAnalysis::visit(EnumStatement *node)
dvander@2
  1362
{
dvander@172
  1363
    Local<String> name(zone_, node->name());
dvander@172
  1364
    Local<Type> type(zone_);
dvander@172
  1365
    if (name)
dvander@172
  1366
        type = zone_->types()->newEnum(name);
dvander@172
  1367
    else
dvander@172
  1368
        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
dvander@3
  1369
dvander@172
  1370
    if (!type)
dvander@172
  1371
        return;
dvander@172
  1372
dvander@172
  1373
    if (node->decl())
dvander@172
  1374
        node->decl()->setType(type);
dvander@2
  1375
dvander@2
  1376
    int value = 0;
dvander@57
  1377
    for (size_t i = 0; i < node->entries()->length(); i++) {
dvander@2
  1378
        EnumStatement::Entry &entry = node->entries()->at(i);
dvander@2
  1379
dvander@2
  1380
        BoxedPrimitive box = BoxedPrimitive::Int(value);
dvander@2
  1381
        if (entry.expr) {
dvander@2
  1382
            entry.expr->accept(this);
dvander@168
  1383
            if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
dvander@25
  1384
                cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
dvander@25
  1385
                return;
dvander@25
  1386
            }
dvander@2
  1387
dvander@2
  1388
            assert(box.type() == PrimitiveType_Int32);
dvander@2
  1389
            value = box.toInt();
dvander@2
  1390
        }
dvander@2
  1391
dvander@2
  1392
        entry.name->set(type, box);
dvander@2
  1393
        value++;
dvander@2
  1394
    }
dvander@2
  1395
}
dvander@4
  1396
dvander@172
  1397
static int
dvander@172
  1398
SortCaseIntValues(const void *p1, const void *p2)
dvander@172
  1399
{
dvander@172
  1400
    CaseValue *v1 = (CaseValue *)p1;
dvander@172
  1401
    CaseValue *v2 = (CaseValue *)p2;
dvander@172
  1402
dvander@172
  1403
    return v1->box.toInt() - v2->box.toInt();
dvander@172
  1404
}
dvander@172
  1405
dvander@172
  1406
void
dvander@172
  1407
SemanticAnalysis::visit(SwitchStatement *node)
dvander@172
  1408
{
dvander@172
  1409
    Local<Type> caseType(zone_, visitForLoad(node->expression()));
dvander@172
  1410
    if (!caseType)
dvander@172
  1411
        return;
dvander@172
  1412
dvander@172
  1413
    if (!caseType->isEnum() && !caseType->isInt32()) {
dvander@172
  1414
        cc_.reportError(node->pos(), Message_CaseMustBeInteger);
dvander@172
  1415
        return;
dvander@172
  1416
    }
dvander@172
  1417
dvander@172
  1418
    PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
dvander@172
  1419
    ControlStatus status = ControlStatus(false, Returns_Never);
dvander@172
  1420
dvander@172
  1421
    Local<Type> check(zone_);
dvander@172
  1422
    for (size_t i = 0; i < node->cases()->length(); i++) {
dvander@172
  1423
        Case *c = node->cases()->at(i);
dvander@172
  1424
dvander@172
  1425
        check = visitForLoad(c->expression());
dvander@172
  1426
        if (!check)
dvander@172
  1427
            return;
dvander@172
  1428
dvander@172
  1429
        if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
dvander@172
  1430
            return;
dvander@172
  1431
dvander@172
  1432
        CaseValue v(i);
dvander@172
  1433
        if (!EvaluateForConstant(c->expression(), &v.box)) {
dvander@172
  1434
            cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
dvander@172
  1435
            return;
dvander@172
  1436
        }
dvander@172
  1437
        if (!values->append(v))
dvander@172
  1438
            return;
dvander@172
  1439
dvander@172
  1440
        if (c->others()) {
dvander@172
  1441
            for (size_t j = 0; j < c->others()->length(); j++) {
dvander@172
  1442
                Expression *expr = c->others()->at(j);
dvander@172
  1443
                check = visitForLoad(expr);
dvander@172
  1444
                if (!check)
dvander@172
  1445
                    return;
dvander@172
  1446
dvander@172
  1447
                if (!typeCheckAssignment(expr->pos(), check, caseType, false))
dvander@172
  1448
                    return;
dvander@172
  1449
dvander@172
  1450
                CaseValue v(i);
dvander@172
  1451
                if (!EvaluateForConstant(expr, &v.box)) {
dvander@172
  1452
                    cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
dvander@172
  1453
                    return;
dvander@172
  1454
                }
dvander@172
  1455
                if (!values->append(v))
dvander@172
  1456
                    return;
dvander@172
  1457
            }
dvander@172
  1458
        }
dvander@172
  1459
dvander@172
  1460
        ControlStatus latest = visitForControl(c->statement());
dvander@172
  1461
dvander@172
  1462
        if (i != 0)
dvander@172
  1463
            control_->merge(status, latest);
dvander@172
  1464
dvander@172
  1465
        status = latest;
dvander@172
  1466
    }
dvander@172
  1467
dvander@172
  1468
    if (node->defaultCase()) {
dvander@172
  1469
        ControlStatus latest = visitForControl(node->defaultCase());
dvander@172
  1470
dvander@172
  1471
        if (node->cases()->length()) {
dvander@172
  1472
            // If we had any other cases, we must merge.
dvander@172
  1473
            control_->merge(status, latest);
dvander@172
  1474
        } else {
dvander@172
  1475
            // Otherwise, control-flow always flows through here.
dvander@172
  1476
            control_->inherit(latest);
dvander@172
  1477
        }
dvander@172
  1478
    } else if (node->cases()->length()) {
dvander@172
  1479
        control_->merge(status, ControlStatus(false, Returns_Never));
dvander@172
  1480
    }
dvander@172
  1481
dvander@172
  1482
    if (values->length() > 1) {
dvander@172
  1483
        qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
dvander@172
  1484
dvander@172
  1485
        for (size_t i = 1; i < values->length(); i++) {
dvander@172
  1486
            CaseValue &prev = values->at(i - 1);
dvander@172
  1487
            CaseValue &cur = values->at(i);
dvander@172
  1488
            if (prev.box.toInt() == cur.box.toInt()) {
dvander@172
  1489
                cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
dvander@172
  1490
                return;
dvander@172
  1491
            }
dvander@172
  1492
        }
dvander@172
  1493
    }
dvander@172
  1494
dvander@172
  1495
    node->setCaseValueList(values);
dvander@172
  1496
}
dvander@172
  1497
dvander@4
  1498
void
dvander@146
  1499
SemanticAnalysis::visit(StructureStatement *node)
dvander@146
  1500
{
dvander@146
  1501
    // If this node already has a type, it was pre-analyzed, so skip it.
dvander@146
  1502
    if (node->decl()->type())
dvander@146
  1503
        return;
dvander@146
  1504
dvander@146
  1505
    FieldList *fields = node->fields();
dvander@146
  1506
    Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
dvander@146
  1507
    if (!desctable)
dvander@146
  1508
        return;
dvander@146
  1509
dvander@153
  1510
    Vector<unsigned> composedList;
dvander@146
  1511
    StructureBufferBuilder builder;
dvander@146
  1512
dvander@146
  1513
    Local<Type> type(zone_);
dvander@146
  1514
    Local<String> name(zone_);
dvander@146
  1515
    Local<Descriptor> desc(zone_);
dvander@146
  1516
    for (size_t i = 0; i < fields->length(); i++) {
dvander@146
  1517
        StructureStatement::Field *field = fields->at(i);
dvander@146
  1518
dvander@146
  1519
        type = bindType(field->pos(), field->type());
dvander@146
  1520
        if (!type)
dvander@146
  1521
            return;
dvander@146
  1522
dvander@159
  1523
        if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
dvander@159
  1524
            cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
dvander@159
  1525
            return;
dvander@159
  1526
        }
dvander@159
  1527
dvander@146
  1528
        unsigned offset;
dvander@146
  1529
        if (!builder.add(type, &offset))
dvander@146
  1530
            return;
dvander@146
  1531
dvander@146
  1532
        name = field->name();
dvander@146
  1533
        desc = Descriptor::New(zone_, name, type, offset);
dvander@146
  1534
        if (!desc)
dvander@146
  1535
            return;
dvander@146
  1536
dvander@146
  1537
        desctable->set(zone_, i, desc);
dvander@153
  1538
dvander@153
  1539
        if (type->isStruct() || type->isArray()) {
dvander@153
  1540
            if (!composedList.append(i))
dvander@153
  1541
                return;
dvander@153
  1542
        }
dvander@146
  1543
    }
dvander@146
  1544
dvander@153
  1545
    Local<FixedArray> composed(zone_);
dvander@153
  1546
    if (composedList.length()) {
dvander@153
  1547
        composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
dvander@153
  1548
        if (!composed)
dvander@153
  1549
            return;
dvander@153
  1550
dvander@153
  1551
        for (unsigned i = 0; i < composedList.length(); i++)
dvander@153
  1552
            composed->set(zone_, i, desctable->at(i));
dvander@153
  1553
    }
dvander@153
  1554
dvander@153
  1555
    Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
dvander@147
  1556
    if (!map)
dvander@147
  1557
        return;
dvander@147
  1558
dvander@146
  1559
    name = node->decl()->name();
dvander@147
  1560
    type = zone_->types()->newStruct(name, desctable, map);
dvander@146
  1561
    if (!type)
dvander@146
  1562
        return;
dvander@146
  1563
dvander@147
  1564
    map->setType(type);
dvander@146
  1565
    node->decl()->setType(type);
dvander@146
  1566
}
dvander@146
  1567
dvander@146
  1568
void
dvander@21
  1569
SemanticAnalysis::visit(StringLiteral *node)
dvander@21
  1570
{
dvander@40
  1571
    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
dvander@21
  1572
    if (!type)
dvander@21
  1573
        return;
dvander@21
  1574
dvander@30
  1575
    type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
dvander@21
  1576
    if (!type)
dvander@21
  1577
        return;
dvander@21
  1578
dvander@21
  1579
    node->setType(type);
dvander@21
  1580
}
dvander@21
  1581
dvander@21
  1582
void
dvander@4
  1583
SemanticAnalysis::visit(FloatLiteral *node)
dvander@4
  1584
{
dvander@40
  1585
    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
dvander@4
  1586
    if (!type)
dvander@4
  1587
        return;
dvander@4
  1588
dvander@4
  1589
    node->setType(type);
dvander@4
  1590
}
dvander@10
  1591
dvander@10
  1592
void
dvander@10
  1593
SemanticAnalysis::visit(BreakStatement *node)
dvander@10
  1594
{
dvander@71
  1595
    if (!loop_) {
dvander@25
  1596
        cc_.reportError(node->pos(), Message_BreakOutsideLoop);
dvander@71
  1597
        return;
dvander@71
  1598
    }
dvander@71
  1599
dvander@71
  1600
    // Note: ignore breaks that occur in unreachable control-flow.
dvander@71
  1601
    if (!control_->status().terminates())
dvander@71
  1602
        loop_->addBreak();
dvander@71
  1603
dvander@71
  1604
    control_->terminate(Returns_Never);
dvander@10
  1605
}
dvander@10
  1606
dvander@10
  1607
void
dvander@10
  1608
SemanticAnalysis::visit(ContinueStatement *node)
dvander@10
  1609
{
dvander@71
  1610
    if (!loop_) {
dvander@25
  1611
        cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
dvander@71
  1612
        return;
dvander@71
  1613
    }
dvander@71
  1614
dvander@71
  1615
    // Note: ignore continues that occur in unreachable control-flow.
dvander@71
  1616
    if (!control_->status().terminates())
dvander@71
  1617
        loop_->addContinue();
dvander@71
  1618
dvander@71
  1619
    control_->terminate(Returns_Never);
dvander@10
  1620
}