src/compiler/HIR.cpp
author Asher Baker <asherkin@gmail.com>
Mon Jun 10 01:04:43 2013 +0100 (2013-06-10)
changeset 263 ba85a47ee414
parent 256 3c184218462d
permissions -rw-r--r--
Normalise line endings.
asherkin@263
     1
/* vim: set ts=4 sw=4 tw=99 et:
asherkin@263
     2
 *
asherkin@263
     3
 * Copyright (C) 2012 David Anderson
asherkin@263
     4
 *
asherkin@263
     5
 * This file is part of JITCraft.
asherkin@263
     6
 *
asherkin@263
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
asherkin@263
     8
 * the terms of the GNU General Public License as published by the Free
asherkin@263
     9
 * Software Foundation, either version 3 of the License, or (at your option)
asherkin@263
    10
 * any later version.
asherkin@263
    11
 * 
asherkin@263
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
asherkin@263
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
asherkin@263
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
asherkin@263
    15
 *
asherkin@263
    16
 * You should have received a copy of the GNU General Public License along with
asherkin@263
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
asherkin@263
    18
 */
asherkin@263
    19
#include "AST.h"
asherkin@263
    20
#include "HIR.h"
asherkin@263
    21
#include "BytecodeEmitter.h"
asherkin@263
    22
#include "../Strings.h"
asherkin@263
    23
#include "../Heap-inl.h"
asherkin@263
    24
#include "../Handles-inl.h"
asherkin@263
    25
asherkin@263
    26
using namespace ke;
asherkin@263
    27
asherkin@263
    28
class HIRTranslator : public HIRVisitor
asherkin@263
    29
{
asherkin@263
    30
  public:
asherkin@263
    31
    HIRTranslator(Zone *zone, BytecodeEmitter &emitter)
asherkin@263
    32
      : zone_(zone),
asherkin@263
    33
        emitter_(emitter)
asherkin@263
    34
    {
asherkin@263
    35
    }
asherkin@263
    36
asherkin@263
    37
    void translate(HIR *hir) {
asherkin@263
    38
        hir->accept(this);
asherkin@263
    39
    }
asherkin@263
    40
asherkin@263
    41
    void visitBoolean(HBoolean *hir);
asherkin@263
    42
    void visitFloat(HFloat *hir);
asherkin@263
    43
    void visitInteger(HInteger *hir);
asherkin@263
    44
    void visitArray(HArray *hir);
asherkin@263
    45
    void visitCall(HCall *call);
asherkin@263
    46
    void visitStore(HStore *store);
asherkin@263
    47
    void visitUnary(HUnary *unary);
asherkin@263
    48
    void visitBinary(HBinary *binary);
asherkin@263
    49
    void visitLocal(HLocal *local);
asherkin@263
    50
    void visitGlobal(HGlobal *global);
asherkin@263
    51
    void visitConvert(HConvert *convert);
asherkin@263
    52
    void visitIndex(HIndex *index);
asherkin@263
    53
    void visitField(HField *field);
asherkin@263
    54
    void visitPostIncDec(HPostIncDec *hir);
asherkin@263
    55
    void visitToRef(HToRef *hir);
asherkin@263
    56
    void visitNewDependentArray(HNewDependentArray *hir);
asherkin@263
    57
    void visitImport(HImport *import);
asherkin@263
    58
asherkin@263
    59
  private:
asherkin@263
    60
    Zone *zone_;
asherkin@263
    61
    BytecodeEmitter &emitter_;
asherkin@263
    62
};
asherkin@263
    63
asherkin@263
    64
#define __ emitter_.
asherkin@263
    65
asherkin@263
    66
void
asherkin@263
    67
HIRTranslator::visitBoolean(HBoolean *hir)
asherkin@263
    68
{
asherkin@263
    69
    if (hir->value())
asherkin@263
    70
        __ true_();
asherkin@263
    71
    else
asherkin@263
    72
        __ false_();
asherkin@263
    73
}
asherkin@263
    74
asherkin@263
    75
void
asherkin@263
    76
HIRTranslator::visitFloat(HFloat *hir)
asherkin@263
    77
{
asherkin@263
    78
    __ float_(hir->value());
asherkin@263
    79
}
asherkin@263
    80
asherkin@263
    81
void
asherkin@263
    82
HIRTranslator::visitInteger(HInteger *hir)
asherkin@263
    83
{
asherkin@263
    84
    __ int_(hir->value());
asherkin@263
    85
}
asherkin@263
    86
asherkin@263
    87
void
asherkin@263
    88
HIRTranslator::visitArray(HArray *hir)
asherkin@263
    89
{
asherkin@263
    90
    __ object(hir->array());
asherkin@263
    91
asherkin@263
    92
    if (hir->duplicate())
asherkin@263
    93
        __ duparray(); 
asherkin@263
    94
}
asherkin@263
    95
asherkin@263
    96
void
asherkin@263
    97
HIRTranslator::visitCall(HCall *call)
asherkin@263
    98
{
asherkin@263
    99
    Local<FunctionType> fun(zone_, FunctionType::cast(call->callee()->type()));
asherkin@263
   100
    
asherkin@263
   101
    assert(call->args()->length() == fun->parameters()->length());
asherkin@263
   102
asherkin@263
   103
    __ note_position(call->node()->pos());
asherkin@263
   104
asherkin@263
   105
    unsigned argc = call->args()->length();
asherkin@263
   106
    for (size_t i = call->args()->length() - 1; i < call->args()->length(); i--) {
asherkin@263
   107
        HIR *hir = call->args()->at(i);
asherkin@263
   108
        hir->accept(this);
asherkin@263
   109
    }
asherkin@263
   110
asherkin@263
   111
    call->callee()->accept(this);
asherkin@263
   112
    __ call(fun, argc);
asherkin@263
   113
}
asherkin@263
   114
asherkin@263
   115
void
asherkin@263
   116
HGlobal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
asherkin@263
   117
{
asherkin@263
   118
}
asherkin@263
   119
asherkin@263
   120
void
asherkin@263
   121
HGlobal::hold(BytecodeEmitter &emitter_)
asherkin@263
   122
{
asherkin@263
   123
}
asherkin@263
   124
asherkin@263
   125
void
asherkin@263
   126
HGlobal::swapAndPick(BytecodeEmitter &emitter_)
asherkin@263
   127
{
asherkin@263
   128
    __ dup();
asherkin@263
   129
}
asherkin@263
   130
asherkin@263
   131
void
asherkin@263
   132
HGlobal::store(BytecodeEmitter &emitter_)
asherkin@263
   133
{
asherkin@263
   134
    __ setglobal(sym_);
asherkin@263
   135
}
asherkin@263
   136
asherkin@263
   137
void
asherkin@263
   138
HGlobal::load(BytecodeEmitter &emitter_)
asherkin@263
   139
{
asherkin@263
   140
    __ getglobal(sym_);
asherkin@263
   141
}
asherkin@263
   142
asherkin@263
   143
bool
asherkin@263
   144
HGlobal::ref(BytecodeEmitter &emitter_)
asherkin@263
   145
{
asherkin@263
   146
    return false;
asherkin@263
   147
}
asherkin@263
   148
asherkin@263
   149
static inline Type *
asherkin@263
   150
MaybeDereference(Type *type)
asherkin@263
   151
{
asherkin@263
   152
    if (type->isReference())
asherkin@263
   153
        return ReferenceType::cast(type)->contained();
asherkin@263
   154
    return type;
asherkin@263
   155
}
asherkin@263
   156
asherkin@263
   157
HLocal::HLocal(AstNode *node, VariableSymbol *sym)
asherkin@263
   158
  : HLValue(node, MaybeDereference(sym->type())),
asherkin@263
   159
    sym_(sym)
asherkin@263
   160
{
asherkin@263
   161
}
asherkin@263
   162
asherkin@263
   163
void
asherkin@263
   164
HLocal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
asherkin@263
   165
{
asherkin@263
   166
    if (sym_->type()->isReference()) {
asherkin@263
   167
        if (sym_->storage() == VariableSymbol::Local)
asherkin@263
   168
            __ getlocal(sym_);
asherkin@263
   169
        else if (sym_->storage() == VariableSymbol::Arg)
asherkin@263
   170
            __ getarg(sym_);
asherkin@263
   171
        else
asherkin@263
   172
            assert(false);
asherkin@263
   173
    }
asherkin@263
   174
}
asherkin@263
   175
asherkin@263
   176
void
asherkin@263
   177
HLocal::hold(BytecodeEmitter &emitter_)
asherkin@263
   178
{
asherkin@263
   179
    if (sym_->type()->isReference())
asherkin@263
   180
        __ dup();
asherkin@263
   181
}
asherkin@263
   182
asherkin@263
   183
void
asherkin@263
   184
HLocal::swapAndPick(BytecodeEmitter &emitter_)
asherkin@263
   185
{
asherkin@263
   186
    if (sym_->type()->isReference()) {
asherkin@263
   187
        __ swap();
asherkin@263
   188
        __ pick2();
asherkin@263
   189
    } else {
asherkin@263
   190
        __ dup();
asherkin@263
   191
    }
asherkin@263
   192
}
asherkin@263
   193
asherkin@263
   194
void
asherkin@263
   195
HLocal::store(BytecodeEmitter &emitter_)
asherkin@263
   196
{
asherkin@263
   197
    if (sym_->type()->isReference()) {
asherkin@263
   198
        __ setref(ReferenceType::cast(sym_->type())->contained());
asherkin@263
   199
    } else {
asherkin@263
   200
        if (sym_->storage() == VariableSymbol::Local)
asherkin@263
   201
            __ setlocal(sym_);
asherkin@263
   202
        else if (sym_->storage() == VariableSymbol::Arg)
asherkin@263
   203
            __ setarg(sym_);
asherkin@263
   204
        else
asherkin@263
   205
            assert(false);
asherkin@263
   206
    }
asherkin@263
   207
}
asherkin@263
   208
asherkin@263
   209
void
asherkin@263
   210
HLocal::load(BytecodeEmitter &emitter_)
asherkin@263
   211
{
asherkin@263
   212
    if (sym_->type()->isReference())
asherkin@263
   213
        __ getref(ReferenceType::cast(sym_->type())->contained());
asherkin@263
   214
    else if (sym_->storage() == VariableSymbol::Local)
asherkin@263
   215
        __ getlocal(sym_);
asherkin@263
   216
    else if (sym_->storage() == VariableSymbol::Arg)
asherkin@263
   217
        __ getarg(sym_);
asherkin@263
   218
    else
asherkin@263
   219
        assert(false);
asherkin@263
   220
}
asherkin@263
   221
asherkin@263
   222
bool
asherkin@263
   223
HLocal::ref(BytecodeEmitter &emitter_)
asherkin@263
   224
{
asherkin@263
   225
    if (sym_->storage() == VariableSymbol::Heap) {
asherkin@263
   226
        // Closing over a reference should never pass SemA.
asherkin@263
   227
        assert(!sym_->type()->isReference());
asherkin@263
   228
asherkin@263
   229
        // We don't support direct references to heap-allocated locals. This
asherkin@263
   230
        // should probably be banned in SemA? But for now, just assert. :TODO:
asherkin@263
   231
        assert(false);
asherkin@263
   232
        return false;
asherkin@263
   233
    }
asherkin@263
   234
        
asherkin@263
   235
    if (sym_->type()->isReference()) {
asherkin@263
   236
        if (sym_->storage() == VariableSymbol::Local)
asherkin@263
   237
            __ getlocal(sym_);
asherkin@263
   238
        else if (sym_->storage() == VariableSymbol::Arg)
asherkin@263
   239
            __ getarg(sym_);
asherkin@263
   240
        else
asherkin@263
   241
            assert(false);
asherkin@263
   242
    } else {
asherkin@263
   243
        __ newref(sym_);
asherkin@263
   244
    }
asherkin@263
   245
asherkin@263
   246
    return true;
asherkin@263
   247
}
asherkin@263
   248
asherkin@263
   249
void
asherkin@263
   250
HIndex::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
asherkin@263
   251
{
asherkin@263
   252
    __ note_position(node()->pos());
asherkin@263
   253
    left_->accept(visitor);
asherkin@263
   254
    right_->accept(visitor);
asherkin@263
   255
}
asherkin@263
   256
asherkin@263
   257
void
asherkin@263
   258
HIndex::hold(BytecodeEmitter &emitter_)
asherkin@263
   259
{
asherkin@263
   260
    __ dup2();
asherkin@263
   261
}
asherkin@263
   262
asherkin@263
   263
void
asherkin@263
   264
HIndex::swapAndPick(BytecodeEmitter &emitter_)
asherkin@263
   265
{
asherkin@263
   266
    // BASE INDEX VALUE
asherkin@263
   267
    __ roll3();         // INDEX VALUE BASE
asherkin@263
   268
    __ roll3();         // VALUE BASE INDEX
asherkin@263
   269
    __ pick3();         // VALUE BASE INDEX VALUE
asherkin@263
   270
}
asherkin@263
   271
asherkin@263
   272
void
asherkin@263
   273
HIndex::store(BytecodeEmitter &emitter_)
asherkin@263
   274
{
asherkin@263
   275
    __ setelem(type());
asherkin@263
   276
}
asherkin@263
   277
asherkin@263
   278
void
asherkin@263
   279
HIndex::load(BytecodeEmitter &emitter_)
asherkin@263
   280
{
asherkin@263
   281
    __ getelem(type());
asherkin@263
   282
}
asherkin@263
   283
asherkin@263
   284
bool
asherkin@263
   285
HIndex::ref(BytecodeEmitter &emitter_)
asherkin@263
   286
{
asherkin@263
   287
    return false;
asherkin@263
   288
}
asherkin@263
   289
asherkin@263
   290
void
asherkin@263
   291
HField::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
asherkin@263
   292
{
asherkin@263
   293
    __ note_position(node()->pos());
asherkin@263
   294
    base_->accept(visitor);
asherkin@263
   295
}
asherkin@263
   296
asherkin@263
   297
void
asherkin@263
   298
HField::hold(BytecodeEmitter &emitter_)
asherkin@263
   299
{
asherkin@263
   300
    __ dup();
asherkin@263
   301
}
asherkin@263
   302
asherkin@263
   303
void
asherkin@263
   304
HField::swapAndPick(BytecodeEmitter &emitter_)
asherkin@263
   305
{
asherkin@263
   306
    // BASE VALUE
asherkin@263
   307
    __ swap();      // VALUE BASE
asherkin@263
   308
    __ pick2();     // VALUE BASE VALUE
asherkin@263
   309
}
asherkin@263
   310
asherkin@263
   311
void
asherkin@263
   312
HField::store(BytecodeEmitter &emitter_)
asherkin@263
   313
{
asherkin@263
   314
    __ setfield(index_, type());
asherkin@263
   315
}
asherkin@263
   316
asherkin@263
   317
void
asherkin@263
   318
HField::load(BytecodeEmitter &emitter_)
asherkin@263
   319
{
asherkin@263
   320
    __ getfield(index_, type());
asherkin@263
   321
}
asherkin@263
   322
asherkin@263
   323
bool
asherkin@263
   324
HField::ref(BytecodeEmitter &emitter_)
asherkin@263
   325
{
asherkin@263
   326
    return false;
asherkin@263
   327
}
asherkin@263
   328
asherkin@263
   329
void
asherkin@263
   330
HIRTranslator::visitLocal(HLocal *local)
asherkin@263
   331
{
asherkin@263
   332
    local->bind(this, emitter_);
asherkin@263
   333
    local->load(emitter_);
asherkin@263
   334
}
asherkin@263
   335
asherkin@263
   336
void
asherkin@263
   337
HIRTranslator::visitIndex(HIndex *index)
asherkin@263
   338
{
asherkin@263
   339
    index->bind(this, emitter_);
asherkin@263
   340
    index->load(emitter_);
asherkin@263
   341
}
asherkin@263
   342
asherkin@263
   343
void
asherkin@263
   344
HIRTranslator::visitField(HField *field)
asherkin@263
   345
{
asherkin@263
   346
    field->bind(this, emitter_);
asherkin@263
   347
    field->load(emitter_);
asherkin@263
   348
}
asherkin@263
   349
asherkin@263
   350
void
asherkin@263
   351
HIRTranslator::visitGlobal(HGlobal *global)
asherkin@263
   352
{
asherkin@263
   353
    global->bind(this, emitter_);
asherkin@263
   354
    global->load(emitter_);
asherkin@263
   355
}
asherkin@263
   356
asherkin@263
   357
static inline Opcode
asherkin@263
   358
TokenToOpcode(TokenKind kind)
asherkin@263
   359
{
asherkin@263
   360
    switch (kind) {
asherkin@263
   361
      case TOK_PLUS:
asherkin@263
   362
      case TOK_ASSIGN_ADD:
asherkin@263
   363
      case TOK_INCREMENT:
asherkin@263
   364
        return OP_ADD;
asherkin@263
   365
      case TOK_MINUS:
asherkin@263
   366
      case TOK_ASSIGN_SUB:
asherkin@263
   367
      case TOK_DECREMENT:
asherkin@263
   368
        return OP_SUB;
asherkin@263
   369
      case TOK_STAR:
asherkin@263
   370
      case TOK_ASSIGN_MUL:
asherkin@263
   371
        return OP_MUL;
asherkin@263
   372
      case TOK_SLASH:
asherkin@263
   373
      case TOK_ASSIGN_DIV:
asherkin@263
   374
        return OP_DIV;
asherkin@263
   375
      case TOK_PERCENT:
asherkin@263
   376
      case TOK_ASSIGN_MOD:
asherkin@263
   377
        return OP_MOD;
asherkin@263
   378
      case TOK_SHR:
asherkin@263
   379
      case TOK_ASSIGN_SHR:
asherkin@263
   380
        return OP_SHR;
asherkin@263
   381
      case TOK_USHR:
asherkin@263
   382
      case TOK_ASSIGN_USHR:
asherkin@263
   383
        return OP_USHR;
asherkin@263
   384
      case TOK_SHL:
asherkin@263
   385
      case TOK_ASSIGN_SHL:
asherkin@263
   386
        return OP_SHL;
asherkin@263
   387
      case TOK_BITAND:
asherkin@263
   388
      case TOK_ASSIGN_BITAND:
asherkin@263
   389
        return OP_BITAND;
asherkin@263
   390
      case TOK_BITOR:
asherkin@263
   391
      case TOK_ASSIGN_BITOR:
asherkin@263
   392
        return OP_BITOR;
asherkin@263
   393
      case TOK_GT:
asherkin@263
   394
          return OP_GT;
asherkin@263
   395
      case TOK_GE:
asherkin@263
   396
          return OP_GE;
asherkin@263
   397
      case TOK_LT:
asherkin@263
   398
          return OP_LT;
asherkin@263
   399
      case TOK_LE:
asherkin@263
   400
          return OP_LE;
asherkin@263
   401
      case TOK_EQUALS:
asherkin@263
   402
          return OP_EQ;
asherkin@263
   403
      case TOK_NOTEQUALS:
asherkin@263
   404
          return OP_NE;
asherkin@263
   405
      default:
asherkin@263
   406
        assert(kind == TOK_BITXOR);
asherkin@263
   407
        return OP_BITXOR;
asherkin@263
   408
    }
asherkin@263
   409
}
asherkin@263
   410
asherkin@263
   411
void
asherkin@263
   412
HIRTranslator::visitStore(HStore *store)
asherkin@263
   413
{
asherkin@263
   414
    store->lval()->bind(this, emitter_);
asherkin@263
   415
asherkin@263
   416
    if (store->kind() == TOK_ASSIGN) {
asherkin@263
   417
        // Fixed-length arrays and structs have copy semantics.
asherkin@263
   418
        Local<Type> type(zone_, store->lval()->type());
asherkin@263
   419
        if (type->isArray() && ArrayType::cast(type)->isFixedLength()) {
asherkin@263
   420
            store->lval()->load(emitter_);
asherkin@263
   421
            store->rval()->accept(this);
asherkin@263
   422
            __ copyarray();
asherkin@263
   423
        } else if (type->isStruct()) {
asherkin@263
   424
            store->lval()->load(emitter_);
asherkin@263
   425
            store->rval()->accept(this);
asherkin@263
   426
            __ copystruct();
asherkin@263
   427
        } else {
asherkin@263
   428
            store->rval()->accept(this);
asherkin@263
   429
            store->lval()->store(emitter_);
asherkin@263
   430
        }
asherkin@263
   431
    } else {
asherkin@263
   432
        // Advanced case: dup the ref, load, op, store.
asherkin@263
   433
        store->lval()->hold(emitter_);
asherkin@263
   434
        store->lval()->load(emitter_);
asherkin@263
   435
        store->rval()->accept(this);
asherkin@263
   436
        __ binary(TokenToOpcode(store->kind()));
asherkin@263
   437
        store->lval()->store(emitter_);
asherkin@263
   438
    }
asherkin@263
   439
}
asherkin@263
   440
asherkin@263
   441
void
asherkin@263
   442
HIRTranslator::visitPostIncDec(HPostIncDec *hir)
asherkin@263
   443
{
asherkin@263
   444
    hir->lval()->bind(this, emitter_);
asherkin@263
   445
    hir->lval()->hold(emitter_);
asherkin@263
   446
    hir->lval()->load(emitter_);
asherkin@263
   447
    hir->lval()->swapAndPick(emitter_);
asherkin@263
   448
    hir->rval()->accept(this);
asherkin@263
   449
    __ binary(TokenToOpcode(hir->kind()));
asherkin@263
   450
    hir->lval()->store(emitter_);
asherkin@263
   451
    __ pop();
asherkin@263
   452
}
asherkin@263
   453
asherkin@263
   454
void
asherkin@263
   455
HIRTranslator::visitBinary(HBinary *binary)
asherkin@263
   456
{
asherkin@263
   457
    binary->left()->accept(this);
asherkin@263
   458
    binary->right()->accept(this);
asherkin@263
   459
asherkin@263
   460
    // We define three sets of math operators:
asherkin@263
   461
    //
asherkin@263
   462
    //  (1) ADD, SUB, MUL, DIV, MOD, which take two equal types and produce
asherkin@263
   463
    //      the same type.
asherkin@263
   464
    //  (2) LT, LE, GE, GT, EQ, NE, which take two equal types and produce
asherkin@263
   465
    //      a boolean.
asherkin@263
   466
    //  (3) SHL, SR, USHR, BITAND, BITOR, BITXOR, BITNOT, which take two
asherkin@263
   467
    //      equal integer types and return that integer type.
asherkin@263
   468
    //
asherkin@263
   469
    Opcode op = TokenToOpcode(binary->token());
asherkin@263
   470
asherkin@263
   471
    if (op == OP_DIV)
asherkin@263
   472
        __ note_position(binary->node()->pos());
asherkin@263
   473
asherkin@263
   474
    if (op >= OP_ADD && op <= OP_NE) {
asherkin@263
   475
        if (binary->type()->isFloat())
asherkin@263
   476
            op = Opcode(int(op) + int(OP_ADD_F - OP_ADD));
asherkin@263
   477
    } else {
asherkin@263
   478
        assert(binary->type()->isInt32());
asherkin@263
   479
    }
asherkin@263
   480
asherkin@263
   481
    __ binary(op);
asherkin@263
   482
}
asherkin@263
   483
asherkin@263
   484
void
asherkin@263
   485
HIRTranslator::visitUnary(HUnary *unary)
asherkin@263
   486
{
asherkin@263
   487
    unary->in()->accept(this);
asherkin@263
   488
asherkin@263
   489
    switch (unary->token()) {
asherkin@263
   490
      case TOK_TILDE:
asherkin@263
   491
        __ bitnot();
asherkin@263
   492
        break;
asherkin@263
   493
asherkin@263
   494
      case TOK_MINUS:
asherkin@263
   495
        if (unary->type()->isFloat())
asherkin@263
   496
            __ neg_f();
asherkin@263
   497
        else
asherkin@263
   498
            __ neg();
asherkin@263
   499
        break;
asherkin@263
   500
asherkin@263
   501
      default:
asherkin@263
   502
        assert(unary->token() == TOK_LABEL);
asherkin@263
   503
        __ bitcast(unary->type());
asherkin@263
   504
        break;
asherkin@263
   505
    }
asherkin@263
   506
}
asherkin@263
   507
asherkin@263
   508
void
asherkin@263
   509
HIRTranslator::visitConvert(HConvert *convert)
asherkin@263
   510
{
asherkin@263
   511
    convert->in()->accept(this);
asherkin@263
   512
    __ unary(convert->opcode());
asherkin@263
   513
}
asherkin@263
   514
asherkin@263
   515
void
asherkin@263
   516
HIRTranslator::visitToRef(HToRef *hir)
asherkin@263
   517
{
asherkin@263
   518
    HIR *in = hir->in();
asherkin@263
   519
asherkin@263
   520
    // See if we can bind a direct reference.
asherkin@263
   521
    if (in->isLValue() && in->toLValue()->ref(emitter_))
asherkin@263
   522
        return;
asherkin@263
   523
asherkin@263
   524
    // No, we can't. So instead we create an on-stack reference.
asherkin@263
   525
    in->accept(this);
asherkin@263
   526
    __ slotref_lifo();
asherkin@263
   527
}
asherkin@263
   528
asherkin@263
   529
void
asherkin@263
   530
HIRTranslator::visitNewDependentArray(HNewDependentArray *hir)
asherkin@263
   531
{
asherkin@263
   532
    hir->base()->accept(this);
asherkin@263
   533
    hir->index()->accept(this);
asherkin@263
   534
asherkin@263
   535
    Local<ArrayType> type(zone_, ArrayType::cast(hir->type()));
asherkin@263
   536
asherkin@263
   537
    // The dependent map is used for the opcode, but is not attached.
asherkin@263
   538
    Local<ArrayMap> map(zone_, ArrayMap::NewDependent(zone_, type));
asherkin@263
   539
    if (!map)
asherkin@263
   540
        return;
asherkin@263
   541
asherkin@263
   542
    __ deparray(map);
asherkin@263
   543
}
asherkin@263
   544
asherkin@263
   545
void
asherkin@263
   546
HIRTranslator::visitImport(HImport *import)
asherkin@263
   547
{
asherkin@263
   548
    __ import(import->index());
asherkin@263
   549
}
asherkin@263
   550
asherkin@263
   551
void
asherkin@263
   552
ke::EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir)
asherkin@263
   553
{
asherkin@263
   554
    HIRTranslator translator(zone, emitter);
asherkin@263
   555
    translator.translate(hir);
asherkin@263
   556
}