jscript: Added support for pstrFormalParams argument in ParseProcedureText.

This commit is contained in:
Jacek Caban 2012-10-04 14:58:05 +02:00 committed by Alexandre Julliard
parent 1d542e3aa4
commit bf65003271
7 changed files with 117 additions and 12 deletions

View File

@ -131,24 +131,32 @@ static WCHAR *compiler_alloc_string(bytecode_t *code, const WCHAR *str)
return ret; return ret;
} }
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str) static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
{ {
if(!ctx->code->bstr_pool_size) { if(!ctx->code->bstr_pool_size) {
ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR)); ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
if(!ctx->code->bstr_pool) if(!ctx->code->bstr_pool)
return NULL; return FALSE;
ctx->code->bstr_pool_size = 8; ctx->code->bstr_pool_size = 8;
}else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) { }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
BSTR *new_pool; BSTR *new_pool;
new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR)); new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
if(!new_pool) if(!new_pool)
return NULL; return FALSE;
ctx->code->bstr_pool = new_pool; ctx->code->bstr_pool = new_pool;
ctx->code->bstr_pool_size *= 2; 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); ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
if(!ctx->code->bstr_pool[ctx->code->bstr_cnt]) if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
return NULL; return NULL;
@ -156,6 +164,18 @@ static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
return ctx->code->bstr_pool[ctx->code->bstr_cnt++]; 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) static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
{ {
assert(ctx->code_size >= ctx->code_off); assert(ctx->code_size >= ctx->code_off);
@ -1885,8 +1905,78 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source,
return S_OK; return S_OK;
} }
HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
bytecode_t **ret) {
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}; compiler_ctx_t compiler = {0};
HRESULT hres; HRESULT hres;
@ -1895,6 +1985,12 @@ HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimi
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
if(args) {
hres = compile_arguments(&compiler, args);
if(FAILED(hres))
return hres;
}
if(use_decode) { if(use_decode) {
hres = decode_source(compiler.code->source); hres = decode_source(compiler.code->source);
if(FAILED(hres)) { if(FAILED(hres)) {

View File

@ -178,7 +178,7 @@ typedef struct _bytecode_t {
struct _bytecode_t *next; struct _bytecode_t *next;
} bytecode_t; } bytecode_t;
HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,BOOL,BOOL,bytecode_t**) DECLSPEC_HIDDEN; HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,BOOL,BOOL,bytecode_t**) DECLSPEC_HIDDEN;
void release_bytecode(bytecode_t*) DECLSPEC_HIDDEN; void release_bytecode(bytecode_t*) DECLSPEC_HIDDEN;
static inline void bytecode_addref(bytecode_t *code) static inline void bytecode_addref(bytecode_t *code)

View File

@ -750,7 +750,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
hres = compile_script(ctx, str, NULL, FALSE, FALSE, &code); hres = compile_script(ctx, str, NULL, NULL, FALSE, FALSE, &code);
heap_free(str); heap_free(str);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;

View File

@ -370,7 +370,7 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
} }
TRACE("parsing %s\n", debugstr_jsval(argv[0])); TRACE("parsing %s\n", debugstr_jsval(argv[0]));
hres = compile_script(ctx, get_string(argv[0]), NULL, TRUE, FALSE, &code); hres = compile_script(ctx, get_string(argv[0]), NULL, NULL, TRUE, FALSE, &code);
if(FAILED(hres)) { if(FAILED(hres)) {
WARN("parse (%s) failed: %08x\n", debugstr_jsval(argv[0]), hres); WARN("parse (%s) failed: %08x\n", debugstr_jsval(argv[0]), hres);
return throw_syntax_error(ctx, hres, NULL); return throw_syntax_error(ctx, hres, NULL);

View File

@ -763,7 +763,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED; return E_UNEXPECTED;
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, FALSE, This->is_encode, &code); hres = compile_script(This->ctx, pstrCode, NULL, pstrDelimiter, FALSE, This->is_encode, &code);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
@ -830,7 +830,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars
if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED; return E_UNEXPECTED;
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, FALSE, This->is_encode, &code); hres = compile_script(This->ctx, pstrCode, pstrFormalParams, pstrDelimiter, FALSE, This->is_encode, &code);
if(FAILED(hres)) { if(FAILED(hres)) {
WARN("Parse failed %08x\n", hres); WARN("Parse failed %08x\n", hres);
return hres; return hres;

View File

@ -1927,6 +1927,17 @@ static void test_parse_proc(void)
dp.cArgs = 1; dp.cArgs = 1;
V_VT(args) = VT_EMPTY; V_VT(args) = VT_EMPTY;
invoke_procedure(NULL, "return arguments.length == 1;", &dp); invoke_procedure(NULL, "return arguments.length == 1;", &dp);
V_VT(args) = VT_BOOL;
V_BOOL(args) = VARIANT_TRUE;
invoke_procedure(" x ", "return x;", &dp);
dp.cArgs = 2;
V_VT(args) = VT_I4;
V_I4(args) = 2;
V_VT(args+1) = VT_I4;
V_I4(args+1) = 1;
invoke_procedure(" _x1 , y_2", "return _x1 === 1 && y_2 === 2;", &dp);
} }
static void run_encoded_tests(void) static void run_encoded_tests(void)

View File

@ -2355,10 +2355,8 @@ static void test_event_call(void)
dp.cArgs = 2; dp.cArgs = 2;
V_VT(&res) = VT_EMPTY; V_VT(&res) = VT_EMPTY;
hres = IDispatch_Invoke(sink_disp, 2, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL); hres = IDispatch_Invoke(sink_disp, 2, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);
todo_wine { /* Needs jscript fixes */
ok(hres == S_OK, "Invoke failed: %08x\n", hres); ok(hres == S_OK, "Invoke failed: %08x\n", hres);
ok(V_VT(&res) == VT_I4 && V_I4(&res) == 7, "unexpected result: %d\n", V_I4(&res)); ok(V_VT(&res) == VT_I4 && V_I4(&res) == 7, "unexpected result: %d\n", V_I4(&res));
}
V_VT(&res) = VT_ERROR; V_VT(&res) = VT_ERROR;
hres = IDispatch_Invoke(sink_disp, 10, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL); hres = IDispatch_Invoke(sink_disp, 10, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);