HRESULT compile_subscript_stat(parser_ctx_t *parser, statement_t *stat, BOOL from_eval, unsigned *ret_off) { unsigned off; HRESULT hres; TRACE("\n"); hres = init_compiler(parser); if(FAILED(hres)) return hres; off = parser->compiler->code_off; if(stat->next) hres = compile_block_statement(parser->compiler, stat); else hres = compile_statement(parser->compiler, NULL, stat); if(FAILED(hres)) return hres; resolve_labels(parser->compiler, off); if(!from_eval && !push_instr(parser->compiler, OP_pop)) return E_OUTOFMEMORY; if(!push_instr(parser->compiler, OP_ret)) return E_OUTOFMEMORY; if(TRACE_ON(jscript_disas)) dump_code(parser->compiler, off); *ret_off = off; return S_OK; }
static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func) { HRESULT hres; func->code_off = ctx->instr_cnt; ctx->while_end_label = -1; ctx->sub_end_label = -1; ctx->func_end_label = -1; ctx->prop_end_label = -1; switch(func->type) { case FUNC_FUNCTION: ctx->func_end_label = alloc_label(ctx); if(ctx->func_end_label == -1) return E_OUTOFMEMORY; /* FIXME ! */ break; case FUNC_SUB: ctx->sub_end_label = alloc_label(ctx); if(ctx->sub_end_label == -1) return E_OUTOFMEMORY; break; case FUNC_PROPGET: case FUNC_PROPLET: case FUNC_PROPSET: case FUNC_DEFGET: ctx->prop_end_label = alloc_label(ctx); if(ctx->prop_end_label == -1) return E_OUTOFMEMORY; break; case FUNC_GLOBAL: break; } ctx->func = func; ctx->dim_decls = NULL; hres = compile_statement(ctx, stat); ctx->func = NULL; if(FAILED(hres)) return hres; assert(ctx->while_end_label == -1); if(ctx->sub_end_label != -1) label_set_addr(ctx, ctx->sub_end_label); if(ctx->func_end_label != -1) label_set_addr(ctx, ctx->func_end_label); if(ctx->prop_end_label != -1) label_set_addr(ctx, ctx->prop_end_label); if(push_instr(ctx, OP_ret) == -1) return E_OUTOFMEMORY; resolve_labels(ctx, func->code_off); if(func->var_cnt) { dim_decl_t *dim_decl; if(func->type == FUNC_GLOBAL) { dynamic_var_t *new_var; func->var_cnt = 0; for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) { new_var = compiler_alloc(ctx->code, sizeof(*new_var)); if(!new_var) return E_OUTOFMEMORY; new_var->name = compiler_alloc_string(ctx->code, dim_decl->name); if(!new_var->name) return E_OUTOFMEMORY; V_VT(&new_var->v) = VT_EMPTY; new_var->next = ctx->global_vars; ctx->global_vars = new_var; } }else { unsigned i; func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t)); if(!func->vars) return E_OUTOFMEMORY; for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) { func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name); if(!func->vars[i].name) return E_OUTOFMEMORY; } assert(i == func->var_cnt); } } return S_OK; }