ReactOS 0.4.16-dev-297-gc569aee
compile.c File Reference
#include <assert.h>
#include "vbscript.h"
#include "parse.h"
#include "parser.tab.h"
#include "wine/debug.h"
Include dependency graph for compile.c:

Go to the source code of this file.

Classes

struct  _statement_ctx_t
 
struct  compile_ctx_t
 

Macros

#define X(n, a, b, c)   {#n,b,c},
 
#define LABEL_FLAG   0x80000000
 

Typedefs

typedef struct _statement_ctx_t statement_ctx_t
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (vbscript)
 
 WINE_DECLARE_DEBUG_CHANNEL (vbscript_disas)
 
static HRESULT compile_expression (compile_ctx_t *, expression_t *)
 
static HRESULT compile_statement (compile_ctx_t *, statement_ctx_t *, statement_t *)
 
static void dump_instr_arg (instr_arg_type_t type, instr_arg_t *arg)
 
static void dump_code (compile_ctx_t *ctx)
 
static voidcompiler_alloc (vbscode_t *vbscode, size_t size)
 
static voidcompiler_alloc_zero (vbscode_t *vbscode, size_t size)
 
static WCHARcompiler_alloc_string (vbscode_t *vbscode, const WCHAR *str)
 
static instr_tinstr_ptr (compile_ctx_t *ctx, unsigned id)
 
static unsigned push_instr (compile_ctx_t *ctx, vbsop_t op)
 
static HRESULT push_instr_int (compile_ctx_t *ctx, vbsop_t op, LONG arg)
 
static HRESULT push_instr_uint (compile_ctx_t *ctx, vbsop_t op, unsigned arg)
 
static HRESULT push_instr_addr (compile_ctx_t *ctx, vbsop_t op, unsigned arg)
 
static HRESULT push_instr_str (compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
 
static HRESULT push_instr_double (compile_ctx_t *ctx, vbsop_t op, double arg)
 
static BSTR alloc_bstr_arg (compile_ctx_t *ctx, const WCHAR *str)
 
static HRESULT push_instr_bstr (compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg)
 
static HRESULT push_instr_bstr_uint (compile_ctx_t *ctx, vbsop_t op, const WCHAR *arg1, unsigned arg2)
 
static HRESULT push_instr_uint_bstr (compile_ctx_t *ctx, vbsop_t op, unsigned arg1, const WCHAR *arg2)
 
static unsigned alloc_label (compile_ctx_t *ctx)
 
static void label_set_addr (compile_ctx_t *ctx, unsigned label)
 
static unsigned stack_offset (compile_ctx_t *ctx)
 
static BOOL emit_catch_jmp (compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
 
static BOOL emit_catch (compile_ctx_t *ctx, unsigned off)
 
static HRESULT compile_error (script_ctx_t *ctx, HRESULT error)
 
static expression_tlookup_const_decls (compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
 
static HRESULT compile_args (compile_ctx_t *ctx, expression_t *args, unsigned *ret)
 
static HRESULT compile_member_expression (compile_ctx_t *ctx, member_expression_t *expr, BOOL ret_val)
 
static HRESULT compile_unary_expression (compile_ctx_t *ctx, unary_expression_t *expr, vbsop_t op)
 
static HRESULT compile_binary_expression (compile_ctx_t *ctx, binary_expression_t *expr, vbsop_t op)
 
static HRESULT compile_if_statement (compile_ctx_t *ctx, if_statement_t *stat)
 
static HRESULT compile_while_statement (compile_ctx_t *ctx, while_statement_t *stat)
 
static HRESULT compile_dowhile_statement (compile_ctx_t *ctx, while_statement_t *stat)
 
static HRESULT compile_foreach_statement (compile_ctx_t *ctx, foreach_statement_t *stat)
 
static HRESULT compile_forto_statement (compile_ctx_t *ctx, forto_statement_t *stat)
 
static HRESULT compile_select_statement (compile_ctx_t *ctx, select_statement_t *stat)
 
static HRESULT compile_assignment (compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
 
static HRESULT compile_assign_statement (compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
 
static HRESULT compile_call_statement (compile_ctx_t *ctx, call_statement_t *stat)
 
static BOOL lookup_dim_decls (compile_ctx_t *ctx, const WCHAR *name)
 
static BOOL lookup_args_name (compile_ctx_t *ctx, const WCHAR *name)
 
static HRESULT compile_dim_statement (compile_ctx_t *ctx, dim_statement_t *stat)
 
static HRESULT compile_const_statement (compile_ctx_t *ctx, const_statement_t *stat)
 
static HRESULT compile_function_statement (compile_ctx_t *ctx, function_statement_t *stat)
 
static HRESULT compile_exitdo_statement (compile_ctx_t *ctx)
 
static HRESULT compile_exitfor_statement (compile_ctx_t *ctx)
 
static HRESULT exit_label (compile_ctx_t *ctx, unsigned jmp_label)
 
static HRESULT compile_exitsub_statement (compile_ctx_t *ctx)
 
static HRESULT compile_exitfunc_statement (compile_ctx_t *ctx)
 
static HRESULT compile_exitprop_statement (compile_ctx_t *ctx)
 
static HRESULT compile_onerror_statement (compile_ctx_t *ctx, onerror_statement_t *stat)
 
static HRESULT compile_retval_statement (compile_ctx_t *ctx, retval_statement_t *stat)
 
static void resolve_labels (compile_ctx_t *ctx, unsigned off)
 
static HRESULT fill_array_desc (compile_ctx_t *ctx, dim_decl_t *dim_decl, array_desc_t *array_desc)
 
static HRESULT compile_func (compile_ctx_t *ctx, statement_t *stat, function_t *func)
 
static BOOL lookup_funcs_name (compile_ctx_t *ctx, const WCHAR *name)
 
static HRESULT create_function (compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
 
static BOOL lookup_class_name (compile_ctx_t *ctx, const WCHAR *name)
 
static HRESULT create_class_funcprop (compile_ctx_t *ctx, function_decl_t *func_decl, vbdisp_funcprop_desc_t *desc)
 
static BOOL lookup_class_funcs (class_desc_t *class_desc, const WCHAR *name)
 
static HRESULT compile_class (compile_ctx_t *ctx, class_decl_t *class_decl)
 
static BOOL lookup_script_identifier (script_ctx_t *script, const WCHAR *identifier)
 
static HRESULT check_script_collisions (compile_ctx_t *ctx, script_ctx_t *script)
 
void release_vbscode (vbscode_t *code)
 
static vbscode_talloc_vbscode (compile_ctx_t *ctx, const WCHAR *source)
 
static void release_compiler (compile_ctx_t *ctx)
 
HRESULT compile_script (script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, vbscode_t **ret)
 
HRESULT compile_procedure (script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, class_desc_t **ret)
 

Variables

struct {
   const char *   op_str
 
   instr_arg_type_t   arg1_type
 
   instr_arg_type_t   arg2_type
 
instr_info []
 

Macro Definition Documentation

◆ LABEL_FLAG

#define LABEL_FLAG   0x80000000

Definition at line 320 of file compile.c.

◆ X

#define X (   n,
  a,
  b,
  c 
)    {#n,b,c},

Typedef Documentation

◆ statement_ctx_t

Function Documentation

◆ alloc_bstr_arg()

static BSTR alloc_bstr_arg ( compile_ctx_t ctx,
const WCHAR str 
)
static

Definition at line 242 of file compile.c.

243{
244 if(!ctx->code->bstr_pool_size) {
245 ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
246 if(!ctx->code->bstr_pool)
247 return NULL;
248 ctx->code->bstr_pool_size = 8;
249 }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
250 BSTR *new_pool;
251
252 new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
253 if(!new_pool)
254 return NULL;
255
256 ctx->code->bstr_pool = new_pool;
257 ctx->code->bstr_pool_size *= 2;
258 }
259
260 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
261 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
262 return NULL;
263
264 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
265}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define NULL
Definition: types.h:112
OLECHAR * BSTR
Definition: compat.h:2293
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
const WCHAR * str

Referenced by compile_forto_statement(), push_instr_bstr(), push_instr_bstr_uint(), and push_instr_uint_bstr().

◆ alloc_label()

static unsigned alloc_label ( compile_ctx_t ctx)
static

Definition at line 322 of file compile.c.

323{
324 if(!ctx->labels_size) {
325 ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
326 if(!ctx->labels)
327 return 0;
328 ctx->labels_size = 8;
329 }else if(ctx->labels_size == ctx->labels_cnt) {
330 unsigned *new_labels;
331
332 new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
333 if(!new_labels)
334 return 0;
335
336 ctx->labels = new_labels;
337 ctx->labels_size *= 2;
338 }
339
340 return ctx->labels_cnt++ | LABEL_FLAG;
341}
#define LABEL_FLAG
Definition: compile.c:393

◆ alloc_vbscode()

static vbscode_t * alloc_vbscode ( compile_ctx_t ctx,
const WCHAR source 
)
static

Definition at line 1787 of file compile.c.

1788{
1789 vbscode_t *ret;
1790
1791 ret = heap_alloc_zero(sizeof(*ret));
1792 if(!ret)
1793 return NULL;
1794
1795 ret->source = heap_strdupW(source);
1796 if(!ret->source) {
1797 heap_free(ret);
1798 return NULL;
1799 }
1800
1801 ret->instrs = heap_alloc(32*sizeof(instr_t));
1802 if(!ret->instrs) {
1804 return NULL;
1805 }
1806
1807 ctx->instr_cnt = 1;
1808 ctx->instr_size = 32;
1809 heap_pool_init(&ret->heap);
1810
1811 ret->option_explicit = ctx->parser.option_explicit;
1812
1813 ret->main_code.type = FUNC_GLOBAL;
1814 ret->main_code.code_ctx = ret;
1815
1816 list_init(&ret->entry);
1817 return ret;
1818}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: edit.c:4312
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
void release_vbscode(vbscode_t *code)
Definition: compile.c:1768
@ FUNC_GLOBAL
Definition: vbscript.h:308
int ret

Referenced by compile_script().

◆ check_script_collisions()

static HRESULT check_script_collisions ( compile_ctx_t ctx,
script_ctx_t script 
)
static

Definition at line 1738 of file compile.c.

1739{
1740 class_desc_t *class;
1743
1744 for(var = ctx->global_vars; var; var = var->next) {
1745 if(lookup_script_identifier(script, var->name)) {
1746 FIXME("%s: redefined\n", debugstr_w(var->name));
1747 return E_FAIL;
1748 }
1749 }
1750
1751 for(func = ctx->funcs; func; func = func->next) {
1753 FIXME("%s: redefined\n", debugstr_w(func->name));
1754 return E_FAIL;
1755 }
1756 }
1757
1758 for(class = ctx->classes; class; class = class->next) {
1760 FIXME("%s: redefined\n", debugstr_w(class->name));
1761 return E_FAIL;
1762 }
1763 }
1764
1765 return S_OK;
1766}
const WCHAR * class
Definition: main.c:68
#define FIXME(fmt,...)
Definition: precomp.h:53
#define E_FAIL
Definition: ddrawi.h:102
GLenum func
Definition: glext.h:6028
#define S_OK
Definition: intsafe.h:52
#define debugstr_w
Definition: kernel32.h:32
const char * var
Definition: shader.c:5666
script
Definition: msipriv.h:383
static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
Definition: compile.c:1714

Referenced by compile_script().

◆ compile_args()

static HRESULT compile_args ( compile_ctx_t ctx,
expression_t args,
unsigned ret 
)
static

Definition at line 410 of file compile.c.

411{
412 unsigned arg_cnt = 0;
414
415 while(args) {
417 if(FAILED(hres))
418 return hres;
419
420 arg_cnt++;
421 args = args->next;
422 }
423
424 *ret = arg_cnt;
425 return S_OK;
426}
#define FAILED(hr)
Definition: intsafe.h:51
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
HRESULT hres
Definition: protocol.c:465
Definition: match.c:390
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:162

Referenced by compile_assignment(), compile_member_expression(), and shader_arb_select().

◆ compile_assign_statement()

static HRESULT compile_assign_statement ( compile_ctx_t ctx,
assign_statement_t stat,
BOOL  is_set 
)
static

Definition at line 968 of file compile.c.

969{
970 return compile_assignment(ctx, stat->member_expr, stat->value_expr, is_set);
971}
Definition: stat.h:55
static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
Definition: compile.c:934

Referenced by compile_statement().

◆ compile_assignment()

static HRESULT compile_assignment ( compile_ctx_t ctx,
member_expression_t member_expr,
expression_t value_expr,
BOOL  is_set 
)
static

Definition at line 934 of file compile.c.

935{
936 unsigned args_cnt;
937 vbsop_t op;
939
940 if(member_expr->obj_expr) {
941 hres = compile_expression(ctx, member_expr->obj_expr);
942 if(FAILED(hres))
943 return hres;
944
945 op = is_set ? OP_set_member : OP_assign_member;
946 }else {
947 op = is_set ? OP_set_ident : OP_assign_ident;
948 }
949
950 hres = compile_expression(ctx, value_expr);
951 if(FAILED(hres))
952 return hres;
953
954 hres = compile_args(ctx, member_expr->args, &args_cnt);
955 if(FAILED(hres))
956 return hres;
957
958 hres = push_instr_bstr_uint(ctx, op, member_expr->identifier, args_cnt);
959 if(FAILED(hres))
960 return hres;
961
962 if(!emit_catch(ctx, 0))
963 return E_OUTOFMEMORY;
964
965 return S_OK;
966}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
UINT op
Definition: effect.c:236
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:290
expression_t * obj_expr
Definition: parse.h:96
const WCHAR * identifier
Definition: parser.h:325
expression_t * args
Definition: parse.h:98
static BOOL emit_catch(compile_ctx_t *ctx, unsigned off)
Definition: compile.c:373
static HRESULT compile_args(compile_ctx_t *ctx, expression_t *args, unsigned *ret)
Definition: compile.c:410
vbsop_t
Definition: vbscript.h:281

Referenced by compile_assign_statement(), and compile_call_statement().

◆ compile_binary_expression()

static HRESULT compile_binary_expression ( compile_ctx_t ctx,
binary_expression_t expr,
vbsop_t  op 
)
static

Definition at line 469 of file compile.c.

470{
472
474 if(FAILED(hres))
475 return hres;
476
477 hres = compile_expression(ctx, expr->right);
478 if(FAILED(hres))
479 return hres;
480
481 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
482}
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
Definition: query.h:86

◆ compile_call_statement()

static HRESULT compile_call_statement ( compile_ctx_t ctx,
call_statement_t stat 
)
static

Definition at line 973 of file compile.c.

974{
976
977 /* It's challenging for parser to distinguish parameterized assignment with one argument from call
978 * with equality expression argument, so we do it in compiler. */
979 if(!stat->is_strict && stat->expr->args && !stat->expr->args->next && stat->expr->args->type == EXPR_EQUAL) {
980 binary_expression_t *eqexpr = (binary_expression_t*)stat->expr->args;
981
982 if(eqexpr->left->type == EXPR_BRACKETS) {
983 member_expression_t new_member = *stat->expr;
984
985 WARN("converting call expr to assign expr\n");
986
987 new_member.args = ((unary_expression_t*)eqexpr->left)->subexpr;
988 return compile_assignment(ctx, &new_member, eqexpr->right, FALSE);
989 }
990 }
991
993 if(FAILED(hres))
994 return hres;
995
996 if(!emit_catch(ctx, 0))
997 return E_OUTOFMEMORY;
998
999 return S_OK;
1000}
#define WARN(fmt,...)
Definition: precomp.h:61
#define FALSE
Definition: types.h:117
@ EXPR_BRACKETS
Definition: parse.h:25
@ EXPR_EQUAL
Definition: parse.h:30
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:382
expression_type_t type
Definition: parser.h:278
expression_t * left
Definition: parse.h:90
expression_t * right
Definition: parse.h:91

Referenced by compile_statement().

◆ compile_class()

static HRESULT compile_class ( compile_ctx_t ctx,
class_decl_t class_decl 
)
static

Definition at line 1601 of file compile.c.

1602{
1603 function_decl_t *func_decl, *func_prop_decl;
1604 class_desc_t *class_desc;
1605 dim_decl_t *prop_decl;
1606 unsigned i;
1607 HRESULT hres;
1608
1609 static const WCHAR class_initializeW[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0};
1610 static const WCHAR class_terminateW[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0};
1611
1612 if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
1613 || lookup_const_decls(ctx, class_decl->name, FALSE) || lookup_class_name(ctx, class_decl->name)) {
1614 FIXME("%s: redefinition\n", debugstr_w(class_decl->name));
1615 return E_FAIL;
1616 }
1617
1618 class_desc = compiler_alloc_zero(ctx->code, sizeof(*class_desc));
1619 if(!class_desc)
1620 return E_OUTOFMEMORY;
1621
1622 class_desc->name = compiler_alloc_string(ctx->code, class_decl->name);
1623 if(!class_desc->name)
1624 return E_OUTOFMEMORY;
1625
1626 class_desc->func_cnt = 1; /* always allocate slot for default getter */
1627
1628 for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
1629 for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1630 if(func_prop_decl->type == FUNC_DEFGET)
1631 break;
1632 }
1633 if(!func_prop_decl)
1634 class_desc->func_cnt++;
1635 }
1636
1637 class_desc->funcs = compiler_alloc(ctx->code, class_desc->func_cnt*sizeof(*class_desc->funcs));
1638 if(!class_desc->funcs)
1639 return E_OUTOFMEMORY;
1640 memset(class_desc->funcs, 0, class_desc->func_cnt*sizeof(*class_desc->funcs));
1641
1642 for(func_decl = class_decl->funcs, i=1; func_decl; func_decl = func_decl->next, i++) {
1643 for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
1644 if(func_prop_decl->type == FUNC_DEFGET) {
1645 i--;
1646 break;
1647 }
1648 }
1649
1650 if(!wcsicmp(class_initializeW, func_decl->name)) {
1651 if(func_decl->type != FUNC_SUB) {
1652 FIXME("class initializer is not sub\n");
1653 return E_FAIL;
1654 }
1655
1656 class_desc->class_initialize_id = i;
1657 }else if(!wcsicmp(class_terminateW, func_decl->name)) {
1658 if(func_decl->type != FUNC_SUB) {
1659 FIXME("class terminator is not sub\n");
1660 return E_FAIL;
1661 }
1662
1663 class_desc->class_terminate_id = i;
1664 }
1665
1666 hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i));
1667 if(FAILED(hres))
1668 return hres;
1669 }
1670
1671 for(prop_decl = class_decl->props; prop_decl; prop_decl = prop_decl->next)
1672 class_desc->prop_cnt++;
1673
1674 class_desc->props = compiler_alloc(ctx->code, class_desc->prop_cnt*sizeof(*class_desc->props));
1675 if(!class_desc->props)
1676 return E_OUTOFMEMORY;
1677
1678 for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next, i++) {
1679 if(lookup_class_funcs(class_desc, prop_decl->name)) {
1680 FIXME("Property %s redefined\n", debugstr_w(prop_decl->name));
1681 return E_FAIL;
1682 }
1683
1684 class_desc->props[i].name = compiler_alloc_string(ctx->code, prop_decl->name);
1685 if(!class_desc->props[i].name)
1686 return E_OUTOFMEMORY;
1687
1688 class_desc->props[i].is_public = prop_decl->is_public;
1689 class_desc->props[i].is_array = prop_decl->is_array;
1690
1691 if(prop_decl->is_array)
1692 class_desc->array_cnt++;
1693 }
1694
1695 if(class_desc->array_cnt) {
1696 class_desc->array_descs = compiler_alloc(ctx->code, class_desc->array_cnt*sizeof(*class_desc->array_descs));
1697 if(!class_desc->array_descs)
1698 return E_OUTOFMEMORY;
1699
1700 for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next) {
1701 if(prop_decl->is_array) {
1702 hres = fill_array_desc(ctx, prop_decl, class_desc->array_descs + i++);
1703 if(FAILED(hres))
1704 return hres;
1705 }
1706 }
1707 }
1708
1709 class_desc->next = ctx->classes;
1710 ctx->classes = class_desc;
1711 return S_OK;
1712}
#define wcsicmp
Definition: compat.h:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:128
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:161
#define memset(x, y, z)
Definition: compat.h:39
const WCHAR * name
Definition: parse.h:184
function_decl_t * funcs
Definition: parse.h:185
dim_decl_t * props
Definition: parse.h:186
array_desc_t * array_descs
Definition: vbscript.h:109
unsigned prop_cnt
Definition: vbscript.h:105
vbdisp_prop_desc_t * props
Definition: vbscript.h:106
vbdisp_funcprop_desc_t * funcs
Definition: vbscript.h:103
unsigned class_terminate_id
Definition: vbscript.h:101
unsigned class_initialize_id
Definition: vbscript.h:100
unsigned func_cnt
Definition: vbscript.h:102
struct _class_desc_t * next
Definition: vbscript.h:113
const WCHAR * name
Definition: vbscript.h:97
unsigned array_cnt
Definition: vbscript.h:108
struct _dim_decl_t * next
Definition: parse.h:154
const WCHAR * name
Definition: parse.h:150
BOOL is_public
Definition: parse.h:152
BOOL is_array
Definition: parse.h:151
struct _function_decl_t * next_prop_func
Definition: parse.h:175
const WCHAR * name
Definition: parse.h:169
struct _function_decl_t * next
Definition: parse.h:174
function_type_t type
Definition: parse.h:170
const WCHAR * name
Definition: vbscript.h:86
static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1002
static HRESULT fill_array_desc(compile_ctx_t *ctx, dim_decl_t *dim_decl, array_desc_t *array_desc)
Definition: compile.c:1333
static BOOL lookup_class_funcs(class_desc_t *class_desc, const WCHAR *name)
Definition: compile.c:1589
static expression_t * lookup_const_decls(compile_ctx_t *ctx, const WCHAR *name, BOOL lookup_global)
Definition: compile.c:390
static BOOL lookup_class_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1537
static void * compiler_alloc_zero(vbscode_t *vbscode, size_t size)
Definition: compile.c:124
static HRESULT create_class_funcprop(compile_ctx_t *ctx, function_decl_t *func_decl, vbdisp_funcprop_desc_t *desc)
Definition: compile.c:1549
static BOOL lookup_funcs_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1470
@ FUNC_SUB
Definition: vbscript.h:310
@ FUNC_DEFGET
Definition: vbscript.h:314
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by compile_script().

◆ compile_const_statement()

static HRESULT compile_const_statement ( compile_ctx_t ctx,
const_statement_t stat 
)
static

Definition at line 1061 of file compile.c.

1062{
1063 const_decl_t *decl, *next_decl = stat->decls;
1064
1065 do {
1066 decl = next_decl;
1067
1069 || lookup_dim_decls(ctx, decl->name)) {
1070 FIXME("%s redefined\n", debugstr_w(decl->name));
1071 return E_FAIL;
1072 }
1073
1074 if(ctx->func->type == FUNC_GLOBAL) {
1075 HRESULT hres;
1076
1078 if(FAILED(hres))
1079 return hres;
1080
1081 hres = push_instr_bstr(ctx, OP_const, decl->name);
1082 if(FAILED(hres))
1083 return hres;
1084
1085 if(!emit_catch(ctx, 0))
1086 return E_OUTOFMEMORY;
1087 }
1088
1089 next_decl = decl->next;
1090 decl->next = ctx->const_decls;
1091 ctx->const_decls = decl;
1092 } while(next_decl);
1093
1094 return S_OK;
1095}
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
const WCHAR * name
Definition: parse.h:232
struct _const_decl_t * next
Definition: parse.h:234
expression_t * value_expr
Definition: parse.h:233
static BOOL lookup_args_name(compile_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1014

Referenced by compile_statement().

◆ compile_dim_statement()

static HRESULT compile_dim_statement ( compile_ctx_t ctx,
dim_statement_t stat 
)
static

Definition at line 1026 of file compile.c.

1027{
1028 dim_decl_t *dim_decl = stat->dim_decls;
1029
1030 while(1) {
1031 if(lookup_dim_decls(ctx, dim_decl->name) || lookup_args_name(ctx, dim_decl->name)
1032 || lookup_const_decls(ctx, dim_decl->name, FALSE)) {
1033 FIXME("dim %s name redefined\n", debugstr_w(dim_decl->name));
1034 return E_FAIL;
1035 }
1036
1037 ctx->func->var_cnt++;
1038
1039 if(dim_decl->is_array) {
1040 HRESULT hres = push_instr_bstr_uint(ctx, OP_dim, dim_decl->name, ctx->func->array_cnt++);
1041 if(FAILED(hres))
1042 return hres;
1043
1044 if(!emit_catch(ctx, 0))
1045 return E_OUTOFMEMORY;
1046 }
1047
1048 if(!dim_decl->next)
1049 break;
1050 dim_decl = dim_decl->next;
1051 }
1052
1053 if(ctx->dim_decls_tail)
1054 ctx->dim_decls_tail->next = stat->dim_decls;
1055 else
1056 ctx->dim_decls = stat->dim_decls;
1057 ctx->dim_decls_tail = dim_decl;
1058 return S_OK;
1059}

Referenced by compile_statement().

◆ compile_dowhile_statement()

static HRESULT compile_dowhile_statement ( compile_ctx_t ctx,
while_statement_t stat 
)
static

Definition at line 674 of file compile.c.

675{
676 statement_ctx_t loop_ctx = {0};
677 unsigned start_addr;
678 vbsop_t jmp_op;
680
681 start_addr = ctx->instr_cnt;
682
683 if(!(loop_ctx.while_end_label = alloc_label(ctx)))
684 return E_OUTOFMEMORY;
685
686 hres = compile_statement(ctx, &loop_ctx, stat->body);
687 if(FAILED(hres))
688 return hres;
689
690 if(stat->expr) {
692 if(FAILED(hres))
693 return hres;
694
695 jmp_op = stat->stat.type == STAT_DOUNTIL ? OP_jmp_false : OP_jmp_true;
696 }else {
697 jmp_op = OP_jmp;
698 }
699
700 hres = push_instr_addr(ctx, jmp_op, start_addr);
701 if(FAILED(hres))
702 return hres;
703
705
706 if(!emit_catch(ctx, 0))
707 return E_OUTOFMEMORY;
708
709 return S_OK;
710}
@ STAT_DOUNTIL
Definition: parse.h:106
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
unsigned while_end_label
Definition: compile.c:33
static HRESULT push_instr_addr(compile_ctx_t *ctx, vbsop_t op, unsigned arg)
Definition: compile.c:195

Referenced by compile_statement().

◆ compile_error()

static HRESULT compile_error ( script_ctx_t ctx,
HRESULT  error 
)
static

Definition at line 378 of file compile.c.

379{
380 if(error == SCRIPT_E_REPORTED)
381 return error;
382
383 clear_ei(&ctx->ei);
384 ctx->ei.scode = error = map_hres(error);
385 ctx->ei.bstrSource = get_vbscript_string(VBS_COMPILE_ERROR);
386 ctx->ei.bstrDescription = get_vbscript_error_string(error);
387 return report_script_error(ctx);
388}
HRESULT report_script_error(script_ctx_t *ctx)
Definition: vbscript.c:315
#define VBS_COMPILE_ERROR
void clear_ei(script_ctx_t *ctx)
Definition: engine.c:430
#define error(str)
Definition: mkdosfs.c:1605
HRESULT map_hres
Definition: sec_mgr.c:1753
BSTR get_vbscript_error_string(HRESULT) DECLSPEC_HIDDEN
Definition: vbscript_main.c:45
BSTR get_vbscript_string(int) DECLSPEC_HIDDEN
Definition: vbscript_main.c:38

Referenced by compile_script().

◆ compile_exitdo_statement()

static HRESULT compile_exitdo_statement ( compile_ctx_t ctx)
static

Definition at line 1109 of file compile.c.

1110{
1111 statement_ctx_t *iter;
1112 unsigned pop_cnt = 0;
1113
1114 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1115 pop_cnt += iter->stack_use;
1116 if(iter->while_end_label)
1117 break;
1118 }
1119 if(!iter) {
1120 FIXME("Exit Do outside Do Loop\n");
1121 return E_FAIL;
1122 }
1123
1124 if(pop_cnt) {
1125 HRESULT hres;
1126
1127 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1128 if(FAILED(hres))
1129 return hres;
1130 }
1131
1132 return push_instr_addr(ctx, OP_jmp, iter->while_end_label);
1133}
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
unsigned stack_use
Definition: compile.c:33
struct _statement_ctx_t * next
Definition: compile.c:42

Referenced by compile_statement().

◆ compile_exitfor_statement()

static HRESULT compile_exitfor_statement ( compile_ctx_t ctx)
static

Definition at line 1135 of file compile.c.

1136{
1137 statement_ctx_t *iter;
1138 unsigned pop_cnt = 0;
1139
1140 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1141 pop_cnt += iter->stack_use;
1142 if(iter->for_end_label)
1143 break;
1144 }
1145 if(!iter) {
1146 FIXME("Exit For outside For loop\n");
1147 return E_FAIL;
1148 }
1149
1150 if(pop_cnt) {
1151 HRESULT hres;
1152
1153 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1154 if(FAILED(hres))
1155 return hres;
1156 }
1157
1158 return push_instr_addr(ctx, OP_jmp, iter->for_end_label);
1159}
unsigned for_end_label
Definition: compile.c:34

Referenced by compile_statement().

◆ compile_exitfunc_statement()

static HRESULT compile_exitfunc_statement ( compile_ctx_t ctx)
static

Definition at line 1186 of file compile.c.

1187{
1188 if(!ctx->func_end_label) {
1189 FIXME("Exit Function outside Function?\n");
1190 return E_FAIL;
1191 }
1192
1193 return exit_label(ctx, ctx->func_end_label);
1194}
static HRESULT exit_label(compile_ctx_t *ctx, unsigned jmp_label)
Definition: compile.c:1161

Referenced by compile_statement().

◆ compile_exitprop_statement()

static HRESULT compile_exitprop_statement ( compile_ctx_t ctx)
static

Definition at line 1196 of file compile.c.

1197{
1198 if(!ctx->prop_end_label) {
1199 FIXME("Exit Property outside Property?\n");
1200 return E_FAIL;
1201 }
1202
1203 return exit_label(ctx, ctx->prop_end_label);
1204}

Referenced by compile_statement().

◆ compile_exitsub_statement()

static HRESULT compile_exitsub_statement ( compile_ctx_t ctx)
static

Definition at line 1176 of file compile.c.

1177{
1178 if(!ctx->sub_end_label) {
1179 FIXME("Exit Sub outside Sub?\n");
1180 return E_FAIL;
1181 }
1182
1183 return exit_label(ctx, ctx->sub_end_label);
1184}

Referenced by compile_statement().

◆ compile_expression()

static HRESULT compile_expression ( compile_ctx_t ctx,
expression_t expr 
)
static

Definition at line 484 of file compile.c.

485{
486 switch(expr->type) {
487 case EXPR_ADD:
489 case EXPR_AND:
491 case EXPR_BOOL:
492 return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
493 case EXPR_BRACKETS:
494 return compile_expression(ctx, ((unary_expression_t*)expr)->subexpr);
495 case EXPR_CONCAT:
497 case EXPR_DIV:
499 case EXPR_DOUBLE:
500 return push_instr_double(ctx, OP_double, ((double_expression_t*)expr)->value);
501 case EXPR_EMPTY:
502 return push_instr(ctx, OP_empty) ? S_OK : E_OUTOFMEMORY;
503 case EXPR_EQUAL:
505 case EXPR_EQV:
507 case EXPR_EXP:
509 case EXPR_GT:
511 case EXPR_GTEQ:
513 case EXPR_IDIV:
515 case EXPR_IS:
517 case EXPR_IMP:
519 case EXPR_LT:
521 case EXPR_LTEQ:
523 case EXPR_ME:
524 return push_instr(ctx, OP_me) ? S_OK : E_OUTOFMEMORY;
525 case EXPR_MEMBER:
527 case EXPR_MOD:
529 case EXPR_MUL:
531 case EXPR_NEG:
533 case EXPR_NEQUAL:
535 case EXPR_NEW:
536 return push_instr_str(ctx, OP_new, ((string_expression_t*)expr)->value);
537 case EXPR_NOARG:
538 return push_instr_int(ctx, OP_hres, DISP_E_PARAMNOTFOUND);
539 case EXPR_NOT:
541 case EXPR_NOTHING:
542 return push_instr(ctx, OP_nothing) ? S_OK : E_OUTOFMEMORY;
543 case EXPR_NULL:
544 return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
545 case EXPR_OR:
547 case EXPR_STRING:
548 return push_instr_str(ctx, OP_string, ((string_expression_t*)expr)->value);
549 case EXPR_SUB:
551 case EXPR_INT:
552 return push_instr_int(ctx, OP_int, ((int_expression_t*)expr)->value);
553 case EXPR_XOR:
555 default:
556 FIXME("Unimplemented expression type %d\n", expr->type);
557 return E_NOTIMPL;
558 }
559
560 return S_OK;
561}
#define E_NOTIMPL
Definition: ddrawi.h:99
#define TRUE
Definition: types.h:120
@ EXPR_MEMBER
Definition: parser.h:266
@ EXPR_MOD
Definition: parser.h:229
@ EXPR_NEW
Definition: parser.h:267
@ EXPR_DIV
Definition: parser.h:228
@ EXPR_ADD
Definition: parser.h:225
@ EXPR_MUL
Definition: parser.h:227
@ EXPR_OR
Definition: parser.h:218
@ EXPR_SUB
Definition: parser.h:226
@ EXPR_AND
Definition: parser.h:219
@ EXPR_LT
Definition: parse.h:39
@ EXPR_NULL
Definition: parse.h:51
@ EXPR_EQV
Definition: parse.h:31
@ EXPR_EXP
Definition: parse.h:32
@ EXPR_NOTHING
Definition: parse.h:50
@ EXPR_IDIV
Definition: parse.h:35
@ EXPR_DOUBLE
Definition: parse.h:28
@ EXPR_IS
Definition: parse.h:38
@ EXPR_EMPTY
Definition: parse.h:29
@ EXPR_IMP
Definition: parse.h:36
@ EXPR_NEG
Definition: parse.h:45
@ EXPR_CONCAT
Definition: parse.h:26
@ EXPR_ME
Definition: parse.h:41
@ EXPR_INT
Definition: parse.h:37
@ EXPR_NEQUAL
Definition: parse.h:46
@ EXPR_STRING
Definition: parse.h:53
@ EXPR_NOT
Definition: parse.h:49
@ EXPR_GTEQ
Definition: parse.h:34
@ EXPR_NOARG
Definition: parse.h:48
@ EXPR_BOOL
Definition: parse.h:24
@ EXPR_LTEQ
Definition: parse.h:40
@ EXPR_GT
Definition: parse.h:33
@ EXPR_XOR
Definition: parse.h:55
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:355
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:326
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:370
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:248
int type
Definition: query.h:87
Definition: pdh_main.c:94
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513

◆ compile_foreach_statement()

static HRESULT compile_foreach_statement ( compile_ctx_t ctx,
foreach_statement_t stat 
)
static

Definition at line 712 of file compile.c.

713{
714 statement_ctx_t loop_ctx = {1};
715 unsigned loop_start;
717
718 /* Preserve a place on the stack in case we throw before having proper enum collection. */
719 if(!push_instr(ctx, OP_empty))
720 return E_OUTOFMEMORY;
721
722 hres = compile_expression(ctx, stat->group_expr);
723 if(FAILED(hres))
724 return hres;
725
726 if(!push_instr(ctx, OP_newenum))
727 return E_OUTOFMEMORY;
728
729 if(!(loop_ctx.for_end_label = alloc_label(ctx)))
730 return E_OUTOFMEMORY;
731
732 hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
733 if(FAILED(hres))
734 return hres;
735
736 if(!emit_catch(ctx, 1))
737 return E_OUTOFMEMORY;
738
739 loop_start = ctx->instr_cnt;
740 hres = compile_statement(ctx, &loop_ctx, stat->body);
741 if(FAILED(hres))
742 return hres;
743
744 /* We need a separated enumnext here, because we need to jump out of the loop on exception. */
745 hres = push_instr_uint_bstr(ctx, OP_enumnext, loop_ctx.for_end_label, stat->identifier);
746 if(FAILED(hres))
747 return hres;
748
749 hres = push_instr_addr(ctx, OP_jmp, loop_start);
750 if(FAILED(hres))
751 return hres;
752
754 return S_OK;
755}
static HRESULT push_instr_uint_bstr(compile_ctx_t *ctx, vbsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:302

Referenced by compile_statement().

◆ compile_forto_statement()

static HRESULT compile_forto_statement ( compile_ctx_t ctx,
forto_statement_t stat 
)
static

Definition at line 757 of file compile.c.

758{
759 statement_ctx_t loop_ctx = {2};
760 unsigned step_instr, instr;
761 BSTR identifier;
763
764 identifier = alloc_bstr_arg(ctx, stat->identifier);
765 if(!identifier)
766 return E_OUTOFMEMORY;
767
768 hres = compile_expression(ctx, stat->from_expr);
769 if(FAILED(hres))
770 return hres;
771
772 /* FIXME: Assign should happen after both expressions evaluation. */
773 instr = push_instr(ctx, OP_assign_ident);
774 if(!instr)
775 return E_OUTOFMEMORY;
776 instr_ptr(ctx, instr)->arg1.bstr = identifier;
777 instr_ptr(ctx, instr)->arg2.uint = 0;
778
779 hres = compile_expression(ctx, stat->to_expr);
780 if(FAILED(hres))
781 return hres;
782
783 if(!push_instr(ctx, OP_val))
784 return E_OUTOFMEMORY;
785
786 if(stat->step_expr) {
787 hres = compile_expression(ctx, stat->step_expr);
788 if(FAILED(hres))
789 return hres;
790
791 if(!push_instr(ctx, OP_val))
792 return E_OUTOFMEMORY;
793 }else {
794 hres = push_instr_int(ctx, OP_int, 1);
795 if(FAILED(hres))
796 return hres;
797 }
798
799 loop_ctx.for_end_label = alloc_label(ctx);
800 if(!loop_ctx.for_end_label)
801 return E_OUTOFMEMORY;
802
803 step_instr = push_instr(ctx, OP_step);
804 if(!step_instr)
805 return E_OUTOFMEMORY;
806 instr_ptr(ctx, step_instr)->arg2.bstr = identifier;
807 instr_ptr(ctx, step_instr)->arg1.uint = loop_ctx.for_end_label;
808
809 if(!emit_catch(ctx, 2))
810 return E_OUTOFMEMORY;
811
812 hres = compile_statement(ctx, &loop_ctx, stat->body);
813 if(FAILED(hres))
814 return hres;
815
816 /* FIXME: Error handling can't be done compatible with native using OP_incc here. */
817 instr = push_instr(ctx, OP_incc);
818 if(!instr)
819 return E_OUTOFMEMORY;
820 instr_ptr(ctx, instr)->arg1.bstr = identifier;
821
822 hres = push_instr_addr(ctx, OP_jmp, step_instr);
823 if(FAILED(hres))
824 return hres;
825
826 hres = push_instr_uint(ctx, OP_pop, 2);
827 if(FAILED(hres))
828 return hres;
829
831
832 /* FIXME: reconsider after OP_incc fixup. */
833 if(!emit_catch(ctx, 0))
834 return E_OUTOFMEMORY;
835
836 return S_OK;
837}
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
instr_arg_t arg2
Definition: vbscript.h:299
instr_arg_t arg1
Definition: vbscript.h:298
unsigned uint
Definition: engine.h:112
BSTR bstr
Definition: engine.h:109
static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:242

Referenced by compile_statement().

◆ compile_func()

static HRESULT compile_func ( compile_ctx_t ctx,
statement_t stat,
function_t func 
)
static

Definition at line 1355 of file compile.c.

1356{
1357 HRESULT hres;
1358
1359 func->code_off = ctx->instr_cnt;
1360
1361 ctx->sub_end_label = 0;
1362 ctx->func_end_label = 0;
1363 ctx->prop_end_label = 0;
1364
1365 switch(func->type) {
1366 case FUNC_FUNCTION:
1367 ctx->func_end_label = alloc_label(ctx);
1368 if(!ctx->func_end_label)
1369 return E_OUTOFMEMORY;
1370 break;
1371 case FUNC_SUB:
1372 ctx->sub_end_label = alloc_label(ctx);
1373 if(!ctx->sub_end_label)
1374 return E_OUTOFMEMORY;
1375 break;
1376 case FUNC_PROPGET:
1377 case FUNC_PROPLET:
1378 case FUNC_PROPSET:
1379 case FUNC_DEFGET:
1380 ctx->prop_end_label = alloc_label(ctx);
1381 if(!ctx->prop_end_label)
1382 return E_OUTOFMEMORY;
1383 break;
1384 case FUNC_GLOBAL:
1385 break;
1386 }
1387
1388 ctx->func = func;
1389 ctx->dim_decls = ctx->dim_decls_tail = NULL;
1390 ctx->const_decls = NULL;
1392 ctx->func = NULL;
1393 if(FAILED(hres))
1394 return hres;
1395
1396 if(ctx->sub_end_label)
1397 label_set_addr(ctx, ctx->sub_end_label);
1398 if(ctx->func_end_label)
1399 label_set_addr(ctx, ctx->func_end_label);
1400 if(ctx->prop_end_label)
1401 label_set_addr(ctx, ctx->prop_end_label);
1402
1403 if(!push_instr(ctx, OP_ret))
1404 return E_OUTOFMEMORY;
1405
1406 resolve_labels(ctx, func->code_off);
1407
1408 if(func->var_cnt) {
1409 dim_decl_t *dim_decl;
1410
1411 if(func->type == FUNC_GLOBAL) {
1412 dynamic_var_t *new_var;
1413
1414 func->var_cnt = 0;
1415
1416 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1417 new_var = compiler_alloc(ctx->code, sizeof(*new_var));
1418 if(!new_var)
1419 return E_OUTOFMEMORY;
1420
1421 new_var->name = compiler_alloc_string(ctx->code, dim_decl->name);
1422 if(!new_var->name)
1423 return E_OUTOFMEMORY;
1424
1425 V_VT(&new_var->v) = VT_EMPTY;
1426 new_var->is_const = FALSE;
1427
1428 new_var->next = ctx->global_vars;
1429 ctx->global_vars = new_var;
1430 }
1431 }else {
1432 unsigned i;
1433
1434 func->vars = compiler_alloc(ctx->code, func->var_cnt * sizeof(var_desc_t));
1435 if(!func->vars)
1436 return E_OUTOFMEMORY;
1437
1438 for(dim_decl = ctx->dim_decls, i=0; dim_decl; dim_decl = dim_decl->next, i++) {
1439 func->vars[i].name = compiler_alloc_string(ctx->code, dim_decl->name);
1440 if(!func->vars[i].name)
1441 return E_OUTOFMEMORY;
1442 }
1443
1444 assert(i == func->var_cnt);
1445 }
1446 }
1447
1448 if(func->array_cnt) {
1449 unsigned array_id = 0;
1450 dim_decl_t *dim_decl;
1451
1452 func->array_descs = compiler_alloc(ctx->code, func->array_cnt * sizeof(array_desc_t));
1453 if(!func->array_descs)
1454 return E_OUTOFMEMORY;
1455
1456 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1457 if(dim_decl->is_array) {
1458 hres = fill_array_desc(ctx, dim_decl, func->array_descs + array_id++);
1459 if(FAILED(hres))
1460 return hres;
1461 }
1462 }
1463
1464 assert(array_id == func->array_cnt);
1465 }
1466
1467 return S_OK;
1468}
@ VT_EMPTY
Definition: compat.h:2295
#define assert(x)
Definition: debug.h:53
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2211
#define V_VT(A)
Definition: oleauto.h:211
VARIANT v
Definition: vbscript.h:174
const WCHAR * name
Definition: vbscript.h:175
struct _dynamic_var_t * next
Definition: vbscript.h:173
char * name
Definition: compiler.c:66
@ FUNC_PROPLET
Definition: vbscript.h:312
@ FUNC_PROPSET
Definition: vbscript.h:313
@ FUNC_PROPGET
Definition: vbscript.h:311
@ FUNC_FUNCTION
Definition: vbscript.h:309

Referenced by compile_script(), and create_function().

◆ compile_function_statement()

static HRESULT compile_function_statement ( compile_ctx_t ctx,
function_statement_t stat 
)
static

Definition at line 1097 of file compile.c.

1098{
1099 if(ctx->func != &ctx->code->main_code) {
1100 FIXME("Function is not in the global code\n");
1101 return E_FAIL;
1102 }
1103
1104 stat->func_decl->next = ctx->func_decls;
1105 ctx->func_decls = stat->func_decl;
1106 return S_OK;
1107}

Referenced by compile_statement().

◆ compile_if_statement()

static HRESULT compile_if_statement ( compile_ctx_t ctx,
if_statement_t stat 
)
static

Definition at line 563 of file compile.c.

564{
565 unsigned cnd_jmp, endif_label = 0;
566 elseif_decl_t *elseif_decl;
568
570 if(FAILED(hres))
571 return hres;
572
573 cnd_jmp = push_instr(ctx, OP_jmp_false);
574 if(!cnd_jmp)
575 return E_OUTOFMEMORY;
576
577 if(!emit_catch(ctx, 0))
578 return E_OUTOFMEMORY;
579
580 hres = compile_statement(ctx, NULL, stat->if_stat);
581 if(FAILED(hres))
582 return hres;
583
584 if(stat->else_stat || stat->elseifs) {
585 endif_label = alloc_label(ctx);
586 if(!endif_label)
587 return E_OUTOFMEMORY;
588
589 hres = push_instr_addr(ctx, OP_jmp, endif_label);
590 if(FAILED(hres))
591 return hres;
592 }
593
594 for(elseif_decl = stat->elseifs; elseif_decl; elseif_decl = elseif_decl->next) {
595 instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
596
597 hres = compile_expression(ctx, elseif_decl->expr);
598 if(FAILED(hres))
599 return hres;
600
601 cnd_jmp = push_instr(ctx, OP_jmp_false);
602 if(!cnd_jmp)
603 return E_OUTOFMEMORY;
604
605 if(!emit_catch(ctx, 0))
606 return E_OUTOFMEMORY;
607
608 hres = compile_statement(ctx, NULL, elseif_decl->stat);
609 if(FAILED(hres))
610 return hres;
611
612 hres = push_instr_addr(ctx, OP_jmp, endif_label);
613 if(FAILED(hres))
614 return hres;
615 }
616
617 instr_ptr(ctx, cnd_jmp)->arg1.uint = ctx->instr_cnt;
618
619 if(stat->else_stat) {
620 hres = compile_statement(ctx, NULL, stat->else_stat);
621 if(FAILED(hres))
622 return hres;
623 }
624
625 if(endif_label)
626 label_set_addr(ctx, endif_label);
627 return S_OK;
628}
statement_t * stat
Definition: parse.h:192
expression_t * expr
Definition: parse.h:191
struct _elseif_decl_t * next
Definition: parse.h:193

◆ compile_member_expression()

static HRESULT compile_member_expression ( compile_ctx_t ctx,
member_expression_t expr,
BOOL  ret_val 
)
static

Definition at line 428 of file compile.c.

429{
430 unsigned arg_cnt = 0;
432
433 if(ret_val && !expr->args) {
434 expression_t *const_expr;
435
436 const_expr = lookup_const_decls(ctx, expr->identifier, TRUE);
437 if(const_expr)
438 return compile_expression(ctx, const_expr);
439 }
440
441 hres = compile_args(ctx, expr->args, &arg_cnt);
442 if(FAILED(hres))
443 return hres;
444
445 if(expr->obj_expr) {
446 hres = compile_expression(ctx, expr->obj_expr);
447 if(FAILED(hres))
448 return hres;
449
450 hres = push_instr_bstr_uint(ctx, ret_val ? OP_mcall : OP_mcallv, expr->identifier, arg_cnt);
451 }else {
452 hres = push_instr_bstr_uint(ctx, ret_val ? OP_icall : OP_icallv, expr->identifier, arg_cnt);
453 }
454
455 return hres;
456}

◆ compile_onerror_statement()

static HRESULT compile_onerror_statement ( compile_ctx_t ctx,
onerror_statement_t stat 
)
static

Definition at line 1206 of file compile.c.

1207{
1208 return push_instr_int(ctx, OP_errmode, stat->resume_next);
1209}

Referenced by compile_statement().

◆ compile_procedure()

HRESULT compile_procedure ( script_ctx_t script,
const WCHAR src,
const WCHAR delimiter,
DWORD  flags,
class_desc_t **  ret 
)

Definition at line 1930 of file compile.c.

1931{
1933 vbscode_t *code;
1934 HRESULT hres;
1935
1937 if(FAILED(hres))
1938 return hres;
1939
1940 if(!(desc = compiler_alloc_zero(code, sizeof(*desc))))
1941 return E_OUTOFMEMORY;
1942 if(!(desc->funcs = compiler_alloc_zero(code, sizeof(*desc->funcs))))
1943 return E_OUTOFMEMORY;
1944
1945 desc->ctx = script;
1946 desc->func_cnt = 1;
1947 desc->funcs->entries[VBDISP_CALLGET] = &code->main_code;
1948
1949 desc->next = script->procs;
1950 script->procs = desc;
1951
1952 *ret = desc;
1953 return S_OK;
1954}
GLenum src
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
static const WCHAR desc[]
Definition: protectdata.c:36
const char * delimiter
Definition: string.c:1566
Definition: inflate.c:139
HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *delimiter, DWORD flags, vbscode_t **ret)
Definition: compile.c:1828
@ VBDISP_CALLGET
Definition: vbscript.h:72

Referenced by VBScriptParseProcedure_ParseProcedureText().

◆ compile_retval_statement()

static HRESULT compile_retval_statement ( compile_ctx_t ctx,
retval_statement_t stat 
)
static

Definition at line 1211 of file compile.c.

1212{
1213 HRESULT hres;
1214
1215 hres = compile_expression(ctx, stat->expr);
1216 if(FAILED(hres))
1217 return hres;
1218
1219 hres = push_instr(ctx, OP_retval);
1220 if(FAILED(hres))
1221 return hres;
1222
1223 return S_OK;
1224}

Referenced by compile_statement().

◆ compile_script()

HRESULT compile_script ( script_ctx_t script,
const WCHAR src,
const WCHAR delimiter,
DWORD  flags,
vbscode_t **  ret 
)

Definition at line 1828 of file compile.c.

1829{
1830 function_t *new_func;
1831 function_decl_t *func_decl;
1832 class_decl_t *class_decl;
1834 vbscode_t *code;
1835 HRESULT hres;
1836
1837 if (!src) src = L"";
1838
1839 hres = parse_script(&ctx.parser, src, delimiter, flags);
1840 if(FAILED(hres))
1841 return compile_error(script, hres);
1842
1843 code = ctx.code = alloc_vbscode(&ctx, src);
1844 if(!ctx.code)
1846
1847 ctx.funcs = NULL;
1848 ctx.func_decls = NULL;
1849 ctx.global_vars = NULL;
1850 ctx.classes = NULL;
1851 ctx.labels = NULL;
1852 ctx.global_consts = NULL;
1853 ctx.stat_ctx = NULL;
1854 ctx.labels_cnt = ctx.labels_size = 0;
1855
1856 hres = compile_func(&ctx, ctx.parser.stats, &ctx.code->main_code);
1857 if(FAILED(hres)) {
1859 return compile_error(script, hres);
1860 }
1861
1862 ctx.global_consts = ctx.const_decls;
1863
1864 for(func_decl = ctx.func_decls; func_decl; func_decl = func_decl->next) {
1865 hres = create_function(&ctx, func_decl, &new_func);
1866 if(FAILED(hres)) {
1868 return compile_error(script, hres);
1869 }
1870
1871 new_func->next = ctx.funcs;
1872 ctx.funcs = new_func;
1873 }
1874
1875 for(class_decl = ctx.parser.class_decls; class_decl; class_decl = class_decl->next) {
1876 hres = compile_class(&ctx, class_decl);
1877 if(FAILED(hres)) {
1879 return compile_error(script, hres);
1880 }
1881 }
1882
1884 if(FAILED(hres)) {
1886 return compile_error(script, hres);
1887 }
1888
1889 if(ctx.global_vars) {
1891
1892 for(var = ctx.global_vars; var->next; var = var->next);
1893
1894 var->next = script->global_vars;
1895 script->global_vars = ctx.global_vars;
1896 }
1897
1898 if(ctx.funcs) {
1899 for(new_func = ctx.funcs; new_func->next; new_func = new_func->next);
1900
1901 new_func->next = script->global_funcs;
1902 script->global_funcs = ctx.funcs;
1903 }
1904
1905 if(ctx.classes) {
1906 class_desc_t *class = ctx.classes;
1907
1908 while(1) {
1909 class->ctx = script;
1910 if(!class->next)
1911 break;
1912 class = class->next;
1913 }
1914
1915 class->next = script->classes;
1916 script->classes = ctx.classes;
1917 }
1918
1919 if(TRACE_ON(vbscript_disas))
1920 dump_code(&ctx);
1921
1922 ctx.code = NULL;
1924
1925 list_add_tail(&script->code_list, &code->entry);
1926 *ret = code;
1927 return S_OK;
1928}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define TRACE_ON(x)
Definition: compat.h:75
HRESULT parse_script(parser_ctx_t *, const WCHAR *, const WCHAR *, DWORD) DECLSPEC_HIDDEN
static void dump_code(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:109
#define L(x)
Definition: ntvdm.h:50
static unsigned __int64 next
Definition: rand_nt.c:6
struct _class_decl_t * next
Definition: parse.h:187
script_ctx_t * ctx
Definition: vbscript.h:98
function_t * next
Definition: vbscript.h:333
static void release_compiler(compile_ctx_t *ctx)
Definition: compile.c:1820
static vbscode_t * alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
Definition: compile.c:1787
static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
Definition: compile.c:1601
static HRESULT compile_error(script_ctx_t *ctx, HRESULT error)
Definition: compile.c:378
static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *func)
Definition: compile.c:1355
static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script)
Definition: compile.c:1738
static HRESULT create_function(compile_ctx_t *ctx, function_decl_t *decl, function_t **ret)
Definition: compile.c:1482

◆ compile_select_statement()

static HRESULT compile_select_statement ( compile_ctx_t ctx,
select_statement_t stat 
)
static

Definition at line 839 of file compile.c.

840{
841 unsigned end_label, case_cnt = 0, *case_labels = NULL, i;
842 case_clausule_t *case_iter;
843 expression_t *expr_iter;
845
847 if(FAILED(hres))
848 return hres;
849
850 if(!push_instr(ctx, OP_val))
851 return E_OUTOFMEMORY;
852
853 end_label = alloc_label(ctx);
854 if(!end_label)
855 return E_OUTOFMEMORY;
856
857 if(!emit_catch_jmp(ctx, 0, end_label))
858 return E_OUTOFMEMORY;
859
860 for(case_iter = stat->case_clausules; case_iter; case_iter = case_iter->next)
861 case_cnt++;
862
863 if(case_cnt) {
864 case_labels = heap_alloc(case_cnt*sizeof(*case_labels));
865 if(!case_labels)
866 return E_OUTOFMEMORY;
867 }
868
869 for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
870 case_labels[i] = alloc_label(ctx);
871 if(!case_labels[i]) {
873 break;
874 }
875
876 if(!case_iter->expr)
877 break;
878
879 for(expr_iter = case_iter->expr; expr_iter; expr_iter = expr_iter->next) {
880 hres = compile_expression(ctx, expr_iter);
881 if(FAILED(hres))
882 break;
883
884 hres = push_instr_addr(ctx, OP_case, case_labels[i]);
885 if(FAILED(hres))
886 break;
887
888 if(!emit_catch_jmp(ctx, 0, case_labels[i])) {
890 break;
891 }
892 }
893 }
894
895 if(FAILED(hres)) {
896 heap_free(case_labels);
897 return hres;
898 }
899
900 hres = push_instr_uint(ctx, OP_pop, 1);
901 if(FAILED(hres)) {
902 heap_free(case_labels);
903 return hres;
904 }
905
906 hres = push_instr_addr(ctx, OP_jmp, case_iter ? case_labels[i] : end_label);
907 if(FAILED(hres)) {
908 heap_free(case_labels);
909 return hres;
910 }
911
912 for(case_iter = stat->case_clausules, i=0; case_iter; case_iter = case_iter->next, i++) {
913 label_set_addr(ctx, case_labels[i]);
914 hres = compile_statement(ctx, NULL, case_iter->stat);
915 if(FAILED(hres))
916 break;
917
918 if(!case_iter->next)
919 break;
920
921 hres = push_instr_addr(ctx, OP_jmp, end_label);
922 if(FAILED(hres))
923 break;
924 }
925
926 heap_free(case_labels);
927 if(FAILED(hres))
928 return hres;
929
930 label_set_addr(ctx, end_label);
931 return S_OK;
932}
struct _case_clausule_t * next
Definition: parser.h:195
statement_t * stat
Definition: parser.h:193
expression_t * expr
Definition: parser.h:192
struct _expression_t * next
Definition: parse.h:60
static BOOL emit_catch_jmp(compile_ctx_t *ctx, unsigned stack_off, unsigned code_off)
Definition: compile.c:360

Referenced by compile_statement().

◆ compile_statement()

static HRESULT compile_statement ( compile_ctx_t ctx,
statement_ctx_t stat_ctx,
statement_t stat 
)
static

Definition at line 1226 of file compile.c.

1227{
1228 HRESULT hres;
1229
1230 if(stat_ctx) {
1231 stat_ctx->next = ctx->stat_ctx;
1232 ctx->stat_ctx = stat_ctx;
1233 }
1234
1235 while(stat) {
1236 switch(stat->type) {
1237 case STAT_ASSIGN:
1239 break;
1240 case STAT_CALL:
1242 break;
1243 case STAT_CONST:
1245 break;
1246 case STAT_DIM:
1248 break;
1249 case STAT_DOWHILE:
1250 case STAT_DOUNTIL:
1252 break;
1253 case STAT_EXITDO:
1255 break;
1256 case STAT_EXITFOR:
1258 break;
1259 case STAT_EXITFUNC:
1261 break;
1262 case STAT_EXITPROP:
1264 break;
1265 case STAT_EXITSUB:
1267 break;
1268 case STAT_FOREACH:
1270 break;
1271 case STAT_FORTO:
1273 break;
1274 case STAT_FUNC:
1276 break;
1277 case STAT_IF:
1279 break;
1280 case STAT_ONERROR:
1282 break;
1283 case STAT_SELECT:
1285 break;
1286 case STAT_SET:
1288 break;
1289 case STAT_STOP:
1290 hres = push_instr(ctx, OP_stop) ? S_OK : E_OUTOFMEMORY;
1291 break;
1292 case STAT_UNTIL:
1293 case STAT_WHILE:
1294 case STAT_WHILELOOP:
1296 break;
1297 case STAT_RETVAL:
1299 break;
1300 default:
1301 FIXME("Unimplemented statement type %d\n", stat->type);
1302 hres = E_NOTIMPL;
1303 }
1304
1305 if(FAILED(hres))
1306 return hres;
1307 stat = stat->next;
1308 }
1309
1310 if(stat_ctx) {
1311 assert(ctx->stat_ctx == stat_ctx);
1312 ctx->stat_ctx = stat_ctx->next;
1313 }
1314
1315 return S_OK;
1316}
@ STAT_IF
Definition: parser.h:112
@ STAT_WHILE
Definition: parser.h:119
@ STAT_EXITPROP
Definition: parse.h:111
@ STAT_UNTIL
Definition: parse.h:121
@ STAT_RETVAL
Definition: parse.h:124
@ STAT_ASSIGN
Definition: parse.h:102
@ STAT_CALL
Definition: parse.h:103
@ STAT_STOP
Definition: parse.h:120
@ STAT_EXITDO
Definition: parse.h:108
@ STAT_DIM
Definition: parse.h:105
@ STAT_CONST
Definition: parse.h:104
@ STAT_ONERROR
Definition: parse.h:117
@ STAT_FUNC
Definition: parse.h:115
@ STAT_FOREACH
Definition: parse.h:113
@ STAT_EXITSUB
Definition: parse.h:112
@ STAT_EXITFUNC
Definition: parse.h:110
@ STAT_DOWHILE
Definition: parse.h:107
@ STAT_EXITFOR
Definition: parse.h:109
@ STAT_FORTO
Definition: parse.h:114
@ STAT_WHILELOOP
Definition: parse.h:123
@ STAT_SET
Definition: parse.h:119
@ STAT_SELECT
Definition: parse.h:118
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1217
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1178
static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
Definition: compile.c:839
static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat)
Definition: compile.c:973
static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:674
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
Definition: compile.c:968
static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement_t *stat)
Definition: compile.c:1097
static HRESULT compile_exitfor_statement(compile_ctx_t *ctx)
Definition: compile.c:1135
static HRESULT compile_const_statement(compile_ctx_t *ctx, const_statement_t *stat)
Definition: compile.c:1061
static HRESULT compile_exitfunc_statement(compile_ctx_t *ctx)
Definition: compile.c:1186
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat)
Definition: compile.c:757
static HRESULT compile_exitdo_statement(compile_ctx_t *ctx)
Definition: compile.c:1109
static HRESULT compile_onerror_statement(compile_ctx_t *ctx, onerror_statement_t *stat)
Definition: compile.c:1206
static HRESULT compile_exitprop_statement(compile_ctx_t *ctx)
Definition: compile.c:1196
static HRESULT compile_foreach_statement(compile_ctx_t *ctx, foreach_statement_t *stat)
Definition: compile.c:712
static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
Definition: compile.c:1026
static HRESULT compile_retval_statement(compile_ctx_t *ctx, retval_statement_t *stat)
Definition: compile.c:1211
static HRESULT compile_exitsub_statement(compile_ctx_t *ctx)
Definition: compile.c:1176

◆ compile_unary_expression()

static HRESULT compile_unary_expression ( compile_ctx_t ctx,
unary_expression_t expr,
vbsop_t  op 
)
static

Definition at line 458 of file compile.c.

459{
461
462 hres = compile_expression(ctx, expr->subexpr);
463 if(FAILED(hres))
464 return hres;
465
466 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
467}

◆ compile_while_statement()

static HRESULT compile_while_statement ( compile_ctx_t ctx,
while_statement_t stat 
)
static

Definition at line 630 of file compile.c.

631{
632 statement_ctx_t stat_ctx = {0}, *loop_ctx;
633 unsigned start_addr;
634 unsigned jmp_end;
636
637 start_addr = ctx->instr_cnt;
638
640 if(FAILED(hres))
641 return hres;
642
643 jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
644 if(!jmp_end)
645 return E_OUTOFMEMORY;
646
647 if(!emit_catch(ctx, 0))
648 return E_OUTOFMEMORY;
649
650 if(stat->stat.type == STAT_WHILE) {
651 loop_ctx = NULL;
652 }else {
653 if(!(stat_ctx.while_end_label = alloc_label(ctx)))
654 return E_OUTOFMEMORY;
655 loop_ctx = &stat_ctx;
656 }
657
658 hres = compile_statement(ctx, loop_ctx, stat->body);
659 if(FAILED(hres))
660 return hres;
661
662 hres = push_instr_addr(ctx, OP_jmp, start_addr);
663 if(FAILED(hres))
664 return hres;
665
666 instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
667
668 if(loop_ctx)
670
671 return S_OK;
672}

◆ compiler_alloc()

static void * compiler_alloc ( vbscode_t vbscode,
size_t  size 
)
inlinestatic

Definition at line 119 of file compile.c.

120{
121 return heap_pool_alloc(&vbscode->heap, size);
122}
GLsizeiptr size
Definition: glext.h:5919
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
heap_pool_t heap
Definition: vbscript.h:349

◆ compiler_alloc_string()

static WCHAR * compiler_alloc_string ( vbscode_t vbscode,
const WCHAR str 
)
static

Definition at line 134 of file compile.c.

135{
136 size_t size;
137 WCHAR *ret;
138
139 size = (lstrlenW(str)+1)*sizeof(WCHAR);
140 ret = compiler_alloc(vbscode, size);
141 if(ret)
142 memcpy(ret, str, size);
143 return ret;
144}
#define lstrlenW
Definition: compat.h:750
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

◆ compiler_alloc_zero()

static void * compiler_alloc_zero ( vbscode_t vbscode,
size_t  size 
)
inlinestatic

Definition at line 124 of file compile.c.

125{
126 void *ret;
127
128 ret = heap_pool_alloc(&vbscode->heap, size);
129 if(ret)
130 memset(ret, 0, size);
131 return ret;
132}

Referenced by compile_class(), and compile_procedure().

◆ create_class_funcprop()

static HRESULT create_class_funcprop ( compile_ctx_t ctx,
function_decl_t func_decl,
vbdisp_funcprop_desc_t desc 
)
static

Definition at line 1549 of file compile.c.

1550{
1551 vbdisp_invoke_type_t invoke_type;
1552 function_decl_t *funcprop_decl;
1553 HRESULT hres;
1554
1555 desc->name = compiler_alloc_string(ctx->code, func_decl->name);
1556 if(!desc->name)
1557 return E_OUTOFMEMORY;
1558
1559 for(funcprop_decl = func_decl; funcprop_decl; funcprop_decl = funcprop_decl->next_prop_func) {
1560 switch(funcprop_decl->type) {
1561 case FUNC_FUNCTION:
1562 case FUNC_SUB:
1563 case FUNC_PROPGET:
1564 case FUNC_DEFGET:
1565 invoke_type = VBDISP_CALLGET;
1566 break;
1567 case FUNC_PROPLET:
1568 invoke_type = VBDISP_LET;
1569 break;
1570 case FUNC_PROPSET:
1571 invoke_type = VBDISP_SET;
1572 break;
1574 }
1575
1576 assert(!desc->entries[invoke_type]);
1577
1578 if(funcprop_decl->is_public)
1579 desc->is_public = TRUE;
1580
1581 hres = create_function(ctx, funcprop_decl, desc->entries+invoke_type);
1582 if(FAILED(hres))
1583 return hres;
1584 }
1585
1586 return S_OK;
1587}
#define DEFAULT_UNREACHABLE
BOOL is_public
Definition: parse.h:171
vbdisp_invoke_type_t
Definition: vbscript.h:71
@ VBDISP_LET
Definition: vbscript.h:73
@ VBDISP_SET
Definition: vbscript.h:74

Referenced by compile_class().

◆ create_function()

static HRESULT create_function ( compile_ctx_t ctx,
function_decl_t decl,
function_t **  ret 
)
static

Definition at line 1482 of file compile.c.

1483{
1485 HRESULT hres;
1486
1487 if(lookup_dim_decls(ctx, decl->name) || lookup_funcs_name(ctx, decl->name) || lookup_const_decls(ctx, decl->name, FALSE)) {
1488 FIXME("%s: redefinition\n", debugstr_w(decl->name));
1489 return E_FAIL;
1490 }
1491
1492 func = compiler_alloc(ctx->code, sizeof(*func));
1493 if(!func)
1494 return E_OUTOFMEMORY;
1495
1496 func->name = compiler_alloc_string(ctx->code, decl->name);
1497 if(!func->name)
1498 return E_OUTOFMEMORY;
1499
1500 func->vars = NULL;
1501 func->var_cnt = 0;
1502 func->array_cnt = 0;
1503 func->code_ctx = ctx->code;
1504 func->type = decl->type;
1505 func->is_public = decl->is_public;
1506
1507 func->arg_cnt = 0;
1508 if(decl->args) {
1509 arg_decl_t *arg;
1510 unsigned i;
1511
1512 for(arg = decl->args; arg; arg = arg->next)
1513 func->arg_cnt++;
1514
1515 func->args = compiler_alloc(ctx->code, func->arg_cnt * sizeof(arg_desc_t));
1516 if(!func->args)
1517 return E_OUTOFMEMORY;
1518
1519 for(i = 0, arg = decl->args; arg; arg = arg->next, i++) {
1520 func->args[i].name = compiler_alloc_string(ctx->code, arg->name);
1521 if(!func->args[i].name)
1522 return E_OUTOFMEMORY;
1523 func->args[i].by_ref = arg->by_ref;
1524 }
1525 }else {
1526 func->args = NULL;
1527 }
1528
1529 hres = compile_func(ctx, decl->body, func);
1530 if(FAILED(hres))
1531 return hres;
1532
1533 *ret = func;
1534 return S_OK;
1535}
arg_decl_t * args
Definition: parse.h:172
statement_t * body
Definition: parse.h:173
void * arg
Definition: msvc.h:10

Referenced by compile_script(), and create_class_funcprop().

◆ dump_code()

static void dump_code ( compile_ctx_t ctx)
static

Definition at line 106 of file compile.c.

107{
108 instr_t *instr;
109
110 for(instr = ctx->code->instrs+1; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
111 assert(instr->op < OP_LAST);
112 TRACE_(vbscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
113 dump_instr_arg(instr_info[instr->op].arg1_type, &instr->arg1);
114 dump_instr_arg(instr_info[instr->op].arg2_type, &instr->arg2);
115 TRACE_(vbscript_disas)("\n");
116 }
117}
#define TRACE_(x)
Definition: compat.h:76
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
@ OP_LAST
Definition: engine.h:105
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:86
jsop_t op
Definition: engine.h:127

◆ dump_instr_arg()

static void dump_instr_arg ( instr_arg_type_t  type,
instr_arg_t arg 
)
static

Definition at line 83 of file compile.c.

84{
85 switch(type) {
86 case ARG_STR:
87 case ARG_BSTR:
88 TRACE_(vbscript_disas)("\t%s", debugstr_w(arg->str));
89 break;
90 case ARG_INT:
91 TRACE_(vbscript_disas)("\t%d", arg->uint);
92 break;
93 case ARG_UINT:
94 case ARG_ADDR:
95 TRACE_(vbscript_disas)("\t%u", arg->uint);
96 break;
97 case ARG_DOUBLE:
98 TRACE_(vbscript_disas)("\t%lf", *arg->dbl);
99 break;
100 case ARG_NONE:
101 break;
103 }
104}
#define ARG_NONE
Definition: amlcode.h:216
@ ARG_INT
Definition: engine.h:121
@ ARG_ADDR
Definition: engine.h:117
@ ARG_BSTR
Definition: engine.h:118
@ ARG_STR
Definition: engine.h:122
@ ARG_UINT
Definition: engine.h:123
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
@ ARG_DOUBLE
Definition: vbscript.h:219

◆ emit_catch()

◆ emit_catch_jmp()

static BOOL emit_catch_jmp ( compile_ctx_t ctx,
unsigned  stack_off,
unsigned  code_off 
)
static

Definition at line 360 of file compile.c.

361{
362 unsigned code;
363
364 code = push_instr(ctx, OP_catch);
365 if(!code)
366 return FALSE;
367
368 instr_ptr(ctx, code)->arg1.uint = code_off;
369 instr_ptr(ctx, code)->arg2.uint = stack_off + stack_offset(ctx);
370 return TRUE;
371}
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:349

Referenced by compile_select_statement(), and emit_catch().

◆ exit_label()

static HRESULT exit_label ( compile_ctx_t ctx,
unsigned  jmp_label 
)
static

Definition at line 1161 of file compile.c.

1162{
1163 unsigned pop_cnt = stack_offset(ctx);
1164
1165 if(pop_cnt) {
1166 HRESULT hres;
1167
1168 hres = push_instr_uint(ctx, OP_pop, pop_cnt);
1169 if(FAILED(hres))
1170 return hres;
1171 }
1172
1173 return push_instr_addr(ctx, OP_jmp, jmp_label);
1174}

Referenced by compile_exitfunc_statement(), compile_exitprop_statement(), and compile_exitsub_statement().

◆ fill_array_desc()

static HRESULT fill_array_desc ( compile_ctx_t ctx,
dim_decl_t dim_decl,
array_desc_t array_desc 
)
static

Definition at line 1333 of file compile.c.

1334{
1335 unsigned dim_cnt = 0, i;
1336 dim_list_t *iter;
1337
1338 for(iter = dim_decl->dims; iter; iter = iter->next)
1339 dim_cnt++;
1340
1341 array_desc->bounds = compiler_alloc(ctx->code, dim_cnt * sizeof(SAFEARRAYBOUND));
1342 if(!array_desc->bounds)
1343 return E_OUTOFMEMORY;
1344
1345 array_desc->dim_cnt = dim_cnt;
1346
1347 for(iter = dim_decl->dims, i=0; iter; iter = iter->next, i++) {
1348 array_desc->bounds[i].cElements = iter->val+1;
1349 array_desc->bounds[i].lLbound = 0;
1350 }
1351
1352 return S_OK;
1353}
dim_list_t * dims
Definition: parse.h:153
struct _dim_list_t * next
Definition: parse.h:146
unsigned val
Definition: parse.h:145
unsigned dim_cnt
Definition: vbscript.h:79
SAFEARRAYBOUND * bounds
Definition: vbscript.h:80

Referenced by compile_class(), and compile_func().

◆ instr_ptr()

static instr_t * instr_ptr ( compile_ctx_t ctx,
unsigned  id 
)
inlinestatic

Definition at line 146 of file compile.c.

147{
148 assert(id < ctx->instr_cnt);
149 return ctx->code->instrs + id;
150}
GLuint id
Definition: glext.h:5910

◆ label_set_addr()

static void label_set_addr ( compile_ctx_t ctx,
unsigned  label 
)
inlinestatic

Definition at line 343 of file compile.c.

344{
346 ctx->labels[label & ~LABEL_FLAG] = ctx->instr_cnt;
347}
static const WCHAR label[]
Definition: itemdlg.c:1546

◆ lookup_args_name()

static BOOL lookup_args_name ( compile_ctx_t ctx,
const WCHAR name 
)
static

Definition at line 1014 of file compile.c.

1015{
1016 unsigned i;
1017
1018 for(i = 0; i < ctx->func->arg_cnt; i++) {
1019 if(!wcsicmp(ctx->func->args[i].name, name))
1020 return TRUE;
1021 }
1022
1023 return FALSE;
1024}
Definition: name.c:39

Referenced by compile_const_statement(), and compile_dim_statement().

◆ lookup_class_funcs()

static BOOL lookup_class_funcs ( class_desc_t class_desc,
const WCHAR name 
)
static

Definition at line 1589 of file compile.c.

1590{
1591 unsigned i;
1592
1593 for(i=0; i < class_desc->func_cnt; i++) {
1594 if(class_desc->funcs[i].name && !wcsicmp(class_desc->funcs[i].name, name))
1595 return TRUE;
1596 }
1597
1598 return FALSE;
1599}
const WCHAR * name
Definition: vbscript.h:90

Referenced by compile_class().

◆ lookup_class_name()

static BOOL lookup_class_name ( compile_ctx_t ctx,
const WCHAR name 
)
static

Definition at line 1537 of file compile.c.

1538{
1539 class_desc_t *iter;
1540
1541 for(iter = ctx->classes; iter; iter = iter->next) {
1542 if(!wcsicmp(iter->name, name))
1543 return TRUE;
1544 }
1545
1546 return FALSE;
1547}

Referenced by compile_class().

◆ lookup_const_decls()

static expression_t * lookup_const_decls ( compile_ctx_t ctx,
const WCHAR name,
BOOL  lookup_global 
)
static

Definition at line 390 of file compile.c.

391{
392 const_decl_t *decl;
393
394 for(decl = ctx->const_decls; decl; decl = decl->next) {
395 if(!wcsicmp(decl->name, name))
396 return decl->value_expr;
397 }
398
399 if(!lookup_global)
400 return NULL;
401
402 for(decl = ctx->global_consts; decl; decl = decl->next) {
403 if(!wcsicmp(decl->name, name))
404 return decl->value_expr;
405 }
406
407 return NULL;
408}

Referenced by compile_class(), compile_const_statement(), compile_dim_statement(), compile_member_expression(), and create_function().

◆ lookup_dim_decls()

static BOOL lookup_dim_decls ( compile_ctx_t ctx,
const WCHAR name 
)
static

Definition at line 1002 of file compile.c.

1003{
1004 dim_decl_t *dim_decl;
1005
1006 for(dim_decl = ctx->dim_decls; dim_decl; dim_decl = dim_decl->next) {
1007 if(!wcsicmp(dim_decl->name, name))
1008 return TRUE;
1009 }
1010
1011 return FALSE;
1012}

Referenced by compile_class(), compile_const_statement(), compile_dim_statement(), and create_function().

◆ lookup_funcs_name()

static BOOL lookup_funcs_name ( compile_ctx_t ctx,
const WCHAR name 
)
static

Definition at line 1470 of file compile.c.

1471{
1472 function_t *iter;
1473
1474 for(iter = ctx->funcs; iter; iter = iter->next) {
1475 if(!wcsicmp(iter->name, name))
1476 return TRUE;
1477 }
1478
1479 return FALSE;
1480}
const WCHAR * name
Definition: vbscript.h:323

Referenced by compile_class(), and create_function().

◆ lookup_script_identifier()

static BOOL lookup_script_identifier ( script_ctx_t script,
const WCHAR identifier 
)
static

Definition at line 1714 of file compile.c.

1715{
1716 class_desc_t *class;
1719
1720 for(var = script->global_vars; var; var = var->next) {
1721 if(!wcsicmp(var->name, identifier))
1722 return TRUE;
1723 }
1724
1725 for(func = script->global_funcs; func; func = func->next) {
1726 if(!wcsicmp(func->name, identifier))
1727 return TRUE;
1728 }
1729
1730 for(class = script->classes; class; class = class->next) {
1731 if(!wcsicmp(class->name, identifier))
1732 return TRUE;
1733 }
1734
1735 return FALSE;
1736}

Referenced by check_script_collisions().

◆ push_instr()

static unsigned push_instr ( compile_ctx_t ctx,
vbsop_t  op 
)
static

Definition at line 152 of file compile.c.

153{
154 assert(ctx->instr_size && ctx->instr_size >= ctx->instr_cnt);
155
156 if(ctx->instr_size == ctx->instr_cnt) {
157 instr_t *new_instr;
158
159 new_instr = heap_realloc(ctx->code->instrs, ctx->instr_size*2*sizeof(instr_t));
160 if(!new_instr)
161 return 0;
162
163 ctx->code->instrs = new_instr;
164 ctx->instr_size *= 2;
165 }
166
167 ctx->code->instrs[ctx->instr_cnt].op = op;
168 return ctx->instr_cnt++;
169}

◆ push_instr_addr()

static HRESULT push_instr_addr ( compile_ctx_t ctx,
vbsop_t  op,
unsigned  arg 
)
static

◆ push_instr_bstr()

static HRESULT push_instr_bstr ( compile_ctx_t ctx,
vbsop_t  op,
const WCHAR arg 
)
static

Definition at line 267 of file compile.c.

268{
269 unsigned instr;
270 BSTR bstr;
271
272 bstr = alloc_bstr_arg(ctx, arg);
273 if(!bstr)
274 return E_OUTOFMEMORY;
275
276 instr = push_instr(ctx, op);
277 if(!instr)
278 return E_OUTOFMEMORY;
279
280 instr_ptr(ctx, instr)->arg1.bstr = bstr;
281 return S_OK;
282}

◆ push_instr_bstr_uint()

static HRESULT push_instr_bstr_uint ( compile_ctx_t ctx,
vbsop_t  op,
const WCHAR arg1,
unsigned  arg2 
)
static

Definition at line 284 of file compile.c.

285{
286 unsigned instr;
287 BSTR bstr;
288
289 bstr = alloc_bstr_arg(ctx, arg1);
290 if(!bstr)
291 return E_OUTOFMEMORY;
292
293 instr = push_instr(ctx, op);
294 if(!instr)
295 return E_OUTOFMEMORY;
296
297 instr_ptr(ctx, instr)->arg1.bstr = bstr;
298 instr_ptr(ctx, instr)->arg2.uint = arg2;
299 return S_OK;
300}
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514

◆ push_instr_double()

static HRESULT push_instr_double ( compile_ctx_t ctx,
vbsop_t  op,
double  arg 
)
static

Definition at line 224 of file compile.c.

225{
226 unsigned instr;
227 double *d;
228
229 d = compiler_alloc(ctx->code, sizeof(double));
230 if(!d)
231 return E_OUTOFMEMORY;
232
233 instr = push_instr(ctx, op);
234 if(!instr)
235 return E_OUTOFMEMORY;
236
237 *d = arg;
238 instr_ptr(ctx, instr)->arg1.dbl = d;
239 return S_OK;
240}
#define d
Definition: ke_i.h:81
double * dbl
Definition: vbscript.h:293

◆ push_instr_int()

static HRESULT push_instr_int ( compile_ctx_t ctx,
vbsop_t  op,
LONG  arg 
)
static

Definition at line 171 of file compile.c.

172{
173 unsigned ret;
174
175 ret = push_instr(ctx, op);
176 if(!ret)
177 return E_OUTOFMEMORY;
178
180 return S_OK;
181}
LONG lng
Definition: engine.h:110

◆ push_instr_str()

static HRESULT push_instr_str ( compile_ctx_t ctx,
vbsop_t  op,
const WCHAR arg 
)
static

Definition at line 207 of file compile.c.

208{
209 unsigned instr;
210 WCHAR *str;
211
213 if(!str)
214 return E_OUTOFMEMORY;
215
216 instr = push_instr(ctx, op);
217 if(!instr)
218 return E_OUTOFMEMORY;
219
220 instr_ptr(ctx, instr)->arg1.str = str;
221 return S_OK;
222}
jsstr_t * str
Definition: engine.h:111

◆ push_instr_uint()

static HRESULT push_instr_uint ( compile_ctx_t ctx,
vbsop_t  op,
unsigned  arg 
)
static

Definition at line 183 of file compile.c.

184{
185 unsigned ret;
186
187 ret = push_instr(ctx, op);
188 if(!ret)
189 return E_OUTOFMEMORY;
190
192 return S_OK;
193}

◆ push_instr_uint_bstr()

static HRESULT push_instr_uint_bstr ( compile_ctx_t ctx,
vbsop_t  op,
unsigned  arg1,
const WCHAR arg2 
)
static

Definition at line 302 of file compile.c.

303{
304 unsigned instr;
305 BSTR bstr;
306
307 bstr = alloc_bstr_arg(ctx, arg2);
308 if(!bstr)
309 return E_OUTOFMEMORY;
310
311 instr = push_instr(ctx, op);
312 if(!instr)
313 return E_OUTOFMEMORY;
314
315 instr_ptr(ctx, instr)->arg1.uint = arg1;
316 instr_ptr(ctx, instr)->arg2.bstr = bstr;
317 return S_OK;
318}

Referenced by compile_foreach_statement().

◆ release_compiler()

static void release_compiler ( compile_ctx_t ctx)
static

Definition at line 1820 of file compile.c.

1821{
1822 parser_release(&ctx->parser);
1823 heap_free(ctx->labels);
1824 if(ctx->code)
1825 release_vbscode(ctx->code);
1826}
void parser_release(parser_ctx_t *) DECLSPEC_HIDDEN

Referenced by compile_script().

◆ release_vbscode()

void release_vbscode ( vbscode_t code)

Definition at line 1768 of file compile.c.

1769{
1770 unsigned i;
1771
1772 list_remove(&code->entry);
1773
1774 for(i=0; i < code->bstr_cnt; i++)
1775 SysFreeString(code->bstr_pool[i]);
1776
1777 if(code->context)
1778 IDispatch_Release(code->context);
1779 heap_pool_free(&code->heap);
1780
1781 heap_free(code->bstr_pool);
1782 heap_free(code->source);
1783 heap_free(code->instrs);
1784 heap_free(code);
1785}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:169
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271

Referenced by alloc_vbscode(), destroy_script(), and release_compiler().

◆ resolve_labels()

static void resolve_labels ( compile_ctx_t ctx,
unsigned  off 
)
static

Definition at line 1318 of file compile.c.

1319{
1320 instr_t *instr;
1321
1322 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->instr_cnt; instr++) {
1323 if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->arg1.uint & LABEL_FLAG)) {
1324 assert((instr->arg1.uint & ~LABEL_FLAG) < ctx->labels_cnt);
1325 instr->arg1.uint = ctx->labels[instr->arg1.uint & ~LABEL_FLAG];
1326 }
1327 assert(instr_info[instr->op].arg2_type != ARG_ADDR);
1328 }
1329
1330 ctx->labels_cnt = 0;
1331}

◆ stack_offset()

static unsigned stack_offset ( compile_ctx_t ctx)
inlinestatic

Definition at line 349 of file compile.c.

350{
351 statement_ctx_t *iter;
352 unsigned ret = 0;
353
354 for(iter = ctx->stat_ctx; iter; iter = iter->next)
355 ret += iter->stack_use;
356
357 return ret;
358}

Referenced by convert_old_args(), debugcontrol_GetStackTrace(), DECLARE_INTERFACE_(), emit_catch_jmp(), exit_label(), write_iface_fs(), write_new_procformatstring_type(), write_param_fs(), and write_procformatstring_func().

◆ WINE_DECLARE_DEBUG_CHANNEL()

WINE_DECLARE_DEBUG_CHANNEL ( vbscript_disas  )

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( vbscript  )

Variable Documentation

◆ arg1_type

instr_arg_type_t arg1_type

Definition at line 75 of file compile.c.

◆ arg2_type

instr_arg_type_t arg2_type

Definition at line 76 of file compile.c.

◆ 

const struct { ... } instr_info[]
Initial value:
= {
#define X(n,a,b,c)
}
#define OP_LIST
Definition: engine.h:21

◆ op_str

const char* op_str

Definition at line 74 of file compile.c.