jscript: Added support for pstrFormalParams argument in ParseProcedureText.
This commit is contained in:
parent
1d542e3aa4
commit
bf65003271
|
@ -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)) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue