/*
 * Copyright 2011 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <math.h>
#include <assert.h>

#include "jscript.h"
#include "engine.h"
#include "parser.h"

#include "wine/rbtree.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(jscript);
WINE_DECLARE_DEBUG_CHANNEL(jscript_disas);

typedef struct _statement_ctx_t {
    unsigned stack_use;
    BOOL using_scope;
    BOOL using_except;

    unsigned break_label;
    unsigned continue_label;

    const labelled_statement_t *labelled_stat;

    struct _statement_ctx_t *next;
} statement_ctx_t;

typedef struct {
    struct wine_rb_entry entry;
    BSTR name;
    int ref;
} function_local_t;

typedef struct {
    parser_ctx_t *parser;
    bytecode_t *code;

    BOOL from_eval;

    unsigned code_off;
    unsigned code_size;

    unsigned *labels;
    unsigned labels_size;
    unsigned labels_cnt;

    struct wine_rb_tree locals;
    unsigned locals_cnt;

    statement_ctx_t *stat_ctx;
    function_code_t *func;

    function_expression_t *func_head;
    function_expression_t *func_tail;

    heap_pool_t heap;
} compiler_ctx_t;

static const struct {
    const char *op_str;
    instr_arg_type_t arg1_type;
    instr_arg_type_t arg2_type;
} instr_info[] = {
#define X(n,a,b,c) {#n,b,c},
OP_LIST
#undef X
};

static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
{
    switch(type) {
    case ARG_STR:
        TRACE_(jscript_disas)("\t%s", debugstr_jsstr(arg->str));
        break;
    case ARG_BSTR:
        TRACE_(jscript_disas)("\t%s", debugstr_wn(arg->bstr, SysStringLen(arg->bstr)));
        break;
    case ARG_INT:
        TRACE_(jscript_disas)("\t%d", arg->uint);
        break;
    case ARG_UINT:
    case ARG_ADDR:
        TRACE_(jscript_disas)("\t%u", arg->uint);
        break;
    case ARG_FUNC:
    case ARG_NONE:
        break;
    DEFAULT_UNREACHABLE;
    }
}

static void dump_code(compiler_ctx_t *ctx, unsigned off)
{
    instr_t *instr;

    for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
        TRACE_(jscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
        if(instr_info[instr->op].arg1_type == ARG_DBL) {
            TRACE_(jscript_disas)("\t%lf", instr->u.dbl);
        }else {
            dump_instr_arg(instr_info[instr->op].arg1_type, instr->u.arg);
            dump_instr_arg(instr_info[instr->op].arg2_type, instr->u.arg+1);
        }
        TRACE_(jscript_disas)("\n");
    }
}

static HRESULT compile_expression(compiler_ctx_t*,expression_t*,BOOL);
static HRESULT compile_statement(compiler_ctx_t*,statement_ctx_t*,statement_t*);

static inline void *compiler_alloc(bytecode_t *code, size_t size)
{
    return heap_pool_alloc(&code->heap, size);
}

static jsstr_t *compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len)
{
    jsstr_t *new_str;

    if(!ctx->code->str_pool_size) {
        ctx->code->str_pool = heap_alloc(8 * sizeof(jsstr_t*));
        if(!ctx->code->str_pool)
            return NULL;
        ctx->code->str_pool_size = 8;
    }else if(ctx->code->str_pool_size == ctx->code->str_cnt) {
        jsstr_t **new_pool;

        new_pool = heap_realloc(ctx->code->str_pool, ctx->code->str_pool_size*2*sizeof(jsstr_t*));
        if(!new_pool)
            return NULL;

        ctx->code->str_pool = new_pool;
        ctx->code->str_pool_size *= 2;
    }

    new_str = jsstr_alloc_len(str, len);
    if(!new_str)
        return NULL;

    ctx->code->str_pool[ctx->code->str_cnt++] = new_str;
    return new_str;
}

static jsstr_t *compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
{
    return compiler_alloc_string_len(ctx, str, strlenW(str));
}

static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
{
    if(!ctx->code->bstr_pool_size) {
        ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
        if(!ctx->code->bstr_pool)
            return FALSE;
        ctx->code->bstr_pool_size = 8;
    }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
        BSTR *new_pool;

        new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
        if(!new_pool)
            return FALSE;

        ctx->code->bstr_pool = new_pool;
        ctx->code->bstr_pool_size *= 2;
    }

    return TRUE;
}

static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
{
    if(!ensure_bstr_slot(ctx))
        return NULL;

    ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
    if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
        return NULL;

    return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
}

static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_t len)
{
    if(!ensure_bstr_slot(ctx))
        return NULL;

    ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocStringLen(str, len);
    if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
        return NULL;

    return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
}

static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
{
    assert(ctx->code_size >= ctx->code_off);

    if(ctx->code_size == ctx->code_off) {
        instr_t *new_instrs;

        new_instrs = heap_realloc(ctx->code->instrs, ctx->code_size*2*sizeof(instr_t));
        if(!new_instrs)
            return 0;

        ctx->code->instrs = new_instrs;
        ctx->code_size *= 2;
    }

    ctx->code->instrs[ctx->code_off].op = op;
    return ctx->code_off++;
}

static inline instr_t *instr_ptr(compiler_ctx_t *ctx, unsigned off)
{
    assert(off < ctx->code_off);
    return ctx->code->instrs + off;
}

static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
{
    unsigned instr;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.arg->lng = arg;
    return S_OK;
}

static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
{
    unsigned instr;
    jsstr_t *str;

    str = compiler_alloc_string(ctx, arg);
    if(!str)
        return E_OUTOFMEMORY;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.arg->str = str;
    return S_OK;
}

static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
{
    unsigned instr;
    WCHAR *str;

    str = compiler_alloc_bstr(ctx, arg);
    if(!str)
        return E_OUTOFMEMORY;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.arg->bstr = str;
    return S_OK;
}

static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
{
    unsigned instr;
    WCHAR *str;

    str = compiler_alloc_bstr(ctx, arg1);
    if(!str)
        return E_OUTOFMEMORY;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.arg[0].bstr = str;
    instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
    return S_OK;
}

static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
{
    unsigned instr;
    jsstr_t *str;

    str = compiler_alloc_string(ctx, arg2);
    if(!str)
        return E_OUTOFMEMORY;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.arg[0].uint = arg1;
    instr_ptr(ctx, instr)->u.arg[1].str = str;
    return S_OK;
}

static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
{
    unsigned instr;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.dbl = arg;
    return S_OK;
}

static inline void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
{
    instr_ptr(ctx, instr)->u.arg->uint = arg;
}

static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
{
    unsigned instr;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    set_arg_uint(ctx, instr, arg);
    return S_OK;
}

static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
{
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression1, TRUE);
    if(FAILED(hres))
        return hres;

    hres = compile_expression(ctx, expr->expression2, TRUE);
    if(FAILED(hres))
        return hres;

    return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
}

static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
{
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression, TRUE);
    if(FAILED(hres))
        return hres;

    return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
}

/* ECMA-262 3rd Edition    11.2.1 */
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
{
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression, TRUE);
    if(FAILED(hres))
        return hres;

    return push_instr_bstr(ctx, OP_member, expr->identifier);
}

#define LABEL_FLAG 0x80000000

static unsigned alloc_label(compiler_ctx_t *ctx)
{
    if(!ctx->labels_size) {
        ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
        if(!ctx->labels)
            return 0;
        ctx->labels_size = 8;
    }else if(ctx->labels_size == ctx->labels_cnt) {
        unsigned *new_labels;

        new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
        if(!new_labels)
            return 0;

        ctx->labels = new_labels;
        ctx->labels_size *= 2;
    }

    return ctx->labels_cnt++ | LABEL_FLAG;
}

static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
{
    assert(label & LABEL_FLAG);
    ctx->labels[label & ~LABEL_FLAG] = ctx->code_off;
}

static inline BOOL is_memberid_expr(expression_type_t type)
{
    return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY;
}

static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
{
    statement_ctx_t *iter;
    local_ref_t *ref;

    for(iter = ctx->stat_ctx; iter; iter = iter->next) {
        if(iter->using_scope)
            return FALSE;
    }

    ref = lookup_local(ctx->func, identifier);
    if(!ref)
        return FALSE;

    *ret_ref = ref->ref;
    return TRUE;
}

static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
{
    int local_ref;
    if(bind_local(ctx, identifier, &local_ref))
        return push_instr_int(ctx, OP_local_ref, local_ref);
    return push_instr_bstr_uint(ctx, OP_identid, identifier, flags);
}

static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier)
{
    int local_ref;
    if(bind_local(ctx, identifier, &local_ref))
        return push_instr_int(ctx, OP_local, local_ref);
    return push_instr_bstr(ctx, OP_ident, identifier);
}

static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
{
    HRESULT hres = S_OK;

    switch(expr->type) {
    case EXPR_IDENT: {
        identifier_expression_t *ident_expr = (identifier_expression_t*)expr;

        hres = emit_identifier_ref(ctx, ident_expr->identifier, flags);
        break;
    }
    case EXPR_ARRAY: {
        binary_expression_t *array_expr = (binary_expression_t*)expr;

        hres = compile_expression(ctx, array_expr->expression1, TRUE);
        if(FAILED(hres))
            return hres;

        hres = compile_expression(ctx, array_expr->expression2, TRUE);
        if(FAILED(hres))
            return hres;

        hres = push_instr_uint(ctx, OP_memberid, flags);
        break;
    }
    case EXPR_MEMBER: {
        member_expression_t *member_expr = (member_expression_t*)expr;

        hres = compile_expression(ctx, member_expr->expression, TRUE);
        if(FAILED(hres))
            return hres;

        /* FIXME: Potential optimization */
        hres = push_instr_str(ctx, OP_str, member_expr->identifier);
        if(FAILED(hres))
            return hres;

        hres = push_instr_uint(ctx, OP_memberid, flags);
        break;
    }
    DEFAULT_UNREACHABLE;
    }

    return hres;
}

static HRESULT compile_increment_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n)
{
    HRESULT hres;

    if(!is_memberid_expr(expr->expression->type)) {
        hres = compile_expression(ctx, expr->expression, TRUE);
        if(FAILED(hres))
            return hres;

        return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
    }

    hres = compile_memberid_expression(ctx, expr->expression, fdexNameEnsure);
    if(FAILED(hres))
        return hres;

    return push_instr_int(ctx, op, n);
}

/* ECMA-262 3rd Edition    11.14 */
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret)
{
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression1, FALSE);
    if(FAILED(hres))
        return hres;

    return compile_expression(ctx, expr->expression2, emit_ret);
}

/* ECMA-262 3rd Edition    11.11 */
static HRESULT compile_logical_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
{
    unsigned instr;
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression1, TRUE);
    if(FAILED(hres))
        return hres;

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    hres = compile_expression(ctx, expr->expression2, TRUE);
    if(FAILED(hres))
        return hres;

    set_arg_uint(ctx, instr, ctx->code_off);
    return S_OK;
}

/* ECMA-262 3rd Edition    11.12 */
static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr)
{
    unsigned jmp_false, jmp_end;
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression, TRUE);
    if(FAILED(hres))
        return hres;

    jmp_false = push_instr(ctx, OP_cnd_z);
    if(!jmp_false)
        return E_OUTOFMEMORY;

    hres = compile_expression(ctx, expr->true_expression, TRUE);
    if(FAILED(hres))
        return hres;

    jmp_end = push_instr(ctx, OP_jmp);
    if(!jmp_end)
        return E_OUTOFMEMORY;

    set_arg_uint(ctx, jmp_false, ctx->code_off);
    hres = push_instr_uint(ctx, OP_pop, 1);
    if(FAILED(hres))
        return hres;

    hres = compile_expression(ctx, expr->false_expression, TRUE);
    if(FAILED(hres))
        return hres;

    set_arg_uint(ctx, jmp_end, ctx->code_off);
    return S_OK;
}

static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
{
    unsigned arg_cnt = 0;
    argument_t *arg;
    HRESULT hres;

    hres = compile_expression(ctx, expr->expression, TRUE);
    if(FAILED(hres))
        return hres;

    for(arg = expr->argument_list; arg; arg = arg->next) {
        hres = compile_expression(ctx, arg->expr, TRUE);
        if(FAILED(hres))
            return hres;
        arg_cnt++;
    }

    hres = push_instr_uint(ctx, OP_new, arg_cnt);
    if(FAILED(hres))
        return hres;

    hres = push_instr_uint(ctx, OP_pop, arg_cnt+1);
    if(FAILED(hres))
        return hres;

    return push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY;
}

static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
{
    unsigned arg_cnt = 0, extra_args;
    argument_t *arg;
    unsigned instr;
    jsop_t op;
    HRESULT hres;

    if(is_memberid_expr(expr->expression->type)) {
        op = OP_call_member;
        extra_args = 2;
        hres = compile_memberid_expression(ctx, expr->expression, 0);
    }else {
        op = OP_call;
        extra_args = 1;
        hres = compile_expression(ctx, expr->expression, TRUE);
    }

    if(FAILED(hres))
        return hres;

    for(arg = expr->argument_list; arg; arg = arg->next) {
        hres = compile_expression(ctx, arg->expr, TRUE);
        if(FAILED(hres))
            return hres;
        arg_cnt++;
    }

    instr = push_instr(ctx, op);
    if(!instr)
        return E_OUTOFMEMORY;

    instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt;
    instr_ptr(ctx, instr)->u.arg[1].lng = emit_ret;

    hres = push_instr_uint(ctx, OP_pop, arg_cnt + extra_args);
    if(FAILED(hres))
        return hres;

    return !emit_ret || push_instr(ctx, OP_push_ret) ? S_OK : E_OUTOFMEMORY;
}

static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
{
    HRESULT hres;

    switch(expr->expression->type) {
    case EXPR_ARRAY: {
        binary_expression_t *array_expr = (binary_expression_t*)expr->expression;

        hres = compile_expression(ctx, array_expr->expression1, TRUE);
        if(FAILED(hres))
            return hres;

        hres = compile_expression(ctx, array_expr->expression2, TRUE);
        if(FAILED(hres))
            return hres;

        if(!push_instr(ctx, OP_delete))
            return E_OUTOFMEMORY;
        break;
    }
    case EXPR_MEMBER: {
        member_expression_t *member_expr = (member_expression_t*)expr->expression;

        hres = compile_expression(ctx, member_expr->expression, TRUE);
        if(FAILED(hres))
            return hres;

        /* FIXME: Potential optimization */
        hres = push_instr_str(ctx, OP_str, member_expr->identifier);
        if(FAILED(hres))
            return hres;

        if(!push_instr(ctx, OP_delete))
            return E_OUTOFMEMORY;
        break;
    }
    case EXPR_IDENT:
        return push_instr_bstr(ctx, OP_delete_ident, ((identifier_expression_t*)expr->expression)->identifier);
    default: {
        const WCHAR fixmeW[] = {'F','I','X','M','E',0};

        WARN("invalid delete, unimplemented exception message\n");

        hres = compile_expression(ctx, expr->expression, TRUE);
        if(FAILED(hres))
            return hres;

        return push_instr_uint_str(ctx, OP_throw_type, JS_E_INVALID_DELETE, fixmeW);
    }
    }

    return S_OK;
}

static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
{
    BOOL use_throw_path = FALSE;
    unsigned arg_cnt = 0;
    HRESULT hres;

    if(expr->expression1->type == EXPR_CALL) {
        call_expression_t *call_expr = (call_expression_t*)expr->expression1;
        argument_t *arg;

        if(op != OP_LAST) {
            FIXME("op %d not supported on parametrized assign expressions\n", op);
            return E_NOTIMPL;
        }

        if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
            hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
            if(FAILED(hres))
                return hres;

            for(arg = call_expr->argument_list; arg; arg = arg->next) {
                hres = compile_expression(ctx, arg->expr, TRUE);
                if(FAILED(hres))
                    return hres;
                arg_cnt++;
            }
        }else {
            use_throw_path = TRUE;
        }
    }else if(is_memberid_expr(expr->expression1->type)) {
        hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
        if(FAILED(hres))
            return hres;
    }else {
        use_throw_path = TRUE;
    }

    if(use_throw_path) {
        /* Illegal assignment: evaluate and throw */
        hres = compile_expression(ctx, expr->expression1, TRUE);
        if(FAILED(hres))
            return hres;

        hres = compile_expression(ctx, expr->expression2, TRUE);
        if(FAILED(hres))
            return hres;

        if(op != OP_LAST && !push_instr(ctx, op))
            return E_OUTOFMEMORY;

        return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
    }

    if(op != OP_LAST && !push_instr(ctx, OP_refval))
        return E_OUTOFMEMORY;

    hres = compile_expression(ctx, expr->expression2, TRUE);
    if(FAILED(hres))
        return hres;

    if(op != OP_LAST && !push_instr(ctx, op))
        return E_OUTOFMEMORY;

    if(arg_cnt)
        return push_instr_uint(ctx, OP_assign_call, arg_cnt);

    if(!push_instr(ctx, OP_assign))
        return E_OUTOFMEMORY;

    return S_OK;
}

static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
{
    jsop_t op;
    HRESULT hres;

    if(is_memberid_expr(expr->expression->type)) {
        if(expr->expression->type == EXPR_IDENT)
            return push_instr_bstr(ctx, OP_typeofident, ((identifier_expression_t*)expr->expression)->identifier);

        op = OP_typeofid;
        hres = compile_memberid_expression(ctx, expr->expression, 0);
    }else {
        op = OP_typeof;
        hres = compile_expression(ctx, expr->expression, TRUE);
    }
    if(FAILED(hres))
        return hres;

    return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
}

static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
{
    switch(literal->type) {
    case LT_BOOL:
        return push_instr_int(ctx, OP_bool, literal->u.bval);
    case LT_DOUBLE:
        return push_instr_double(ctx, OP_double, literal->u.dval);
    case LT_NULL:
        return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
    case LT_STRING:
        return push_instr_str(ctx, OP_str, literal->u.wstr);
    case LT_REGEXP: {
        unsigned instr;
        jsstr_t *str;

        str = compiler_alloc_string_len(ctx, literal->u.regexp.str, literal->u.regexp.str_len);
        if(!str)
            return E_OUTOFMEMORY;

        instr = push_instr(ctx, OP_regexp);
        if(!instr)
            return E_OUTOFMEMORY;

        instr_ptr(ctx, instr)->u.arg[0].str = str;
        instr_ptr(ctx, instr)->u.arg[1].uint = literal->u.regexp.flags;
        return S_OK;
    }
    DEFAULT_UNREACHABLE;
    }
    return E_FAIL;
}

static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *str)
{
    switch(literal->type) {
    case LT_STRING:
        *str = compiler_alloc_bstr(ctx, literal->u.wstr);
        break;
    case LT_DOUBLE: {
        jsstr_t *jsstr;
        HRESULT hres;

        hres = double_to_string(literal->u.dval, &jsstr);
        if(FAILED(hres))
            return hres;

        *str = compiler_alloc_bstr_len(ctx, NULL, jsstr_length(jsstr));
        if(*str)
            jsstr_flush(jsstr, *str);
        jsstr_release(jsstr);
        break;
    }
    DEFAULT_UNREACHABLE;
    }

    return *str ? S_OK : E_OUTOFMEMORY;
}

static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr)
{
    unsigned i, elem_cnt = expr->length;
    array_element_t *iter;
    HRESULT hres;

    for(iter = expr->element_list; iter; iter = iter->next) {
        elem_cnt += iter->elision+1;

        for(i=0; i < iter->elision; i++) {
            if(!push_instr(ctx, OP_undefined))
                return E_OUTOFMEMORY;
        }

        hres = compile_expression(ctx, iter->expr, TRUE);
        if(FAILED(hres))
            return hres;
    }

    for(i=0; i < expr->length; i++) {
        if(!push_instr(ctx, OP_undefined))
            return E_OUTOFMEMORY;
    }

    return push_instr_uint(ctx, OP_carray, elem_cnt);
}

static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
{
    prop_val_t *iter;
    unsigned instr;
    BSTR name;
    HRESULT hres;

    if(!push_instr(ctx, OP_new_obj))
        return E_OUTOFMEMORY;

    for(iter = expr->property_list; iter; iter = iter->next) {
        hres = literal_as_bstr(ctx, iter->name, &name);
        if(FAILED(hres))
            return hres;

        hres = compile_expression(ctx, iter->value, TRUE);
        if(FAILED(hres))
            return hres;

        instr = push_instr(ctx, OP_obj_prop);
        if(!instr)
            return E_OUTOFMEMORY;

        instr_ptr(ctx, instr)->u.arg->bstr = name;
    }

    return S_OK;
}

static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret)
{
    return emit_ret ? push_instr_uint(ctx, OP_func, expr->func_id) : S_OK;
}

static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr, BOOL emit_ret)
{
    HRESULT hres;

    switch(expr->type) {
    case EXPR_ADD:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_add);
        break;
    case EXPR_AND:
        hres = compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_z);
        break;
    case EXPR_ARRAY:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_array);
        break;
    case EXPR_ARRAYLIT:
        hres = compile_array_literal(ctx, (array_literal_expression_t*)expr);
        break;
    case EXPR_ASSIGN:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_LAST);
        break;
    case EXPR_ASSIGNADD:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_add);
        break;
    case EXPR_ASSIGNAND:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_and);
        break;
    case EXPR_ASSIGNSUB:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_sub);
        break;
    case EXPR_ASSIGNMUL:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mul);
        break;
    case EXPR_ASSIGNDIV:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_div);
        break;
    case EXPR_ASSIGNMOD:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_mod);
        break;
    case EXPR_ASSIGNOR:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_or);
        break;
    case EXPR_ASSIGNLSHIFT:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_lshift);
        break;
    case EXPR_ASSIGNRSHIFT:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift);
        break;
    case EXPR_ASSIGNRRSHIFT:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_rshift2);
        break;
    case EXPR_ASSIGNXOR:
        hres = compile_assign_expression(ctx, (binary_expression_t*)expr, OP_xor);
        break;
    case EXPR_BAND:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
        break;
    case EXPR_BITNEG:
        hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg);
        break;
    case EXPR_BOR:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
        break;
    case EXPR_CALL:
        return compile_call_expression(ctx, (call_expression_t*)expr, emit_ret);
    case EXPR_COMMA:
        return compile_comma_expression(ctx, (binary_expression_t*)expr, emit_ret);
    case EXPR_COND:
        hres = compile_conditional_expression(ctx, (conditional_expression_t*)expr);
        break;
    case EXPR_DELETE:
        hres = compile_delete_expression(ctx, (unary_expression_t*)expr);
        break;
    case EXPR_DIV:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
        break;
    case EXPR_EQ:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq);
        break;
    case EXPR_EQEQ:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq2);
        break;
    case EXPR_FUNC:
        return compile_function_expression(ctx, (function_expression_t*)expr, emit_ret);
    case EXPR_GREATER:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt);
        break;
    case EXPR_GREATEREQ:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gteq);
        break;
    case EXPR_IDENT:
        hres = emit_identifier(ctx, ((identifier_expression_t*)expr)->identifier);
        break;
    case EXPR_IN:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in);
        break;
    case EXPR_INSTANCEOF:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_instanceof);
        break;
    case EXPR_LESS:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
        break;
    case EXPR_LESSEQ:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lteq);
        break;
    case EXPR_LITERAL:
        hres = compile_literal(ctx, ((literal_expression_t*)expr)->literal);
        break;
    case EXPR_LOGNEG:
        hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
        break;
    case EXPR_LSHIFT:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lshift);
        break;
    case EXPR_MEMBER:
        hres = compile_member_expression(ctx, (member_expression_t*)expr);
        break;
    case EXPR_MINUS:
        hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_minus);
        break;
    case EXPR_MOD:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mod);
        break;
    case EXPR_MUL:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_mul);
        break;
    case EXPR_NEW:
        hres = compile_new_expression(ctx, (call_expression_t*)expr);
        break;
    case EXPR_NOTEQ:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq);
        break;
    case EXPR_NOTEQEQ:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq2);
        break;
    case EXPR_OR:
        hres = compile_logical_expression(ctx, (binary_expression_t*)expr, OP_cnd_nz);
        break;
    case EXPR_PLUS:
        hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_tonum);
        break;
    case EXPR_POSTDEC:
        hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, -1);
        break;
    case EXPR_POSTINC:
        hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, 1);
        break;
    case EXPR_PREDEC:
        hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, -1);
        break;
    case EXPR_PREINC:
        hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, 1);
        break;
    case EXPR_PROPVAL:
        hres = compile_object_literal(ctx, (property_value_expression_t*)expr);
        break;
    case EXPR_RSHIFT:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift);
        break;
    case EXPR_RRSHIFT:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_rshift2);
        break;
    case EXPR_SUB:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_sub);
        break;
    case EXPR_THIS:
        return !emit_ret || push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY;
    case EXPR_TYPEOF:
        hres = compile_typeof_expression(ctx, (unary_expression_t*)expr);
        break;
    case EXPR_VOID:
        hres = compile_unary_expression(ctx, (unary_expression_t*)expr, OP_void);
        break;
    case EXPR_BXOR:
        hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_xor);
        break;
    DEFAULT_UNREACHABLE;
    }

    if(FAILED(hres))
        return hres;

    return emit_ret ? S_OK : push_instr_uint(ctx, OP_pop, 1);
}

static inline BOOL is_loop_statement(statement_type_t type)
{
    return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE;
}

/* ECMA-262 3rd Edition    12.1 */
static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
{
    HRESULT hres;

    while(iter) {
        hres = compile_statement(ctx, NULL, iter);
        if(FAILED(hres))
            return hres;

        iter = iter->next;
    }

    return S_OK;
}

/* ECMA-262 3rd Edition    12.2 */
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
{
    variable_declaration_t *iter;
    HRESULT hres;

    assert(list != NULL);

    for(iter = list; iter; iter = iter->next) {
        if(!iter->expr)
            continue;

        hres = emit_identifier_ref(ctx, iter->identifier, 0);
        if(FAILED(hres))
            return hres;

        hres = compile_expression(ctx, iter->expr, TRUE);
        if(FAILED(hres))
            return hres;

        if(!push_instr(ctx, OP_assign))
            return E_OUTOFMEMORY;

        hres = push_instr_uint(ctx, OP_pop, 1);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}

/* ECMA-262 3rd Edition    12.2 */
static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat)
{
    return compile_variable_list(ctx, stat->variable_list);
}

/* ECMA-262 3rd Edition    12.4 */
static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
{
    HRESULT hres;

    hres = compile_expression(ctx, stat->expr, ctx->from_eval);
    if(FAILED(hres))
        return hres;

    return !ctx->from_eval || push_instr(ctx, OP_setret) ? S_OK : E_OUTOFMEMORY;
}

/* ECMA-262 3rd Edition    12.5 */
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
{
    unsigned jmp_else;
    HRESULT hres;

    hres = compile_expression(ctx, stat->expr, TRUE);
    if(FAILED(hres))
        return hres;

    jmp_else = push_instr(ctx, OP_jmp_z);
    if(!jmp_else)
        return E_OUTOFMEMORY;

    hres = compile_statement(ctx, NULL, stat->if_stat);
    if(FAILED(hres))
        return hres;

    if(stat->else_stat) {
        unsigned jmp_end;

        jmp_end = push_instr(ctx, OP_jmp);
        if(!jmp_end)
            return E_OUTOFMEMORY;

        set_arg_uint(ctx, jmp_else, ctx->code_off);

        hres = compile_statement(ctx, NULL, stat->else_stat);
        if(FAILED(hres))
            return hres;

        set_arg_uint(ctx, jmp_end, ctx->code_off);
    }else {
        set_arg_uint(ctx, jmp_else, ctx->code_off);
    }

    return S_OK;
}

/* ECMA-262 3rd Edition    12.6.2 */
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
{
    statement_ctx_t stat_ctx = {0, FALSE, FALSE};
    unsigned jmp_off;
    HRESULT hres;

    stat_ctx.break_label = alloc_label(ctx);
    if(!stat_ctx.break_label)
        return E_OUTOFMEMORY;

    stat_ctx.continue_label = alloc_label(ctx);
    if(!stat_ctx.continue_label)
        return E_OUTOFMEMORY;

    jmp_off = ctx->code_off;

    if(!stat->do_while) {
        label_set_addr(ctx, stat_ctx.continue_label);
        hres = compile_expression(ctx, stat->expr, TRUE);
        if(FAILED(hres))
            return hres;

        hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
        if(FAILED(hres))
            return hres;
    }

    hres = compile_statement(ctx, &stat_ctx, stat->statement);
    if(FAILED(hres))
        return hres;

    if(stat->do_while) {
        label_set_addr(ctx, stat_ctx.continue_label);
        hres = compile_expression(ctx, stat->expr, TRUE);
        if(FAILED(hres))
            return hres;

        hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
        if(FAILED(hres))
            return hres;
    }

    hres = push_instr_uint(ctx, OP_jmp, jmp_off);
    if(FAILED(hres))
        return hres;

    label_set_addr(ctx, stat_ctx.break_label);
    return S_OK;
}

/* ECMA-262 3rd Edition    12.6.3 */
static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
{
    statement_ctx_t stat_ctx = {0, FALSE, FALSE};
    unsigned expr_off;
    HRESULT hres;

    if(stat->variable_list) {
        hres = compile_variable_list(ctx, stat->variable_list);
        if(FAILED(hres))
            return hres;
    }else if(stat->begin_expr) {
        hres = compile_expression(ctx, stat->begin_expr, FALSE);
        if(FAILED(hres))
            return hres;
    }

    stat_ctx.break_label = alloc_label(ctx);
    if(!stat_ctx.break_label)
        return E_OUTOFMEMORY;

    stat_ctx.continue_label = alloc_label(ctx);
    if(!stat_ctx.continue_label)
        return E_OUTOFMEMORY;

    expr_off = ctx->code_off;

    if(stat->expr) {
        hres = compile_expression(ctx, stat->expr, TRUE);
        if(FAILED(hres))
            return hres;

        hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
        if(FAILED(hres))
            return hres;
    }

    hres = compile_statement(ctx, &stat_ctx, stat->statement);
    if(FAILED(hres))
        return hres;

    label_set_addr(ctx, stat_ctx.continue_label);

    if(stat->end_expr) {
        hres = compile_expression(ctx, stat->end_expr, FALSE);
        if(FAILED(hres))
            return hres;
    }

    hres = push_instr_uint(ctx, OP_jmp, expr_off);
    if(FAILED(hres))
        return hres;

    label_set_addr(ctx, stat_ctx.break_label);
    return S_OK;
}

/* ECMA-262 3rd Edition    12.6.4 */
static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat)
{
    statement_ctx_t stat_ctx = {4, FALSE, FALSE};
    HRESULT hres;

    if(stat->variable) {
        hres = compile_variable_list(ctx, stat->variable);
        if(FAILED(hres))
            return hres;
    }

    stat_ctx.break_label = alloc_label(ctx);
    if(!stat_ctx.break_label)
        return E_OUTOFMEMORY;

    stat_ctx.continue_label = alloc_label(ctx);
    if(!stat_ctx.continue_label)
        return E_OUTOFMEMORY;

    hres = compile_expression(ctx, stat->in_expr, TRUE);
    if(FAILED(hres))
        return hres;

    if(stat->variable) {
        hres = emit_identifier_ref(ctx, stat->variable->identifier, fdexNameEnsure);
        if(FAILED(hres))
            return hres;
    }else if(is_memberid_expr(stat->expr->type)) {
        hres = compile_memberid_expression(ctx, stat->expr, fdexNameEnsure);
        if(FAILED(hres))
            return hres;
    }else {
        hres = push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
        if(FAILED(hres))
            return hres;

        /* FIXME: compile statement anyways when we depend on compiler to check errors */
        return S_OK;
    }

    hres = push_instr_int(ctx, OP_int, DISPID_STARTENUM);
    if(FAILED(hres))
        return hres;

    label_set_addr(ctx, stat_ctx.continue_label);
    hres = push_instr_uint(ctx, OP_forin, stat_ctx.break_label);
    if(FAILED(hres))
        return E_OUTOFMEMORY;

    hres = compile_statement(ctx, &stat_ctx, stat->statement);
    if(FAILED(hres))
        return hres;

    hres = push_instr_uint(ctx, OP_jmp, stat_ctx.continue_label);
    if(FAILED(hres))
        return hres;

    label_set_addr(ctx, stat_ctx.break_label);
    return S_OK;
}

static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
{
    unsigned stack_pop = 0;
    statement_ctx_t *iter;
    HRESULT hres;

    for(iter = ctx->stat_ctx; iter != stat_ctx; iter = iter->next) {
        if(iter->using_scope && !push_instr(ctx, OP_pop_scope))
            return E_OUTOFMEMORY;
        if(iter->using_except) {
            if(stack_pop) {
                hres = push_instr_uint(ctx, OP_pop, stack_pop);
                if(FAILED(hres))
                    return hres;
                stack_pop = 0;
            }
            hres = push_instr_uint(ctx, OP_pop_except, ctx->code_off+1);
            if(FAILED(hres))
                return hres;
        }
        stack_pop += iter->stack_use;
    }

    if(stack_pop) {
        hres = push_instr_uint(ctx, OP_pop, stack_pop);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}

/* ECMA-262 3rd Edition    12.7 */
static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
{
    statement_ctx_t *pop_ctx;
    HRESULT hres;

    if(stat->identifier) {
        statement_t *label_stat;
        statement_ctx_t *iter;

        pop_ctx = NULL;

        for(iter = ctx->stat_ctx; iter; iter = iter->next) {
            if(iter->continue_label)
                pop_ctx = iter;
            if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier))
                break;
        }

        if(!iter) {
            WARN("Label not found\n");
            return JS_E_LABEL_NOT_FOUND;
        }

        /* Labelled continue are allowed only on loops */
        for(label_stat = iter->labelled_stat->statement;
            label_stat->type == STAT_LABEL;
            label_stat = ((labelled_statement_t*)label_stat)->statement);
        if(!is_loop_statement(label_stat->type)) {
            WARN("Label is not a loop\n");
            return JS_E_INVALID_CONTINUE;
        }

        assert(pop_ctx != NULL);
    }else {
        for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
            if(pop_ctx->continue_label)
                break;
        }

        if(!pop_ctx) {
            WARN("continue outside loop\n");
            return JS_E_INVALID_CONTINUE;
        }
    }

    hres = pop_to_stat(ctx, pop_ctx);
    if(FAILED(hres))
        return hres;

    return push_instr_uint(ctx, OP_jmp, pop_ctx->continue_label);
}

/* ECMA-262 3rd Edition    12.8 */
static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
{
    statement_ctx_t *pop_ctx;
    HRESULT hres;

    if(stat->identifier) {
        for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
            if(pop_ctx->labelled_stat && !strcmpW(pop_ctx->labelled_stat->identifier, stat->identifier)) {
                assert(pop_ctx->break_label);
                break;
            }
        }

        if(!pop_ctx) {
            WARN("Label not found\n");
            return JS_E_LABEL_NOT_FOUND;
        }
    }else {
        for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
            if(pop_ctx->break_label && !pop_ctx->labelled_stat)
                break;
        }

        if(!pop_ctx) {
            WARN("Break outside loop\n");
            return JS_E_INVALID_BREAK;
        }
    }

    hres = pop_to_stat(ctx, pop_ctx->next);
    if(FAILED(hres))
        return hres;

    return push_instr_uint(ctx, OP_jmp, pop_ctx->break_label);
}

/* ECMA-262 3rd Edition    12.9 */
static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
{
    HRESULT hres;

    if(ctx->from_eval) {
        WARN("misplaced return statement\n");
        return JS_E_MISPLACED_RETURN;
    }

    if(stat->expr) {
        hres = compile_expression(ctx, stat->expr, TRUE);
        if(FAILED(hres))
            return hres;
        if(!push_instr(ctx, OP_setret))
            return E_OUTOFMEMORY;
    }

    hres = pop_to_stat(ctx, NULL);
    if(FAILED(hres))
        return hres;

    return push_instr_uint(ctx, OP_ret, !stat->expr);
}

/* ECMA-262 3rd Edition    12.10 */
static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
{
    statement_ctx_t stat_ctx = {0, TRUE, FALSE};
    HRESULT hres;

    hres = compile_expression(ctx, stat->expr, TRUE);
    if(FAILED(hres))
        return hres;

    if(!push_instr(ctx, OP_push_scope))
        return E_OUTOFMEMORY;

    hres = compile_statement(ctx, &stat_ctx, stat->statement);
    if(FAILED(hres))
        return hres;

    if(!push_instr(ctx, OP_pop_scope))
        return E_OUTOFMEMORY;

    return S_OK;
}

/* ECMA-262 3rd Edition    12.10 */
static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat)
{
    statement_ctx_t stat_ctx = {0, FALSE, FALSE, 0, 0, stat}, *iter;
    HRESULT hres;

    for(iter = ctx->stat_ctx; iter; iter = iter->next) {
        if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier)) {
            WARN("Label %s redefined\n", debugstr_w(stat->identifier));
            return JS_E_LABEL_REDEFINED;
        }
    }

    /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
    stat_ctx.break_label = alloc_label(ctx);
    if(!stat_ctx.break_label)
        return E_OUTOFMEMORY;

    hres = compile_statement(ctx, &stat_ctx, stat->statement);
    if(FAILED(hres))
        return hres;

    label_set_addr(ctx, stat_ctx.break_label);
    return S_OK;
}

/* ECMA-262 3rd Edition    12.13 */
static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat)
{
    statement_ctx_t stat_ctx = {0, FALSE, FALSE};
    unsigned case_cnt = 0, *case_jmps, i, default_jmp;
    BOOL have_default = FALSE;
    statement_t *stat_iter;
    case_clausule_t *iter;
    HRESULT hres;

    hres = compile_expression(ctx, stat->expr, TRUE);
    if(FAILED(hres))
        return hres;

    stat_ctx.break_label = alloc_label(ctx);
    if(!stat_ctx.break_label)
        return E_OUTOFMEMORY;

    for(iter = stat->case_list; iter; iter = iter->next) {
        if(iter->expr)
            case_cnt++;
    }

    case_jmps = heap_alloc(case_cnt * sizeof(*case_jmps));
    if(!case_jmps)
        return E_OUTOFMEMORY;

    i = 0;
    for(iter = stat->case_list; iter; iter = iter->next) {
        if(!iter->expr) {
            have_default = TRUE;
            continue;
        }

        hres = compile_expression(ctx, iter->expr, TRUE);
        if(FAILED(hres))
            break;

        case_jmps[i] = push_instr(ctx, OP_case);
        if(!case_jmps[i]) {
            hres = E_OUTOFMEMORY;
            break;
        }
        i++;
    }

    if(SUCCEEDED(hres)) {
        hres = push_instr_uint(ctx, OP_pop, 1);
        if(SUCCEEDED(hres)) {
            default_jmp = push_instr(ctx, OP_jmp);
            if(!default_jmp)
                hres = E_OUTOFMEMORY;
        }
    }

    if(FAILED(hres)) {
        heap_free(case_jmps);
        return hres;
    }

    i = 0;
    for(iter = stat->case_list; iter; iter = iter->next) {
        while(iter->next && iter->next->stat == iter->stat) {
            set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
            iter = iter->next;
        }

        set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);

        for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
            stat_iter = stat_iter->next) {
            hres = compile_statement(ctx, &stat_ctx, stat_iter);
            if(FAILED(hres))
                break;
        }
        if(FAILED(hres))
            break;
    }

    heap_free(case_jmps);
    if(FAILED(hres))
        return hres;
    assert(i == case_cnt);

    if(!have_default) {
        hres = push_instr_uint(ctx, OP_jmp, stat_ctx.break_label);
        if(FAILED(hres))
            return hres;
        set_arg_uint(ctx, default_jmp, ctx->code_off);
    }

    label_set_addr(ctx, stat_ctx.break_label);
    return S_OK;
}

/* ECMA-262 3rd Edition    12.13 */
static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
{
    HRESULT hres;

    hres = compile_expression(ctx, stat->expr, TRUE);
    if(FAILED(hres))
        return hres;

    return push_instr(ctx, OP_throw) ? S_OK : E_OUTOFMEMORY;
}

/* ECMA-262 3rd Edition    12.14 */
static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
{
    statement_ctx_t try_ctx = {0, FALSE, TRUE}, finally_ctx = {2, FALSE, FALSE};
    unsigned push_except, finally_off = 0, catch_off = 0, pop_except, catch_pop_except = 0;
    BSTR ident;
    HRESULT hres;

    push_except = push_instr(ctx, OP_push_except);
    if(!push_except)
        return E_OUTOFMEMORY;

    if(stat->catch_block) {
        ident = compiler_alloc_bstr(ctx, stat->catch_block->identifier);
        if(!ident)
            return E_OUTOFMEMORY;
    }else {
        ident = NULL;
    }

    hres = compile_statement(ctx, &try_ctx, stat->try_statement);
    if(FAILED(hres))
        return hres;

    pop_except = push_instr(ctx, OP_pop_except);
    if(!pop_except)
        return E_OUTOFMEMORY;

    if(stat->catch_block) {
        statement_ctx_t catch_ctx = {0, TRUE, stat->finally_statement != NULL};

        if(stat->finally_statement)
            catch_ctx.using_except = TRUE;

        catch_off = ctx->code_off;

        hres = push_instr_bstr(ctx, OP_enter_catch, ident);
        if(FAILED(hres))
            return hres;

        hres = compile_statement(ctx, &catch_ctx, stat->catch_block->statement);
        if(FAILED(hres))
            return hres;

        if(!push_instr(ctx, OP_pop_scope))
            return E_OUTOFMEMORY;

        if(stat->finally_statement) {
            catch_pop_except = push_instr(ctx, OP_pop_except);
            if(!catch_pop_except)
                return E_OUTOFMEMORY;
        }
    }

    if(stat->finally_statement) {
        /*
         * finally block expects two elements on the stack, which may be:
         * - (true, return_addr) set by OP_pop_except, OP_end_finally jumps back to passed address
         * - (false, exception_value) set when unwinding an exception, which OP_end_finally rethrows
         */
        finally_off = ctx->code_off;
        hres = compile_statement(ctx, &finally_ctx, stat->finally_statement);
        if(FAILED(hres))
            return hres;

        if(!push_instr(ctx, OP_end_finally))
            return E_OUTOFMEMORY;
    }

    instr_ptr(ctx, pop_except)->u.arg[0].uint = ctx->code_off;
    if(catch_pop_except)
        instr_ptr(ctx, catch_pop_except)->u.arg[0].uint = ctx->code_off;
    instr_ptr(ctx, push_except)->u.arg[0].uint = catch_off;
    instr_ptr(ctx, push_except)->u.arg[1].uint = finally_off;
    return S_OK;
}

static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx, statement_t *stat)
{
    HRESULT hres;

    if(stat_ctx) {
        stat_ctx->next = ctx->stat_ctx;
        ctx->stat_ctx = stat_ctx;
    }

    switch(stat->type) {
    case STAT_BLOCK:
        hres = compile_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
        break;
    case STAT_BREAK:
        hres = compile_break_statement(ctx, (branch_statement_t*)stat);
        break;
    case STAT_CONTINUE:
        hres = compile_continue_statement(ctx, (branch_statement_t*)stat);
        break;
    case STAT_EMPTY:
        /* nothing to do */
        hres = S_OK;
        break;
    case STAT_EXPR:
        hres = compile_expression_statement(ctx, (expression_statement_t*)stat);
        break;
    case STAT_FOR:
        hres = compile_for_statement(ctx, (for_statement_t*)stat);
        break;
    case STAT_FORIN:
        hres = compile_forin_statement(ctx, (forin_statement_t*)stat);
        break;
    case STAT_IF:
        hres = compile_if_statement(ctx, (if_statement_t*)stat);
        break;
    case STAT_LABEL:
        hres = compile_labelled_statement(ctx, (labelled_statement_t*)stat);
        break;
    case STAT_RETURN:
        hres = compile_return_statement(ctx, (expression_statement_t*)stat);
        break;
    case STAT_SWITCH:
        hres = compile_switch_statement(ctx, (switch_statement_t*)stat);
        break;
    case STAT_THROW:
        hres = compile_throw_statement(ctx, (expression_statement_t*)stat);
        break;
    case STAT_TRY:
        hres = compile_try_statement(ctx, (try_statement_t*)stat);
        break;
    case STAT_VAR:
        hres = compile_var_statement(ctx, (var_statement_t*)stat);
        break;
    case STAT_WHILE:
        hres = compile_while_statement(ctx, (while_statement_t*)stat);
        break;
    case STAT_WITH:
        hres = compile_with_statement(ctx, (with_statement_t*)stat);
        break;
    DEFAULT_UNREACHABLE;
    }

    if(stat_ctx) {
        assert(ctx->stat_ctx == stat_ctx);
        ctx->stat_ctx = stat_ctx->next;
    }

    return hres;
}

static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
{
    function_local_t *local = WINE_RB_ENTRY_VALUE(entry, function_local_t, entry);
    return strcmpW(key, local->name);
}

static inline function_local_t *find_local(compiler_ctx_t *ctx, const WCHAR *name)
{
    struct wine_rb_entry *entry = wine_rb_get(&ctx->locals, name);
    return entry ? WINE_RB_ENTRY_VALUE(entry, function_local_t, entry) : NULL;
}

static BOOL alloc_local(compiler_ctx_t *ctx, BSTR name, int ref)
{
    function_local_t *local;

    local = heap_pool_alloc(&ctx->heap, sizeof(*local));
    if(!local)
        return FALSE;

    local->name = name;
    local->ref = ref;
    wine_rb_put(&ctx->locals, name, &local->entry);
    ctx->locals_cnt++;
    return TRUE;
}

static BOOL alloc_variable(compiler_ctx_t *ctx, const WCHAR *name)
{
    BSTR ident;

    if(find_local(ctx, name))
        return TRUE;

    ident = compiler_alloc_bstr(ctx, name);
    if(!ident)
        return FALSE;

    return alloc_local(ctx, ident, ctx->func->var_cnt++);
}

static HRESULT visit_function_expression(compiler_ctx_t *ctx, function_expression_t *expr)
{
    expr->func_id = ctx->func->func_cnt++;
    ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr);

    return !expr->identifier || expr->event_target || alloc_variable(ctx, expr->identifier)
        ? S_OK : E_OUTOFMEMORY;
}

static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr)
{
    HRESULT hres = S_OK;

    switch(expr->type) {
    case EXPR_ADD:
    case EXPR_AND:
    case EXPR_ARRAY:
    case EXPR_ASSIGN:
    case EXPR_ASSIGNADD:
    case EXPR_ASSIGNAND:
    case EXPR_ASSIGNSUB:
    case EXPR_ASSIGNMUL:
    case EXPR_ASSIGNDIV:
    case EXPR_ASSIGNMOD:
    case EXPR_ASSIGNOR:
    case EXPR_ASSIGNLSHIFT:
    case EXPR_ASSIGNRSHIFT:
    case EXPR_ASSIGNRRSHIFT:
    case EXPR_ASSIGNXOR:
    case EXPR_BAND:
    case EXPR_BOR:
    case EXPR_COMMA:
    case EXPR_DIV:
    case EXPR_EQ:
    case EXPR_EQEQ:
    case EXPR_GREATER:
    case EXPR_GREATEREQ:
    case EXPR_IN:
    case EXPR_INSTANCEOF:
    case EXPR_LESS:
    case EXPR_LESSEQ:
    case EXPR_LSHIFT:
    case EXPR_MOD:
    case EXPR_MUL:
    case EXPR_NOTEQ:
    case EXPR_NOTEQEQ:
    case EXPR_OR:
    case EXPR_RSHIFT:
    case EXPR_RRSHIFT:
    case EXPR_SUB:
    case EXPR_BXOR: {
        binary_expression_t *binary_expr = (binary_expression_t*)expr;

        hres = visit_expression(ctx, binary_expr->expression1);
        if(FAILED(hres))
            return hres;

        hres = visit_expression(ctx, binary_expr->expression2);
        break;
    }
    case EXPR_BITNEG:
    case EXPR_DELETE:
    case EXPR_LOGNEG:
    case EXPR_MINUS:
    case EXPR_PLUS:
    case EXPR_POSTDEC:
    case EXPR_POSTINC:
    case EXPR_PREDEC:
    case EXPR_PREINC:
    case EXPR_TYPEOF:
    case EXPR_VOID:
        hres = visit_expression(ctx, ((unary_expression_t*)expr)->expression);
        break;
    case EXPR_IDENT:
    case EXPR_LITERAL:
    case EXPR_THIS:
        break;
    case EXPR_ARRAYLIT: {
        array_literal_expression_t *array_expr = (array_literal_expression_t*)expr;
        array_element_t *iter;

        for(iter = array_expr->element_list; iter; iter = iter->next) {
            hres = visit_expression(ctx, iter->expr);
            if(FAILED(hres))
                return hres;
        }
        break;
    }
    case EXPR_CALL:
    case EXPR_NEW: {
        call_expression_t *call_expr = (call_expression_t*)expr;
        argument_t *arg;

        hres = visit_expression(ctx, call_expr->expression);
        if(FAILED(hres))
            return hres;

        for(arg = call_expr->argument_list; arg; arg = arg->next) {
            hres = visit_expression(ctx, arg->expr);
            if(FAILED(hres))
                return hres;
        }
        break;
    }
    case EXPR_COND: {
        conditional_expression_t *cond_expr = (conditional_expression_t*)expr;

        hres = visit_expression(ctx, cond_expr->expression);
        if(FAILED(hres))
            return hres;

        hres = visit_expression(ctx, cond_expr->true_expression);
        if(FAILED(hres))
            return hres;

        hres = visit_expression(ctx, cond_expr->false_expression);
        break;
    }
    case EXPR_FUNC:
        hres = visit_function_expression(ctx, (function_expression_t*)expr);
        break;
    case EXPR_MEMBER:
        hres = visit_expression(ctx, ((member_expression_t*)expr)->expression);
        break;
    case EXPR_PROPVAL: {
        prop_val_t *iter;
        for(iter = ((property_value_expression_t*)expr)->property_list; iter; iter = iter->next) {
            hres = visit_expression(ctx, iter->value);
            if(FAILED(hres))
                return hres;
        }
        break;
    }
    DEFAULT_UNREACHABLE;
    }

    return hres;
}

static HRESULT visit_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
{
    variable_declaration_t *iter;
    HRESULT hres;

    for(iter = list; iter; iter = iter->next) {
        if(!alloc_variable(ctx, iter->identifier))
            return E_OUTOFMEMORY;

        if(iter->expr) {
            hres = visit_expression(ctx, iter->expr);
            if(FAILED(hres))
                return hres;
        }
    }

    return S_OK;
}

static HRESULT visit_statement(compiler_ctx_t*,statement_t*);

static HRESULT visit_block_statement(compiler_ctx_t *ctx, statement_t *iter)
{
    HRESULT hres;

    while(iter) {
        hres = visit_statement(ctx, iter);
        if(FAILED(hres))
            return hres;

        iter = iter->next;
    }

    return S_OK;
}

static HRESULT visit_statement(compiler_ctx_t *ctx, statement_t *stat)
{
    HRESULT hres = S_OK;

    switch(stat->type) {
    case STAT_BLOCK:
        hres = visit_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
        break;
    case STAT_BREAK:
    case STAT_CONTINUE:
    case STAT_EMPTY:
        break;
    case STAT_EXPR:
    case STAT_RETURN:
    case STAT_THROW: {
        expression_statement_t *expr_stat = (expression_statement_t*)stat;
        if(expr_stat->expr)
            hres = visit_expression(ctx, expr_stat->expr);
        break;
    }
    case STAT_FOR: {
        for_statement_t *for_stat = (for_statement_t*)stat;

        if(for_stat->variable_list)
            hres = visit_variable_list(ctx, for_stat->variable_list);
        else if(for_stat->begin_expr)
            hres = visit_expression(ctx, for_stat->begin_expr);
        if(FAILED(hres))
            break;

        if(for_stat->expr) {
            hres = visit_expression(ctx, for_stat->expr);
            if(FAILED(hres))
                break;
        }

        hres = visit_statement(ctx, for_stat->statement);
        if(FAILED(hres))
            break;

        if(for_stat->end_expr)
            hres = visit_expression(ctx, for_stat->end_expr);
        break;
    }
    case STAT_FORIN:  {
        forin_statement_t *forin_stat = (forin_statement_t*)stat;

        if(forin_stat->variable) {
            hres = visit_variable_list(ctx, forin_stat->variable);
            if(FAILED(hres))
                break;
        }

        hres = visit_expression(ctx, forin_stat->in_expr);
        if(FAILED(hres))
            return hres;

        if(forin_stat->expr) {
            hres = visit_expression(ctx, forin_stat->expr);
            if(FAILED(hres))
                return hres;
        }

        hres = visit_statement(ctx, forin_stat->statement);
        break;
    }
    case STAT_IF: {
        if_statement_t *if_stat = (if_statement_t*)stat;

        hres = visit_expression(ctx, if_stat->expr);
        if(FAILED(hres))
            return hres;

        hres = visit_statement(ctx, if_stat->if_stat);
        if(FAILED(hres))
            return hres;

        if(if_stat->else_stat)
            hres = visit_statement(ctx, if_stat->else_stat);
        break;
    }
    case STAT_LABEL:
        hres = visit_statement(ctx, ((labelled_statement_t*)stat)->statement);
        break;
    case STAT_SWITCH: {
        switch_statement_t *switch_stat = (switch_statement_t*)stat;
        statement_t *stat_iter;
        case_clausule_t *iter;

        hres = visit_expression(ctx, switch_stat->expr);
        if(FAILED(hres))
            return hres;

        for(iter = switch_stat->case_list; iter; iter = iter->next) {
            if(!iter->expr)
                continue;
            hres = visit_expression(ctx, iter->expr);
            if(FAILED(hres))
                return hres;
        }

        for(iter = switch_stat->case_list; iter; iter = iter->next) {
            while(iter->next && iter->next->stat == iter->stat)
                iter = iter->next;
            for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
                stat_iter = stat_iter->next) {
                hres = visit_statement(ctx, stat_iter);
                if(FAILED(hres))
                    return hres;
            }
        }
        break;
    }
    case STAT_TRY: {
        try_statement_t *try_stat = (try_statement_t*)stat;

        hres = visit_statement(ctx, try_stat->try_statement);
        if(FAILED(hres))
            return hres;

        if(try_stat->catch_block) {
            hres = visit_statement(ctx, try_stat->catch_block->statement);
            if(FAILED(hres))
                return hres;
        }

        if(try_stat->finally_statement)
            hres = visit_statement(ctx, try_stat->finally_statement);
        break;
    }
    case STAT_VAR:
        hres = visit_variable_list(ctx, ((var_statement_t*)stat)->variable_list);
        break;
    case STAT_WHILE: {
        while_statement_t *while_stat = (while_statement_t*)stat;

        hres = visit_expression(ctx, while_stat->expr);
        if(FAILED(hres))
            return hres;

        hres = visit_statement(ctx, while_stat->statement);
        break;
    }
    case STAT_WITH: {
        with_statement_t *with_stat = (with_statement_t*)stat;

        hres = visit_expression(ctx, with_stat->expr);
        if(FAILED(hres))
            return hres;

        hres = visit_statement(ctx, with_stat->statement);
        break;
    }
    DEFAULT_UNREACHABLE;
    }

    return hres;
}

static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
{
    instr_t *instr;

    for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
        if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->u.arg->uint & LABEL_FLAG)) {
            assert((instr->u.arg->uint & ~LABEL_FLAG) < ctx->labels_cnt);
            instr->u.arg->uint = ctx->labels[instr->u.arg->uint & ~LABEL_FLAG];
        }
        assert(instr_info[instr->op].arg2_type != ARG_ADDR);
    }

    ctx->labels_cnt = 0;
}

void release_bytecode(bytecode_t *code)
{
    unsigned i;

    if(--code->ref)
        return;

    for(i=0; i < code->bstr_cnt; i++)
        SysFreeString(code->bstr_pool[i]);
    for(i=0; i < code->str_cnt; i++)
        jsstr_release(code->str_pool[i]);

    heap_free(code->source);
    heap_pool_free(&code->heap);
    heap_free(code->bstr_pool);
    heap_free(code->str_pool);
    heap_free(code->instrs);
    heap_free(code);
}

static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source)
{
    compiler->code = heap_alloc_zero(sizeof(bytecode_t));
    if(!compiler->code)
        return E_OUTOFMEMORY;

    compiler->code->ref = 1;
    heap_pool_init(&compiler->code->heap);

    compiler->code->source = heap_strdupW(source);
    if(!compiler->code->source) {
        release_bytecode(compiler->code);
        return E_OUTOFMEMORY;
    }

    compiler->code->instrs = heap_alloc(64 * sizeof(instr_t));
    if(!compiler->code->instrs) {
        release_bytecode(compiler->code);
        return E_OUTOFMEMORY;
    }

    compiler->code_size = 64;
    compiler->code_off = 1;
    return S_OK;
}

static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, function_expression_t *func_expr,
        BOOL from_eval, function_code_t *func)
{
    function_expression_t *iter;
    function_local_t *local;
    unsigned off, i;
    HRESULT hres;

    TRACE("\n");

    ctx->func_head = ctx->func_tail = NULL;
    ctx->from_eval = from_eval;
    ctx->func = func;
    ctx->locals_cnt = 0;
    wine_rb_init(&ctx->locals, function_local_cmp);

    if(func_expr) {
        parameter_t *param_iter;

        if(func_expr->identifier) {
            func->name = compiler_alloc_bstr(ctx, func_expr->identifier);
            if(!func->name)
                return E_OUTOFMEMORY;
        }

        if(func_expr->event_target) {
            func->event_target = compiler_alloc_bstr(ctx, func_expr->event_target);
            if(!func->event_target)
                return E_OUTOFMEMORY;
        }

        func->source = func_expr->src_str;
        func->source_len = func_expr->src_len;

        for(param_iter = func_expr->parameter_list; param_iter; param_iter = param_iter->next)
            func->param_cnt++;

        func->params = compiler_alloc(ctx->code, func->param_cnt * sizeof(*func->params));
        if(!func->params)
            return E_OUTOFMEMORY;

        for(param_iter = func_expr->parameter_list, i=0; param_iter; param_iter = param_iter->next, i++) {
            func->params[i] = compiler_alloc_bstr(ctx, param_iter->identifier);
            if(!func->params[i])
                return E_OUTOFMEMORY;
        }
    }

    for(i = 0; i < func->param_cnt; i++) {
        if(!find_local(ctx, func->params[i]) && !alloc_local(ctx, func->params[i], -i-1))
            return E_OUTOFMEMORY;
    }

    hres = visit_block_statement(ctx, source->statement);
    if(FAILED(hres))
        return hres;

    func->locals = compiler_alloc(ctx->code, ctx->locals_cnt * sizeof(*func->locals));
    if(!func->locals)
        return E_OUTOFMEMORY;
    func->locals_cnt = ctx->locals_cnt;

    func->variables = compiler_alloc(ctx->code, func->var_cnt * sizeof(*func->variables));
    if(!func->variables)
        return E_OUTOFMEMORY;

    i = 0;
    WINE_RB_FOR_EACH_ENTRY(local, &ctx->locals, function_local_t, entry) {
        func->locals[i].name = local->name;
        func->locals[i].ref = local->ref;
        if(local->ref >= 0) {
            func->variables[local->ref].name = local->name;
            func->variables[local->ref].func_id = -1;
        }
        i++;
    }
    assert(i == ctx->locals_cnt);

    func->funcs = compiler_alloc(ctx->code, func->func_cnt * sizeof(*func->funcs));
    if(!func->funcs)
        return E_OUTOFMEMORY;
    memset(func->funcs, 0, func->func_cnt * sizeof(*func->funcs));

    off = ctx->code_off;
    hres = compile_block_statement(ctx, source->statement);
    if(FAILED(hres))
        return hres;

    resolve_labels(ctx, off);

    hres = push_instr_uint(ctx, OP_ret, !from_eval);
    if(FAILED(hres))
        return hres;

    if(TRACE_ON(jscript_disas))
        dump_code(ctx, off);

    func->instr_off = off;

    for(iter = ctx->func_head, i=0; iter; iter = iter->next, i++) {
        hres = compile_function(ctx, iter->source_elements, iter, FALSE, func->funcs+i);
        if(FAILED(hres))
            return hres;

        TRACE("[%d] func %s\n", i, debugstr_w(func->funcs[i].name));
        if(func->funcs[i].name && !func->funcs[i].event_target) {
            local_ref_t *local_ref = lookup_local(func, func->funcs[i].name);
            func->funcs[i].local_ref = local_ref->ref;
            TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name));
            if(local_ref->ref >= 0)
                func->variables[local_ref->ref].func_id = i;
        }
    }

    assert(i == func->func_cnt);

    return S_OK;
}

static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
{
    const WCHAR *ptr = args, *ptr2;
    unsigned arg_cnt = 0;

    while(isspaceW(*ptr))
        ptr++;
    if(!*ptr) {
        if(args_size)
            *args_size = 0;
        return S_OK;
    }

    while(1) {
        if(!isalphaW(*ptr) && *ptr != '_') {
            FIXME("expected alpha or '_': %s\n", debugstr_w(ptr));
            return E_FAIL;
        }

        ptr2 = ptr;
        while(isalnumW(*ptr) || *ptr == '_')
            ptr++;

        if(*ptr && *ptr != ',' && !isspaceW(*ptr)) {
            FIXME("unexpected har %s\n", debugstr_w(ptr));
            return E_FAIL;
        }

        if(arg_array) {
            arg_array[arg_cnt] = compiler_alloc_bstr_len(ctx, ptr2, ptr-ptr2);
            if(!arg_array[arg_cnt])
                return E_OUTOFMEMORY;
        }
        arg_cnt++;

        while(isspaceW(*ptr))
            ptr++;
        if(!*ptr)
            break;
        if(*ptr != ',') {
            FIXME("expected ',': %s\n", debugstr_w(ptr));
            return E_FAIL;
        }

        ptr++;
        while(isspaceW(*ptr))
            ptr++;
    }

    if(args_size)
        *args_size = arg_cnt;
    return S_OK;
}

static HRESULT compile_arguments(compiler_ctx_t *ctx, const WCHAR *args)
{
    HRESULT hres;

    hres = parse_arguments(ctx, args, NULL, &ctx->code->global_code.param_cnt);
    if(FAILED(hres))
        return hres;

    ctx->code->global_code.params = compiler_alloc(ctx->code,
            ctx->code->global_code.param_cnt * sizeof(*ctx->code->global_code.params));
    if(!ctx->code->global_code.params)
        return E_OUTOFMEMORY;

    return parse_arguments(ctx, args, ctx->code->global_code.params, NULL);
}

HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, const WCHAR *delimiter,
        BOOL from_eval, BOOL use_decode, bytecode_t **ret)
{
    compiler_ctx_t compiler = {0};
    HRESULT hres;

    hres = init_code(&compiler, code);
    if(FAILED(hres))
        return hres;

    if(args) {
        hres = compile_arguments(&compiler, args);
        if(FAILED(hres))
            return hres;
    }

    if(use_decode) {
        hres = decode_source(compiler.code->source);
        if(FAILED(hres)) {
            WARN("Decoding failed\n");
            return hres;
        }
    }

    hres = script_parse(ctx, compiler.code->source, delimiter, from_eval, &compiler.parser);
    if(FAILED(hres)) {
        release_bytecode(compiler.code);
        return hres;
    }

    heap_pool_init(&compiler.heap);
    hres = compile_function(&compiler, compiler.parser->source, NULL, from_eval, &compiler.code->global_code);
    heap_pool_free(&compiler.heap);
    parser_release(compiler.parser);
    if(FAILED(hres)) {
        release_bytecode(compiler.code);
        return hres;
    }

    *ret = compiler.code;
    return S_OK;
}
