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