jitcraft/Interpreter.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 01:22:28 2012 -0700 (2012-07-03)
changeset 42 97e089e19d7d
parent 39 158f476b92b3
child 43 f6b1a68e7ebb
permissions -rw-r--r--
Removed ZONE() calls from Interpret.
dvander@39
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@39
     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
 */
dvander@0
    19
#include "Interpreter.h"
dvander@0
    20
#include "Modules.h"
dvander@0
    21
#include "Zone.h"
dvander@0
    22
#include "Types.h"
dvander@12
    23
#include "Array.h"
dvander@14
    24
#include "Reference.h"
dvander@28
    25
#include "Heap-inl.h"
dvander@0
    26
dvander@0
    27
using namespace jc;
dvander@0
    28
dvander@0
    29
#define PUSH_I32(top, value)    \
dvander@0
    30
    do {                        \
dvander@0
    31
        top.sp->i32 = value;    \
dvander@0
    32
        top.sp++;               \
dvander@0
    33
   } while (0)
dvander@0
    34
dvander@4
    35
#define PUSH_F(top, value)      \
dvander@4
    36
    do {                        \
dvander@4
    37
        top.sp->f = value;      \
dvander@4
    38
        top.sp++;               \
dvander@4
    39
   } while (0)
dvander@4
    40
dvander@0
    41
static inline int
dvander@0
    42
POP_I32(Top &top)
dvander@0
    43
{
dvander@0
    44
    int value = top.sp[-1].i32;
dvander@0
    45
    top.sp--;
dvander@0
    46
    return value;
dvander@0
    47
}
dvander@0
    48
dvander@4
    49
static inline float
dvander@4
    50
POP_F(Top &top)
dvander@4
    51
{
dvander@4
    52
    float value = top.sp[-1].f;
dvander@4
    53
    top.sp--;
dvander@4
    54
    return value;
dvander@4
    55
}
dvander@4
    56
dvander@0
    57
static inline bool
dvander@14
    58
PushNewRef(Zone *zone, Top &top, void *location, Heap::Tenure tenure)
dvander@14
    59
{
dvander@14
    60
    Reference *ref = Reference::NewStack(zone, location, tenure);
dvander@14
    61
    if (!ref)
dvander@14
    62
        return false;
dvander@14
    63
    top.sp->ref = ref;
dvander@14
    64
    top.sp++;
dvander@14
    65
    return true;
dvander@14
    66
}
dvander@14
    67
dvander@14
    68
static inline bool
dvander@0
    69
CheckDimensionSize(int size, unsigned width)
dvander@0
    70
{
dvander@0
    71
    if (size <= 0) {
dvander@0
    72
        assert(false);
dvander@0
    73
        return false;
dvander@0
    74
    }
dvander@0
    75
    // One  word, because we hide stuff below and need to add that in.
dvander@0
    76
    if (unsigned(size) >= (INT_MAX / width) - sizeof(unsigned)) {
dvander@0
    77
        assert(false);
dvander@0
    78
        return false;
dvander@0
    79
    }
dvander@0
    80
    return true;
dvander@0
    81
}
dvander@0
    82
dvander@12
    83
// Generate an array with completely static sizes.
dvander@12
    84
static Array *
dvander@27
    85
GenerateArray(Zone *zone, Handle<ArrayMap> map)
dvander@0
    86
{
dvander@12
    87
    assert(map->type()->elements() != -1);
dvander@0
    88
dvander@12
    89
    // :TODO: use Local
dvander@12
    90
    Array *array = Array::New(zone, map, map->type()->elements(), Heap::Tenure_Stack);
dvander@12
    91
    if (!array)
dvander@0
    92
        return NULL;
dvander@0
    93
dvander@12
    94
    if (map->type()->levels() == 1)
dvander@12
    95
        return array;
dvander@0
    96
dvander@27
    97
    Local<ArrayMap> contained(zone, map->contained());
dvander@12
    98
    for (unsigned i = 0; i < unsigned(map->type()->elements()); i++) {
dvander@27
    99
        Array *sub = GenerateArray(zone, contained);
dvander@12
   100
        if (!sub)
dvander@0
   101
            return NULL;
dvander@12
   102
        array->writeObject(zone, i, sub);
dvander@0
   103
    }
dvander@0
   104
dvander@12
   105
    return array;
dvander@0
   106
}
dvander@0
   107
dvander@21
   108
static bool
dvander@21
   109
CopyArray(Zone *zone, Array *source, Array *dest)
dvander@21
   110
{
dvander@21
   111
    assert(source->type()->levels() == 1);
dvander@21
   112
    assert(dest->type()->levels() == 1);
dvander@21
   113
    assert(source->type()->contained()->primitive() ==
dvander@21
   114
           dest->type()->contained()->primitive());
dvander@21
   115
    assert(source->nelements() >= dest->nelements());
dvander@21
   116
    assert(dest->elementSize() == source->elementSize());
dvander@21
   117
dvander@21
   118
    memcpy(source->vec(), dest->vec(), dest->nelements() * dest->elementSize());
dvander@21
   119
    return true;
dvander@21
   120
}
dvander@21
   121
dvander@0
   122
bool
dvander@42
   123
jc::Interpret(Zone *zone, Frame *frame, LocalSlot *result)
dvander@0
   124
{
dvander@42
   125
    Top &top = *zone->stack().top();
dvander@0
   126
    LocalSlot *locals = frame->locals();
dvander@0
   127
dvander@0
   128
    for (;;) {
dvander@0
   129
        Opcode op = Opcode(*top.pc);
dvander@0
   130
        switch (op) {
dvander@0
   131
dvander@0
   132
case OP_NOP:
dvander@0
   133
    break;
dvander@0
   134
dvander@0
   135
case OP_INT:
dvander@0
   136
    PUSH_I32(top, READ_INT32(top.pc));
dvander@0
   137
    break;
dvander@0
   138
dvander@4
   139
case OP_FLOAT:
dvander@4
   140
    PUSH_F(top, READ_FLOAT(top.pc));
dvander@4
   141
    break;
dvander@4
   142
dvander@0
   143
case OP_RETURN:
dvander@0
   144
{
dvander@4
   145
    *result = *--top.sp;
dvander@4
   146
    if (!frame->prev())
dvander@0
   147
        return true;
dvander@0
   148
dvander@42
   149
    frame = zone->stack().popFrame(frame);
dvander@0
   150
    locals = frame->locals();
dvander@4
   151
    *top.sp++ = *result;
dvander@0
   152
    top.pc += OpcodeInfo[*top.pc].length;
dvander@0
   153
    continue;
dvander@0
   154
}
dvander@0
   155
dvander@0
   156
#define RELATIONAL_JUMP(op)                 \
dvander@0
   157
    {                                       \
dvander@0
   158
        int right = POP_I32(top);           \
dvander@0
   159
        int left = POP_I32(top);            \
dvander@0
   160
        if (left op right) {                \
dvander@0
   161
            top.pc += READ_INT32(top.pc);   \
dvander@0
   162
            continue;                       \
dvander@0
   163
        }                                   \
dvander@0
   164
    }
dvander@0
   165
dvander@0
   166
case OP_JL:
dvander@0
   167
    RELATIONAL_JUMP(<);
dvander@0
   168
    break;
dvander@0
   169
dvander@0
   170
case OP_JLE:
dvander@0
   171
    RELATIONAL_JUMP(<=);
dvander@0
   172
    break;
dvander@0
   173
dvander@0
   174
case OP_JG:
dvander@0
   175
    RELATIONAL_JUMP(>);
dvander@0
   176
    break;
dvander@0
   177
dvander@0
   178
case OP_JGE:
dvander@0
   179
    RELATIONAL_JUMP(>=);
dvander@0
   180
    break;
dvander@0
   181
dvander@0
   182
case OP_JEQ:
dvander@0
   183
    RELATIONAL_JUMP(==);
dvander@0
   184
    break;
dvander@0
   185
dvander@0
   186
case OP_JNE:
dvander@0
   187
    RELATIONAL_JUMP(!=);
dvander@0
   188
    break;
dvander@0
   189
dvander@0
   190
case OP_JT:
dvander@0
   191
{
dvander@0
   192
    int value = POP_I32(top);
dvander@0
   193
    if (value) {
dvander@0
   194
        top.pc += READ_INT32(top.pc);
dvander@0
   195
        continue;
dvander@0
   196
    }
dvander@0
   197
    break;
dvander@0
   198
}
dvander@0
   199
dvander@0
   200
case OP_JF:
dvander@0
   201
{
dvander@0
   202
    int value = POP_I32(top);
dvander@0
   203
    if (!value) {
dvander@0
   204
        top.pc += READ_INT32(top.pc);
dvander@0
   205
        continue;
dvander@0
   206
    }
dvander@0
   207
    break;
dvander@0
   208
}
dvander@0
   209
dvander@0
   210
case OP_JUMP:
dvander@0
   211
    top.pc += READ_INT32(top.pc);
dvander@0
   212
    continue;
dvander@0
   213
dvander@0
   214
case OP_GETLOCAL:
dvander@0
   215
{
dvander@0
   216
    int slot = READ_INT32(top.pc);
dvander@0
   217
    *top.sp++ = locals[slot];
dvander@0
   218
    break;
dvander@0
   219
}
dvander@0
   220
dvander@0
   221
case OP_SETLOCAL:
dvander@0
   222
{
dvander@0
   223
    int slot = READ_INT32(top.pc);
dvander@0
   224
    locals[slot] = top.sp[-1];
dvander@0
   225
    break;
dvander@0
   226
}
dvander@0
   227
dvander@0
   228
case OP_ADD:
dvander@0
   229
{
dvander@0
   230
    int right = POP_I32(top);
dvander@0
   231
    int left = POP_I32(top);
dvander@0
   232
    int result = left + right;
dvander@0
   233
    PUSH_I32(top, result);
dvander@0
   234
    break;
dvander@0
   235
}
dvander@0
   236
dvander@0
   237
case OP_SUB:
dvander@0
   238
{
dvander@0
   239
    int right = POP_I32(top);
dvander@0
   240
    int left = POP_I32(top);
dvander@0
   241
    int result = left - right;
dvander@0
   242
    PUSH_I32(top, result);
dvander@0
   243
    break;
dvander@0
   244
}
dvander@0
   245
dvander@0
   246
case OP_MUL:
dvander@0
   247
{
dvander@0
   248
    int right = POP_I32(top);
dvander@0
   249
    int left = POP_I32(top);
dvander@0
   250
    int result = left * right;
dvander@22
   251
    PUSH_I32(top, result);
dvander@0
   252
    break;
dvander@0
   253
}
dvander@0
   254
dvander@0
   255
case OP_DIV:
dvander@0
   256
{
dvander@0
   257
    int right = POP_I32(top);
dvander@0
   258
    int left = POP_I32(top);
dvander@0
   259
    if (!right)
dvander@0
   260
        return false;
dvander@0
   261
    int result = left / right;
dvander@0
   262
    PUSH_I32(top, result);
dvander@0
   263
    break;
dvander@0
   264
}
dvander@0
   265
dvander@4
   266
case OP_ADD_F:
dvander@4
   267
{
dvander@4
   268
    float right = POP_F(top);
dvander@4
   269
    float left = POP_F(top);
dvander@4
   270
    float result = left + right;
dvander@4
   271
    PUSH_F(top, result);
dvander@4
   272
    break;
dvander@4
   273
}
dvander@4
   274
dvander@4
   275
case OP_SUB_F:
dvander@4
   276
{
dvander@4
   277
    float right = POP_F(top);
dvander@4
   278
    float left = POP_F(top);
dvander@4
   279
    float result = left - right;
dvander@4
   280
    PUSH_F(top, result);
dvander@4
   281
    break;
dvander@4
   282
}
dvander@4
   283
dvander@4
   284
case OP_MUL_F:
dvander@4
   285
{
dvander@4
   286
    float right = POP_F(top);
dvander@4
   287
    float left = POP_F(top);
dvander@4
   288
    float result = left * right;
dvander@4
   289
    PUSH_F(top, result);
dvander@4
   290
    break;
dvander@4
   291
}
dvander@4
   292
dvander@4
   293
case OP_DIV_F:
dvander@4
   294
{
dvander@4
   295
    float right = POP_F(top);
dvander@4
   296
    float left = POP_F(top);
dvander@4
   297
    if (!right)
dvander@4
   298
        return false;
dvander@4
   299
    float result = left / right;
dvander@4
   300
    PUSH_F(top, result);
dvander@4
   301
    break;
dvander@4
   302
}
dvander@4
   303
dvander@8
   304
case OP_SHL:
dvander@8
   305
{
dvander@8
   306
    int right = POP_I32(top);
dvander@8
   307
    int left = POP_I32(top);
dvander@8
   308
    int result = left << right;
dvander@8
   309
    PUSH_I32(top, result);
dvander@8
   310
    break;
dvander@8
   311
}
dvander@8
   312
dvander@8
   313
case OP_SHR:
dvander@8
   314
{
dvander@8
   315
    int right = POP_I32(top);
dvander@8
   316
    int left = POP_I32(top);
dvander@8
   317
    int result = left >> right;
dvander@8
   318
    PUSH_I32(top, result);
dvander@8
   319
    break;
dvander@8
   320
}
dvander@8
   321
dvander@8
   322
case OP_USHR:
dvander@8
   323
{
dvander@8
   324
    int right = POP_I32(top);
dvander@8
   325
    int left = POP_I32(top);
dvander@8
   326
    int result = unsigned(left) >> unsigned(right);
dvander@8
   327
    PUSH_I32(top, result);
dvander@8
   328
    break;
dvander@8
   329
}
dvander@8
   330
dvander@8
   331
case OP_BITAND:
dvander@8
   332
{
dvander@8
   333
    int right = POP_I32(top);
dvander@8
   334
    int left = POP_I32(top);
dvander@8
   335
    int result = left & right;
dvander@8
   336
    PUSH_I32(top, result);
dvander@8
   337
    break;
dvander@8
   338
}
dvander@8
   339
dvander@8
   340
case OP_BITOR:
dvander@8
   341
{
dvander@8
   342
    int right = POP_I32(top);
dvander@8
   343
    int left = POP_I32(top);
dvander@8
   344
    int result = left | right;
dvander@8
   345
    PUSH_I32(top, result);
dvander@8
   346
    break;
dvander@8
   347
}
dvander@8
   348
dvander@8
   349
case OP_BITXOR:
dvander@8
   350
{
dvander@8
   351
    int right = POP_I32(top);
dvander@8
   352
    int left = POP_I32(top);
dvander@8
   353
    int result = left ^ right;
dvander@8
   354
    PUSH_I32(top, result);
dvander@8
   355
    break;
dvander@8
   356
}
dvander@8
   357
dvander@0
   358
case OP_POP:
dvander@0
   359
    top.sp--;
dvander@0
   360
    break;
dvander@0
   361
dvander@0
   362
case OP_STOP:
dvander@0
   363
    assert(false);
dvander@0
   364
    break;
dvander@0
   365
dvander@0
   366
case OP_CALLGLOBAL:
dvander@0
   367
{
dvander@0
   368
    unsigned argc = READ_UINT32(top.pc);
dvander@0
   369
    unsigned index = READ_UINT32(top.pc + 4);
dvander@26
   370
    Function *newFun = frame->code()->module()->getFunction(index);
dvander@42
   371
    frame = zone->stack().pushFrame(frame, newFun);
dvander@0
   372
    assert(frame);
dvander@26
   373
    assert(newFun->nargs() == argc);
dvander@0
   374
dvander@0
   375
    locals = frame->locals();
dvander@0
   376
    continue;
dvander@0
   377
}
dvander@0
   378
dvander@0
   379
case OP_GETARG:
dvander@0
   380
{
dvander@0
   381
    unsigned slot = READ_UINT32(top.pc);
dvander@0
   382
    *top.sp++ = frame->arg(slot);
dvander@0
   383
    break;
dvander@0
   384
}
dvander@0
   385
dvander@0
   386
case OP_SETARG:
dvander@0
   387
{
dvander@0
   388
    unsigned slot = READ_UINT32(top.pc);
dvander@0
   389
    frame->arg(slot) = *--top.sp;
dvander@0
   390
    break;
dvander@0
   391
}
dvander@0
   392
dvander@19
   393
case OP_BOUNDS:
dvander@0
   394
{
dvander@12
   395
    Array *array = top.sp[-2].array;
dvander@0
   396
    int index = top.sp[-1].i32;
dvander@12
   397
    if (index < 0 || unsigned(index) >= array->nelements())
dvander@0
   398
        return false;
dvander@0
   399
    break;
dvander@0
   400
}
dvander@0
   401
dvander@6
   402
case OP_GETARRAY_I:
dvander@0
   403
{
dvander@12
   404
    Array *array = top.sp[-2].array;
dvander@0
   405
    int index = top.sp[-1].i32;
dvander@0
   406
    top.sp[-2].i32 = array->readInt32(index);
dvander@0
   407
    top.sp--;
dvander@0
   408
    break;
dvander@0
   409
}
dvander@0
   410
dvander@7
   411
case OP_GETARRAY_F:
dvander@7
   412
{
dvander@12
   413
    Array *array = top.sp[-2].array;
dvander@7
   414
    int index = top.sp[-1].i32;
dvander@7
   415
    top.sp[-2].f = array->readFloat(index);
dvander@7
   416
    top.sp--;
dvander@7
   417
    break;
dvander@7
   418
}
dvander@7
   419
dvander@21
   420
case OP_GETARRAY_C:
dvander@21
   421
{
dvander@21
   422
    Array *array = top.sp[-2].array;
dvander@21
   423
    int index = top.sp[-1].i32;
dvander@21
   424
    top.sp[-2].i32 = array->readChar(index);
dvander@21
   425
    top.sp--;
dvander@21
   426
    break;
dvander@21
   427
}
dvander@21
   428
dvander@6
   429
case OP_SETARRAY_I:
dvander@0
   430
{
dvander@12
   431
    Array *array = top.sp[-3].array;
dvander@0
   432
    int index = top.sp[-2].i32;
dvander@0
   433
    array->writeInt32(index, top.sp[-1].i32);
dvander@0
   434
    top.sp[-3] = top.sp[-1];
dvander@0
   435
    top.sp -= 2;
dvander@0
   436
    break;
dvander@0
   437
}
dvander@0
   438
dvander@7
   439
case OP_SETARRAY_F:
dvander@7
   440
{
dvander@12
   441
    Array *array = top.sp[-3].array;
dvander@7
   442
    int index = top.sp[-2].i32;
dvander@7
   443
    array->writeFloat(index, top.sp[-1].f);
dvander@7
   444
    top.sp[-3] = top.sp[-1];
dvander@7
   445
    top.sp -= 2;
dvander@7
   446
    break;
dvander@7
   447
}
dvander@7
   448
dvander@21
   449
case OP_SETARRAY_C:
dvander@21
   450
{
dvander@21
   451
    Array *array = top.sp[-3].array;
dvander@21
   452
    int index = top.sp[-2].i32;
dvander@21
   453
    array->writeChar(index, top.sp[-1].i32);
dvander@21
   454
    top.sp[-3] = top.sp[-1];
dvander@21
   455
    top.sp -= 2;
dvander@21
   456
    break;
dvander@21
   457
}
dvander@21
   458
dvander@19
   459
case OP_GETARRAY_O:
dvander@0
   460
{
dvander@12
   461
    Array *array = top.sp[-2].array;
dvander@0
   462
    int index = top.sp[-1].i32;
dvander@12
   463
    top.sp[-2].array = Array::cast(array->readObject(index));
dvander@0
   464
    top.sp--;
dvander@0
   465
    break;
dvander@0
   466
}
dvander@0
   467
dvander@4
   468
case OP_CVT_I2F:
dvander@4
   469
{
dvander@4
   470
    int ival = POP_I32(top);
dvander@4
   471
    float fval = (float)ival;
dvander@4
   472
    PUSH_F(top, fval);
dvander@4
   473
    break;
dvander@4
   474
}
dvander@4
   475
dvander@19
   476
case OP_NEWARRAY_LIFO:
dvander@12
   477
{
dvander@12
   478
    // :TODO: use Local
dvander@42
   479
    Local<ArrayMap> map(zone, ArrayMap::cast(frame->code()->map(READ_UINT32(top.pc))));
dvander@42
   480
    Array *array = GenerateArray(zone, map);
dvander@12
   481
    if (!array) {
dvander@12
   482
        assert(false);
dvander@12
   483
        return false;
dvander@12
   484
    }
dvander@12
   485
    top.sp->obj = array;
dvander@12
   486
    top.sp++;
dvander@12
   487
    break;
dvander@12
   488
}
dvander@12
   489
dvander@12
   490
case OP_SAVELIFO:
dvander@10
   491
{
dvander@10
   492
    unsigned slot = READ_UINT32(top.pc);
dvander@42
   493
    locals[slot].address = zone->heap().lifoPosition();
dvander@12
   494
    break;
dvander@12
   495
}
dvander@12
   496
dvander@12
   497
case OP_UNWINDLIFO:
dvander@12
   498
{
dvander@12
   499
    unsigned slot = READ_UINT32(top.pc);
dvander@42
   500
    zone->heap().unwindLifo(locals[slot].address);
dvander@10
   501
    break;
dvander@10
   502
}
dvander@10
   503
dvander@14
   504
case OP_VARREF_LIFO:
dvander@14
   505
{
dvander@14
   506
    unsigned slot = READ_UINT32(top.pc);
dvander@42
   507
    if (!PushNewRef(zone, top, &locals[slot], Heap::Tenure_Stack)) {
dvander@14
   508
        assert(false);
dvander@14
   509
        return false;
dvander@14
   510
    }
dvander@14
   511
    break;
dvander@14
   512
}
dvander@14
   513
dvander@14
   514
case OP_ARGREF_LIFO:
dvander@14
   515
{
dvander@14
   516
    unsigned slot = READ_UINT32(top.pc);
dvander@42
   517
    if (!PushNewRef(zone, top, &frame->arg(slot), Heap::Tenure_Stack)) {
dvander@14
   518
        assert(false);
dvander@14
   519
        return false;
dvander@14
   520
    }
dvander@14
   521
    break;
dvander@14
   522
}
dvander@14
   523
dvander@17
   524
case OP_ARRAYREF_LIFO:
dvander@17
   525
{
dvander@42
   526
    Local<Array> array(zone, top.sp[-2].array);
dvander@42
   527
    Local<Reference> ref(zone, Reference::NewArray(zone, array, top.sp[-1].i32, Heap::Tenure_Stack));
dvander@17
   528
    if (!ref) {
dvander@17
   529
        assert(false);
dvander@17
   530
        return false;
dvander@17
   531
    }
dvander@17
   532
    top.sp[-2].ref = ref;
dvander@17
   533
    top.sp--;
dvander@17
   534
    break;
dvander@17
   535
}
dvander@17
   536
dvander@16
   537
case OP_SLOTREF_LIFO:
dvander@16
   538
{
dvander@42
   539
    Reference *ref = Reference::NewStack(zone, top.sp[-1], Heap::Tenure_Stack);
dvander@16
   540
    if (!ref) {
dvander@16
   541
        assert(false);
dvander@16
   542
        return false;
dvander@16
   543
    }
dvander@16
   544
    top.sp[-1].ref = ref;
dvander@16
   545
    break;
dvander@16
   546
}
dvander@16
   547
dvander@14
   548
case OP_GETREF_I:
dvander@14
   549
{
dvander@14
   550
    top.sp[-1].i32 = top.sp[-1].ref->getInt();
dvander@14
   551
    break;
dvander@14
   552
}
dvander@14
   553
dvander@14
   554
case OP_SETREF_I:
dvander@14
   555
{
dvander@14
   556
    top.sp[-2].ref->setInt(top.sp[-1].i32);
dvander@14
   557
    top.sp[-2].i32 = top.sp[-1].i32;
dvander@23
   558
    top.sp--;
dvander@14
   559
    break;
dvander@14
   560
}
dvander@14
   561
dvander@14
   562
case OP_GETREF_F:
dvander@14
   563
{
dvander@14
   564
    top.sp[-1].f = top.sp[-1].ref->getFloat();
dvander@14
   565
    break;
dvander@14
   566
}
dvander@14
   567
dvander@14
   568
case OP_SETREF_F:
dvander@14
   569
{
dvander@14
   570
    top.sp[-2].ref->setFloat(top.sp[-1].f);
dvander@14
   571
    top.sp[-2].f = top.sp[-1].f;
dvander@14
   572
    break;
dvander@14
   573
}
dvander@14
   574
dvander@21
   575
case OP_OBJECT:
dvander@21
   576
{
dvander@21
   577
    top.sp->obj = frame->code()->object(READ_UINT32(top.pc));
dvander@21
   578
    top.sp++;
dvander@21
   579
    break;
dvander@21
   580
}
dvander@21
   581
dvander@21
   582
case OP_ARRAYCOPY:
dvander@21
   583
{
dvander@21
   584
    // Note for this assignment opcode, we return the left-hand side, not the
dvander@21
   585
    // right, since in this case the result of the expression could be different.
dvander@42
   586
    if (!CopyArray(zone, top.sp[-2].array, top.sp[-1].array)) {
dvander@21
   587
        assert(false);
dvander@21
   588
        return false;
dvander@21
   589
    }
dvander@21
   590
    top.sp--;
dvander@21
   591
    break;
dvander@21
   592
}
dvander@21
   593
dvander@22
   594
case OP_DUP:
dvander@22
   595
{
dvander@23
   596
    top.sp++;
dvander@23
   597
    top.sp[-1] = top.sp[-2];
dvander@22
   598
    break;
dvander@22
   599
}
dvander@22
   600
dvander@22
   601
case OP_DUP2:
dvander@22
   602
{
dvander@23
   603
    top.sp += 2;
dvander@23
   604
    top.sp[-2] = top.sp[-4];
dvander@23
   605
    top.sp[-1] = top.sp[-3];
dvander@23
   606
    break;
dvander@23
   607
}
dvander@23
   608
dvander@23
   609
case OP_SWAP:
dvander@23
   610
{
dvander@23
   611
    LocalSlot slot = top.sp[-2];
dvander@23
   612
    top.sp[-2] = top.sp[-1];
dvander@23
   613
    top.sp[-1] = slot;
dvander@23
   614
    break;
dvander@23
   615
}
dvander@23
   616
dvander@23
   617
case OP_ROLL3:
dvander@23
   618
{
dvander@23
   619
    LocalSlot slot = top.sp[-3];
dvander@23
   620
    top.sp[-3] = top.sp[-2];
dvander@23
   621
    top.sp[-2] = top.sp[-1];
dvander@23
   622
    top.sp[-1] = slot;
dvander@23
   623
    break;
dvander@23
   624
}
dvander@23
   625
dvander@23
   626
case OP_PICK2:
dvander@23
   627
{
dvander@23
   628
    top.sp++;
dvander@23
   629
    top.sp[-1] = top.sp[-3];
dvander@23
   630
    break;
dvander@23
   631
}
dvander@23
   632
dvander@23
   633
case OP_PICK3:
dvander@23
   634
{
dvander@23
   635
    top.sp++;
dvander@23
   636
    top.sp[-1] = top.sp[-4];
dvander@22
   637
    break;
dvander@22
   638
}
dvander@22
   639
dvander@0
   640
default:
dvander@0
   641
    assert(false);
dvander@0
   642
    return false;
dvander@0
   643
dvander@0
   644
        }
dvander@0
   645
dvander@0
   646
        top.pc += OpcodeInfo[op].length;
dvander@0
   647
    }
dvander@0
   648
dvander@0
   649
    return true;
dvander@0
   650
}