ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

global.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2008 Jacek Caban for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include "config.h"
00020 #include "wine/port.h"
00021 
00022 #include <math.h>
00023 #include <limits.h>
00024 
00025 #include "jscript.h"
00026 #include "engine.h"
00027 
00028 #include "wine/debug.h"
00029 
00030 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
00031 
00032 #define LONGLONG_MAX (((LONGLONG)0x7fffffff<<32)|0xffffffff)
00033 
00034 static const WCHAR NaNW[] = {'N','a','N',0};
00035 static const WCHAR InfinityW[] = {'I','n','f','i','n','i','t','y',0};
00036 static const WCHAR ArrayW[] = {'A','r','r','a','y',0};
00037 static const WCHAR BooleanW[] = {'B','o','o','l','e','a','n',0};
00038 static const WCHAR DateW[] = {'D','a','t','e',0};
00039 static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
00040 static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
00041 static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
00042 static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
00043 static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
00044 static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
00045 static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
00046 static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
00047 static const WCHAR NumberW[] = {'N','u','m','b','e','r',0};
00048 static const WCHAR ObjectW[] = {'O','b','j','e','c','t',0};
00049 static const WCHAR StringW[] = {'S','t','r','i','n','g',0};
00050 static const WCHAR RegExpW[] = {'R','e','g','E','x','p',0};
00051 static const WCHAR ActiveXObjectW[] = {'A','c','t','i','v','e','X','O','b','j','e','c','t',0};
00052 static const WCHAR VBArrayW[] = {'V','B','A','r','r','a','y',0};
00053 static const WCHAR EnumeratorW[] = {'E','n','u','m','e','r','a','t','o','r',0};
00054 static const WCHAR escapeW[] = {'e','s','c','a','p','e',0};
00055 static const WCHAR evalW[] = {'e','v','a','l',0};
00056 static const WCHAR isNaNW[] = {'i','s','N','a','N',0};
00057 static const WCHAR isFiniteW[] = {'i','s','F','i','n','i','t','e',0};
00058 static const WCHAR parseIntW[] = {'p','a','r','s','e','I','n','t',0};
00059 static const WCHAR parseFloatW[] = {'p','a','r','s','e','F','l','o','a','t',0};
00060 static const WCHAR unescapeW[] = {'u','n','e','s','c','a','p','e',0};
00061 static const WCHAR _GetObjectW[] = {'G','e','t','O','b','j','e','c','t',0};
00062 static const WCHAR ScriptEngineW[] = {'S','c','r','i','p','t','E','n','g','i','n','e',0};
00063 static const WCHAR ScriptEngineMajorVersionW[] =
00064     {'S','c','r','i','p','t','E','n','g','i','n','e','M','a','j','o','r','V','e','r','s','i','o','n',0};
00065 static const WCHAR ScriptEngineMinorVersionW[] =
00066     {'S','c','r','i','p','t','E','n','g','i','n','e','M','i','n','o','r','V','e','r','s','i','o','n',0};
00067 static const WCHAR ScriptEngineBuildVersionW[] =
00068     {'S','c','r','i','p','t','E','n','g','i','n','e','B','u','i','l','d','V','e','r','s','i','o','n',0};
00069 static const WCHAR CollectGarbageW[] = {'C','o','l','l','e','c','t','G','a','r','b','a','g','e',0};
00070 static const WCHAR MathW[] = {'M','a','t','h',0};
00071 static const WCHAR encodeURIW[] = {'e','n','c','o','d','e','U','R','I',0};
00072 static const WCHAR decodeURIW[] = {'d','e','c','o','d','e','U','R','I',0};
00073 static const WCHAR encodeURIComponentW[] = {'e','n','c','o','d','e','U','R','I','C','o','m','p','o','n','e','n','t',0};
00074 static const WCHAR decodeURIComponentW[] = {'d','e','c','o','d','e','U','R','I','C','o','m','p','o','n','e','n','t',0};
00075 
00076 static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
00077 
00078 static int uri_char_table[] = {
00079     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00-0f */
00080     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 10-1f */
00081     0,2,0,0,1,0,1,2,2,2,2,1,1,2,2,1, /* 20-2f */
00082     2,2,2,2,2,2,2,2,2,2,1,1,0,1,0,1, /* 30-3f */
00083     1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 40-4f */
00084     2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,2, /* 50-5f */
00085     0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 60-6f */
00086     2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,0, /* 70-7f */
00087 };
00088 
00089 /* 1 - reserved */
00090 /* 2 - unescaped */
00091 
00092 static inline BOOL is_uri_reserved(WCHAR c)
00093 {
00094     return c < 128 && uri_char_table[c] == 1;
00095 }
00096 
00097 static inline BOOL is_uri_unescaped(WCHAR c)
00098 {
00099     return c < 128 && uri_char_table[c] == 2;
00100 }
00101 
00102 static WCHAR int_to_char(int i)
00103 {
00104     if(i < 10)
00105         return '0'+i;
00106     return 'A'+i-10;
00107 }
00108 
00109 static HRESULT constructor_call(DispatchEx *constr, WORD flags, DISPPARAMS *dp,
00110         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00111 {
00112     if(flags != DISPATCH_PROPERTYGET)
00113         return jsdisp_call_value(constr, flags, dp, retv, ei, sp);
00114 
00115     V_VT(retv) = VT_DISPATCH;
00116     V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(constr);
00117     IDispatchEx_AddRef(_IDispatchEx_(constr));
00118     return S_OK;
00119 }
00120 
00121 static HRESULT JSGlobal_NaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00122         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00123 {
00124     TRACE("\n");
00125 
00126     switch(flags) {
00127     case DISPATCH_PROPERTYGET:
00128         num_set_nan(retv);
00129         break;
00130 
00131     default:
00132         FIXME("unimplemented flags %x\n", flags);
00133         return E_NOTIMPL;
00134     }
00135 
00136     return S_OK;
00137 }
00138 
00139 static HRESULT JSGlobal_Infinity(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00140         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00141 {
00142     TRACE("\n");
00143 
00144     switch(flags) {
00145     case DISPATCH_PROPERTYGET:
00146         num_set_inf(retv, TRUE);
00147         break;
00148 
00149     default:
00150         FIXME("unimplemented flags %x\n", flags);
00151         return E_NOTIMPL;
00152     }
00153 
00154     return S_OK;
00155 }
00156 
00157 static HRESULT JSGlobal_Array(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00158         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00159 {
00160     TRACE("\n");
00161 
00162     return constructor_call(ctx->array_constr, flags, dp, retv, ei, sp);
00163 }
00164 
00165 static HRESULT JSGlobal_Boolean(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00166         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00167 {
00168     TRACE("\n");
00169 
00170     return constructor_call(ctx->bool_constr, flags, dp, retv, ei, sp);
00171 }
00172 
00173 static HRESULT JSGlobal_Date(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00174         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00175 {
00176     TRACE("\n");
00177 
00178     return constructor_call(ctx->date_constr, flags, dp, retv, ei, sp);
00179 }
00180 
00181 static HRESULT JSGlobal_Error(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00182         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00183 {
00184     TRACE("\n");
00185 
00186     return constructor_call(ctx->error_constr, flags, dp, retv, ei, sp);
00187 }
00188 
00189 static HRESULT JSGlobal_EvalError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00190         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00191 {
00192     TRACE("\n");
00193 
00194     return constructor_call(ctx->eval_error_constr, flags, dp, retv, ei, sp);
00195 }
00196 
00197 static HRESULT JSGlobal_RangeError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00198         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00199 {
00200     TRACE("\n");
00201 
00202     return constructor_call(ctx->range_error_constr, flags, dp, retv, ei, sp);
00203 }
00204 
00205 static HRESULT JSGlobal_ReferenceError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00206         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00207 {
00208     TRACE("\n");
00209 
00210     return constructor_call(ctx->reference_error_constr, flags, dp, retv, ei, sp);
00211 }
00212 
00213 static HRESULT JSGlobal_SyntaxError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00214         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00215 {
00216     TRACE("\n");
00217 
00218     return constructor_call(ctx->syntax_error_constr, flags, dp, retv, ei, sp);
00219 }
00220 
00221 static HRESULT JSGlobal_TypeError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00222         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00223 {
00224     TRACE("\n");
00225 
00226     return constructor_call(ctx->type_error_constr, flags, dp, retv, ei, sp);
00227 }
00228 
00229 static HRESULT JSGlobal_URIError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00230         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00231 {
00232     TRACE("\n");
00233 
00234     return constructor_call(ctx->uri_error_constr, flags, dp, retv, ei, sp);
00235 }
00236 
00237 static HRESULT JSGlobal_Function(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00238         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00239 {
00240     TRACE("\n");
00241 
00242     return constructor_call(ctx->function_constr, flags, dp, retv, ei, sp);
00243 }
00244 
00245 static HRESULT JSGlobal_Number(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00246         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00247 {
00248     TRACE("\n");
00249 
00250     return constructor_call(ctx->number_constr, flags, dp, retv, ei, sp);
00251 }
00252 
00253 static HRESULT JSGlobal_Object(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00254         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00255 {
00256     TRACE("\n");
00257 
00258     return constructor_call(ctx->object_constr, flags, dp, retv, ei, sp);
00259 }
00260 
00261 static HRESULT JSGlobal_String(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00262         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00263 {
00264     TRACE("\n");
00265 
00266     return constructor_call(ctx->string_constr, flags, dp, retv, ei, sp);
00267 }
00268 
00269 static HRESULT JSGlobal_RegExp(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00270         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00271 {
00272     TRACE("\n");
00273 
00274     return constructor_call(ctx->regexp_constr, flags, dp, retv, ei, sp);
00275 }
00276 
00277 static HRESULT JSGlobal_ActiveXObject(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00278         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00279 {
00280     TRACE("\n");
00281 
00282     return constructor_call(ctx->activex_constr, flags, dp, retv, ei, sp);
00283 }
00284 
00285 static HRESULT JSGlobal_VBArray(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00286         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00287 {
00288     FIXME("\n");
00289     return E_NOTIMPL;
00290 }
00291 
00292 static HRESULT JSGlobal_Enumerator(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00293         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00294 {
00295     FIXME("\n");
00296     return E_NOTIMPL;
00297 }
00298 
00299 static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00300         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00301 {
00302     BSTR ret, str;
00303     const WCHAR *ptr;
00304     DWORD len = 0;
00305     HRESULT hres;
00306 
00307     TRACE("\n");
00308 
00309     if(!arg_cnt(dp)) {
00310         if(retv) {
00311             ret = SysAllocString(undefinedW);
00312             if(!ret)
00313                 return E_OUTOFMEMORY;
00314 
00315             V_VT(retv) = VT_BSTR;
00316             V_BSTR(retv) = ret;
00317         }
00318 
00319         return S_OK;
00320     }
00321 
00322     hres = to_string(ctx, get_arg(dp, 0), ei, &str);
00323     if(FAILED(hres))
00324         return hres;
00325 
00326     for(ptr=str; *ptr; ptr++) {
00327         if(*ptr > 0xff)
00328             len += 6;
00329         else if(isalnum((char)*ptr) || *ptr=='*' || *ptr=='@' || *ptr=='-'
00330                 || *ptr=='_' || *ptr=='+' || *ptr=='.' || *ptr=='/')
00331             len++;
00332         else
00333             len += 3;
00334     }
00335 
00336     ret = SysAllocStringLen(NULL, len);
00337     if(!ret) {
00338         SysFreeString(str);
00339         return E_OUTOFMEMORY;
00340     }
00341 
00342     len = 0;
00343     for(ptr=str; *ptr; ptr++) {
00344         if(*ptr > 0xff) {
00345             ret[len++] = '%';
00346             ret[len++] = 'u';
00347             ret[len++] = int_to_char(*ptr >> 12);
00348             ret[len++] = int_to_char((*ptr >> 8) & 0xf);
00349             ret[len++] = int_to_char((*ptr >> 4) & 0xf);
00350             ret[len++] = int_to_char(*ptr & 0xf);
00351         }
00352         else if(isalnum((char)*ptr) || *ptr=='*' || *ptr=='@' || *ptr=='-'
00353                 || *ptr=='_' || *ptr=='+' || *ptr=='.' || *ptr=='/')
00354             ret[len++] = *ptr;
00355         else {
00356             ret[len++] = '%';
00357             ret[len++] = int_to_char(*ptr >> 4);
00358             ret[len++] = int_to_char(*ptr & 0xf);
00359         }
00360     }
00361 
00362     SysFreeString(str);
00363 
00364     if(retv) {
00365         V_VT(retv) = VT_BSTR;
00366         V_BSTR(retv) = ret;
00367     }
00368     else
00369         SysFreeString(ret);
00370 
00371     return S_OK;
00372 }
00373 
00374 /* ECMA-262 3rd Edition    15.1.2.1 */
00375 static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00376         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00377 {
00378     parser_ctx_t *parser_ctx;
00379     VARIANT *arg;
00380     HRESULT hres;
00381 
00382     TRACE("\n");
00383 
00384     if(!arg_cnt(dp)) {
00385         if(retv)
00386             V_VT(retv) = VT_EMPTY;
00387         return S_OK;
00388     }
00389 
00390     arg = get_arg(dp, 0);
00391     if(V_VT(arg) != VT_BSTR) {
00392         if(retv) {
00393             V_VT(retv) = VT_EMPTY;
00394             return VariantCopy(retv, arg);
00395         }
00396         return S_OK;
00397     }
00398 
00399     if(!ctx->exec_ctx) {
00400         FIXME("No active exec_ctx\n");
00401         return E_UNEXPECTED;
00402     }
00403 
00404     TRACE("parsing %s\n", debugstr_w(V_BSTR(arg)));
00405     hres = script_parse(ctx, V_BSTR(arg), NULL, &parser_ctx);
00406     if(FAILED(hres)) {
00407         WARN("parse (%s) failed: %08x\n", debugstr_w(V_BSTR(arg)), hres);
00408         return throw_syntax_error(ctx, ei, hres, NULL);
00409     }
00410 
00411     hres = exec_source(ctx->exec_ctx, parser_ctx, parser_ctx->source, EXECT_EVAL, ei, retv);
00412     parser_release(parser_ctx);
00413 
00414     return hres;
00415 }
00416 
00417 static HRESULT JSGlobal_isNaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00418         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00419 {
00420     VARIANT_BOOL ret = VARIANT_FALSE;
00421     VARIANT num;
00422     HRESULT hres;
00423 
00424     TRACE("\n");
00425 
00426     if(arg_cnt(dp)) {
00427         hres = to_number(ctx, get_arg(dp,0), ei, &num);
00428         if(FAILED(hres))
00429             return hres;
00430 
00431         if(V_VT(&num) == VT_R8 && isnan(V_R8(&num)))
00432             ret = VARIANT_TRUE;
00433     }else {
00434         ret = VARIANT_TRUE;
00435     }
00436 
00437     if(retv) {
00438         V_VT(retv) = VT_BOOL;
00439         V_BOOL(retv) = ret;
00440     }
00441     return S_OK;
00442 }
00443 
00444 static HRESULT JSGlobal_isFinite(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00445         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00446 {
00447     VARIANT_BOOL ret = VARIANT_FALSE;
00448     HRESULT hres;
00449 
00450     TRACE("\n");
00451 
00452     if(arg_cnt(dp)) {
00453         VARIANT num;
00454 
00455         hres = to_number(ctx, get_arg(dp,0), ei, &num);
00456         if(FAILED(hres))
00457             return hres;
00458 
00459         if(V_VT(&num) != VT_R8 || (!isinf(V_R8(&num)) && !isnan(V_R8(&num))))
00460             ret = VARIANT_TRUE;
00461     }
00462 
00463     if(retv) {
00464         V_VT(retv) = VT_BOOL;
00465         V_BOOL(retv) = ret;
00466     }
00467     return S_OK;
00468 }
00469 
00470 static INT char_to_int(WCHAR c)
00471 {
00472     if('0' <= c && c <= '9')
00473         return c - '0';
00474     if('a' <= c && c <= 'z')
00475         return c - 'a' + 10;
00476     if('A' <= c && c <= 'Z')
00477         return c - 'A' + 10;
00478     return 100;
00479 }
00480 
00481 static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00482         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00483 {
00484     DOUBLE ret = 0.0;
00485     INT radix=10, i;
00486     WCHAR *ptr;
00487     BOOL neg = FALSE;
00488     BSTR str;
00489     HRESULT hres;
00490 
00491     if(!arg_cnt(dp)) {
00492         if(retv) num_set_nan(retv);
00493         return S_OK;
00494     }
00495 
00496     if(arg_cnt(dp) >= 2) {
00497         hres = to_int32(ctx, get_arg(dp, 1), ei, &radix);
00498         if(FAILED(hres))
00499             return hres;
00500 
00501         if(!radix) {
00502             radix = 10;
00503         }else if(radix < 2 || radix > 36) {
00504             WARN("radix %d out of range\n", radix);
00505             return E_FAIL;
00506         }
00507     }
00508 
00509     hres = to_string(ctx, get_arg(dp, 0), ei, &str);
00510     if(FAILED(hres))
00511         return hres;
00512 
00513     for(ptr = str; isspaceW(*ptr); ptr++);
00514 
00515     switch(*ptr) {
00516     case '+':
00517         ptr++;
00518         break;
00519     case '-':
00520         neg = TRUE;
00521         ptr++;
00522         break;
00523     case '0':
00524         ptr++;
00525         if(*ptr == 'x' || *ptr == 'X') {
00526             radix = 16;
00527             ptr++;
00528         }
00529     }
00530 
00531     while(*ptr) {
00532         i = char_to_int(*ptr++);
00533         if(i > radix)
00534             break;
00535 
00536         ret = ret*radix + i;
00537     }
00538 
00539     SysFreeString(str);
00540 
00541     if(neg)
00542         ret = -ret;
00543 
00544     if(retv)
00545         num_set_val(retv, ret);
00546     return S_OK;
00547 }
00548 
00549 static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00550         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00551 {
00552     LONGLONG d = 0, hlp;
00553     int exp = 0;
00554     VARIANT *arg;
00555     WCHAR *str;
00556     BSTR val_str = NULL;
00557     BOOL ret_nan = TRUE, positive = TRUE;
00558     HRESULT hres;
00559 
00560     if(!arg_cnt(dp)) {
00561         if(retv)
00562             num_set_nan(retv);
00563         return S_OK;
00564     }
00565 
00566     arg = get_arg(dp, 0);
00567     hres = to_string(ctx, arg, ei, &val_str);
00568     if(FAILED(hres))
00569         return hres;
00570 
00571     str = val_str;
00572 
00573     while(isspaceW(*str)) str++;
00574 
00575     if(*str == '+')
00576         str++;
00577     else if(*str == '-') {
00578         positive = FALSE;
00579         str++;
00580     }
00581 
00582     if(isdigitW(*str))
00583         ret_nan = FALSE;
00584 
00585     while(isdigitW(*str)) {
00586         hlp = d*10 + *(str++) - '0';
00587         if(d>LONGLONG_MAX/10 || hlp<0) {
00588             exp++;
00589             break;
00590         }
00591         else
00592             d = hlp;
00593     }
00594     while(isdigitW(*str)) {
00595         exp++;
00596         str++;
00597     }
00598 
00599     if(*str == '.') str++;
00600 
00601     if(isdigitW(*str))
00602         ret_nan = FALSE;
00603 
00604     while(isdigitW(*str)) {
00605         hlp = d*10 + *(str++) - '0';
00606         if(d>LONGLONG_MAX/10 || hlp<0)
00607             break;
00608 
00609         d = hlp;
00610         exp--;
00611     }
00612     while(isdigitW(*str))
00613         str++;
00614 
00615     if(*str && !ret_nan && (*str=='e' || *str=='E')) {
00616         int sign = 1, e = 0;
00617 
00618         str++;
00619         if(*str == '+')
00620             str++;
00621         else if(*str == '-') {
00622             sign = -1;
00623             str++;
00624         }
00625 
00626         while(isdigitW(*str)) {
00627             if(e>INT_MAX/10 || (e = e*10 + *str++ - '0')<0)
00628                 e = INT_MAX;
00629         }
00630         e *= sign;
00631 
00632         if(exp<0 && e<0 && exp+e>0) exp = INT_MIN;
00633         else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX;
00634         else exp += e;
00635     }
00636 
00637     SysFreeString(val_str);
00638 
00639     if(ret_nan) {
00640         if(retv)
00641             num_set_nan(retv);
00642         return S_OK;
00643     }
00644 
00645     V_VT(retv) = VT_R8;
00646     V_R8(retv) = (double)(positive?d:-d)*pow(10, exp);
00647     return S_OK;
00648 }
00649 
00650 static inline int hex_to_int(const WCHAR wch) {
00651     if(toupperW(wch)>='A' && toupperW(wch)<='F') return toupperW(wch)-'A'+10;
00652     if(isdigitW(wch)) return wch-'0';
00653     return -1;
00654 }
00655 
00656 static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00657         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00658 {
00659     BSTR ret, str;
00660     const WCHAR *ptr;
00661     DWORD len = 0;
00662     HRESULT hres;
00663 
00664     TRACE("\n");
00665 
00666     if(!arg_cnt(dp)) {
00667         if(retv) {
00668             ret = SysAllocString(undefinedW);
00669             if(!ret)
00670                 return E_OUTOFMEMORY;
00671 
00672             V_VT(retv) = VT_BSTR;
00673             V_BSTR(retv) = ret;
00674         }
00675 
00676         return S_OK;
00677     }
00678 
00679     hres = to_string(ctx, get_arg(dp, 0), ei, &str);
00680     if(FAILED(hres))
00681         return hres;
00682 
00683     for(ptr=str; *ptr; ptr++) {
00684         if(*ptr == '%') {
00685             if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1)
00686                 ptr += 2;
00687             else if(*(ptr+1)=='u' && hex_to_int(*(ptr+2))!=-1 && hex_to_int(*(ptr+3))!=-1
00688                     && hex_to_int(*(ptr+4))!=-1 && hex_to_int(*(ptr+5))!=-1)
00689                 ptr += 5;
00690         }
00691 
00692         len++;
00693     }
00694 
00695     ret = SysAllocStringLen(NULL, len);
00696     if(!ret) {
00697         SysFreeString(str);
00698         return E_OUTOFMEMORY;
00699     }
00700 
00701     len = 0;
00702     for(ptr=str; *ptr; ptr++) {
00703         if(*ptr == '%') {
00704             if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1) {
00705                 ret[len] = (hex_to_int(*(ptr+1))<<4) + hex_to_int(*(ptr+2));
00706                 ptr += 2;
00707             }
00708             else if(*(ptr+1)=='u' && hex_to_int(*(ptr+2))!=-1 && hex_to_int(*(ptr+3))!=-1
00709                     && hex_to_int(*(ptr+4))!=-1 && hex_to_int(*(ptr+5))!=-1) {
00710                 ret[len] = (hex_to_int(*(ptr+2))<<12) + (hex_to_int(*(ptr+3))<<8)
00711                     + (hex_to_int(*(ptr+4))<<4) + hex_to_int(*(ptr+5));
00712                 ptr += 5;
00713             }
00714             else
00715                 ret[len] = *ptr;
00716         }
00717         else
00718             ret[len] = *ptr;
00719 
00720         len++;
00721     }
00722 
00723     SysFreeString(str);
00724 
00725     if(retv) {
00726         V_VT(retv) = VT_BSTR;
00727         V_BSTR(retv) = ret;
00728     }
00729     else
00730         SysFreeString(ret);
00731 
00732     return S_OK;
00733 }
00734 
00735 static HRESULT JSGlobal_GetObject(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00736         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00737 {
00738     FIXME("\n");
00739     return E_NOTIMPL;
00740 }
00741 
00742 static HRESULT JSGlobal_ScriptEngine(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00743         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00744 {
00745     FIXME("\n");
00746     return E_NOTIMPL;
00747 }
00748 
00749 static HRESULT JSGlobal_ScriptEngineMajorVersion(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00750         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00751 {
00752     FIXME("\n");
00753     return E_NOTIMPL;
00754 }
00755 
00756 static HRESULT JSGlobal_ScriptEngineMinorVersion(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00757         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00758 {
00759     FIXME("\n");
00760     return E_NOTIMPL;
00761 }
00762 
00763 static HRESULT JSGlobal_ScriptEngineBuildVersion(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00764         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00765 {
00766     FIXME("\n");
00767     return E_NOTIMPL;
00768 }
00769 
00770 static HRESULT JSGlobal_CollectGarbage(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00771         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00772 {
00773     FIXME("\n");
00774     return E_NOTIMPL;
00775 }
00776 
00777 static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00778         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00779 {
00780     const WCHAR *ptr;
00781     DWORD len = 0, i;
00782     char buf[4];
00783     BSTR str, ret;
00784     WCHAR *rptr;
00785     HRESULT hres;
00786 
00787     TRACE("\n");
00788 
00789     if(!arg_cnt(dp)) {
00790         if(retv) {
00791             ret = SysAllocString(undefinedW);
00792             if(!ret)
00793                 return E_OUTOFMEMORY;
00794 
00795             V_VT(retv) = VT_BSTR;
00796             V_BSTR(retv) = ret;
00797         }
00798 
00799         return S_OK;
00800     }
00801 
00802     hres = to_string(ctx, get_arg(dp,0), ei, &str);
00803     if(FAILED(hres))
00804         return hres;
00805 
00806     for(ptr = str; *ptr; ptr++) {
00807         if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
00808             len++;
00809         }else {
00810             i = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, NULL, 0, NULL, NULL)*3;
00811             if(!i) {
00812                 SysFreeString(str);
00813                 return throw_uri_error(ctx, ei, IDS_URI_INVALID_CHAR, NULL);
00814             }
00815 
00816             len += i;
00817         }
00818     }
00819 
00820     rptr = ret = SysAllocStringLen(NULL, len);
00821     if(!ret) {
00822         SysFreeString(str);
00823         return E_OUTOFMEMORY;
00824     }
00825 
00826     for(ptr = str; *ptr; ptr++) {
00827         if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
00828             *rptr++ = *ptr;
00829         }else {
00830             len = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, buf, sizeof(buf), NULL, NULL);
00831             for(i=0; i<len; i++) {
00832                 *rptr++ = '%';
00833                 *rptr++ = int_to_char((BYTE)buf[i] >> 4);
00834                 *rptr++ = int_to_char(buf[i] & 0x0f);
00835             }
00836         }
00837     }
00838 
00839     SysFreeString(str);
00840 
00841     TRACE("%s -> %s\n", debugstr_w(str), debugstr_w(ret));
00842     if(retv) {
00843         V_VT(retv) = VT_BSTR;
00844         V_BSTR(retv) = ret;
00845     }else {
00846         SysFreeString(ret);
00847     }
00848     return S_OK;
00849 }
00850 
00851 static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00852         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00853 {
00854     FIXME("\n");
00855     return E_NOTIMPL;
00856 }
00857 
00858 static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00859         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00860 {
00861     BSTR str, ret;
00862     char buf[4];
00863     const WCHAR *ptr;
00864     DWORD len = 0, size, i;
00865     HRESULT hres;
00866 
00867     TRACE("\n");
00868 
00869     if(!arg_cnt(dp)) {
00870         if(retv) {
00871             ret = SysAllocString(undefinedW);
00872             if(!ret)
00873                 return E_OUTOFMEMORY;
00874 
00875             V_VT(retv) = VT_BSTR;
00876             V_BSTR(retv) = ret;
00877         }
00878 
00879         return S_OK;
00880     }
00881 
00882     hres = to_string(ctx, get_arg(dp, 0), ei, &str);
00883     if(FAILED(hres))
00884         return hres;
00885 
00886     for(ptr=str; *ptr; ptr++) {
00887         if(is_uri_unescaped(*ptr))
00888             len++;
00889         else {
00890             size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, NULL, 0, NULL, NULL);
00891             if(!size) {
00892                 SysFreeString(str);
00893                 FIXME("throw Error\n");
00894                 return E_FAIL;
00895             }
00896             len += size*3;
00897         }
00898     }
00899 
00900     ret = SysAllocStringLen(NULL, len);
00901     if(!ret) {
00902         SysFreeString(str);
00903         return E_OUTOFMEMORY;
00904     }
00905 
00906     len = 0;
00907     for(ptr=str; *ptr; ptr++) {
00908         if(is_uri_unescaped(*ptr))
00909             ret[len++] = *ptr;
00910         else {
00911             size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, buf, sizeof(buf), NULL, NULL);
00912             for(i=0; i<size; i++) {
00913                 ret[len++] = '%';
00914                 ret[len++] = int_to_char((BYTE)buf[i] >> 4);
00915                 ret[len++] = int_to_char(buf[i] & 0x0f);
00916             }
00917         }
00918     }
00919 
00920     SysFreeString(str);
00921 
00922     if(retv) {
00923         V_VT(retv) = VT_BSTR;
00924         V_BSTR(retv) = ret;
00925     } else {
00926         SysFreeString(ret);
00927     }
00928 
00929     return S_OK;
00930 }
00931 
00932 /* ECMA-262 3rd Edition    15.1.3.2 */
00933 static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
00934         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
00935 {
00936     BSTR str, ret;
00937     const WCHAR *ptr;
00938     WCHAR *out_ptr;
00939     DWORD len = 0;
00940     HRESULT hres;
00941 
00942     TRACE("\n");
00943 
00944     if(!arg_cnt(dp)) {
00945         if(retv) {
00946             ret = SysAllocString(undefinedW);
00947             if(!ret)
00948                 return E_OUTOFMEMORY;
00949 
00950             V_VT(retv) = VT_BSTR;
00951             V_BSTR(retv) = ret;
00952         }
00953 
00954         return S_OK;
00955     }
00956 
00957     hres = to_string(ctx, get_arg(dp, 0), ei, &str);
00958     if(FAILED(hres))
00959         return hres;
00960 
00961     ptr = str;
00962     while(*ptr) {
00963         if(*ptr == '%') {
00964             char octets[4];
00965             unsigned char mask = 0x80;
00966             int i, size, num_bytes = 0;
00967             if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
00968                 FIXME("Throw URIError: Invalid hex sequence\n");
00969                 SysFreeString(str);
00970                 return E_FAIL;
00971             }
00972             octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
00973             ptr += 3;
00974             while(octets[0] & mask) {
00975                 mask = mask >> 1;
00976                 ++num_bytes;
00977             }
00978             if(num_bytes == 1 || num_bytes > 4) {
00979                 FIXME("Throw URIError: Invalid initial UTF character\n");
00980                 SysFreeString(str);
00981                 return E_FAIL;
00982             }
00983             for(i = 1; i < num_bytes; ++i) {
00984                 if(*ptr != '%'){
00985                     FIXME("Throw URIError: Incomplete UTF sequence\n");
00986                     SysFreeString(str);
00987                     return E_FAIL;
00988                 }
00989                 if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
00990                     FIXME("Throw URIError: Invalid hex sequence\n");
00991                     SysFreeString(str);
00992                     return E_FAIL;
00993                 }
00994                 octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
00995                 ptr += 3;
00996             }
00997             size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, octets,
00998                     num_bytes ? num_bytes : 1, NULL, 0);
00999             if(size == 0) {
01000                 FIXME("Throw URIError: Invalid UTF sequence\n");
01001                 SysFreeString(str);
01002                 return E_FAIL;
01003             }
01004             len += size;
01005         }else {
01006             ++ptr;
01007             ++len;
01008         }
01009     }
01010 
01011     out_ptr = ret = SysAllocStringLen(NULL, len);
01012     if(!ret) {
01013         SysFreeString(str);
01014         return E_OUTOFMEMORY;
01015     }
01016 
01017     ptr = str;
01018     while(*ptr) {
01019         if(*ptr == '%') {
01020             char octets[4];
01021             unsigned char mask = 0x80;
01022             int i, size, num_bytes = 0;
01023             octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
01024             ptr += 3;
01025             while(octets[0] & mask) {
01026                 mask = mask >> 1;
01027                 ++num_bytes;
01028             }
01029             for(i = 1; i < num_bytes; ++i) {
01030                 octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
01031                 ptr += 3;
01032             }
01033             size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, octets,
01034                     num_bytes ? num_bytes : 1, out_ptr, len);
01035             len -= size;
01036             out_ptr += size;
01037         }else {
01038             *out_ptr++ = *ptr++;
01039             --len;
01040         }
01041     }
01042 
01043     SysFreeString(str);
01044 
01045     if(retv) {
01046         V_VT(retv) = VT_BSTR;
01047         V_BSTR(retv) = ret;
01048     }else {
01049         SysFreeString(ret);
01050     }
01051 
01052     return S_OK;
01053 }
01054 
01055 static const builtin_prop_t JSGlobal_props[] = {
01056     {ActiveXObjectW,             JSGlobal_ActiveXObject,             PROPF_CONSTR|1},
01057     {ArrayW,                     JSGlobal_Array,                     PROPF_CONSTR|1},
01058     {BooleanW,                   JSGlobal_Boolean,                   PROPF_CONSTR|1},
01059     {CollectGarbageW,            JSGlobal_CollectGarbage,            PROPF_METHOD},
01060     {DateW,                      JSGlobal_Date,                      PROPF_CONSTR|7},
01061     {EnumeratorW,                JSGlobal_Enumerator,                PROPF_METHOD|7},
01062     {ErrorW,                     JSGlobal_Error,                     PROPF_CONSTR|1},
01063     {EvalErrorW,                 JSGlobal_EvalError,                 PROPF_CONSTR|1},
01064     {FunctionW,                  JSGlobal_Function,                  PROPF_CONSTR|1},
01065     {_GetObjectW,                JSGlobal_GetObject,                 PROPF_METHOD|2},
01066     {InfinityW,                  JSGlobal_Infinity,                  0},
01067 /*  {MathW,                      JSGlobal_Math,                      0},  */
01068     {NaNW,                       JSGlobal_NaN,                       0},
01069     {NumberW,                    JSGlobal_Number,                    PROPF_CONSTR|1},
01070     {ObjectW,                    JSGlobal_Object,                    PROPF_CONSTR|1},
01071     {RangeErrorW,                JSGlobal_RangeError,                PROPF_CONSTR|1},
01072     {ReferenceErrorW,            JSGlobal_ReferenceError,            PROPF_CONSTR|1},
01073     {RegExpW,                    JSGlobal_RegExp,                    PROPF_CONSTR|2},
01074     {ScriptEngineW,              JSGlobal_ScriptEngine,              PROPF_METHOD},
01075     {ScriptEngineBuildVersionW,  JSGlobal_ScriptEngineBuildVersion,  PROPF_METHOD},
01076     {ScriptEngineMajorVersionW,  JSGlobal_ScriptEngineMajorVersion,  PROPF_METHOD},
01077     {ScriptEngineMinorVersionW,  JSGlobal_ScriptEngineMinorVersion,  PROPF_METHOD},
01078     {StringW,                    JSGlobal_String,                    PROPF_CONSTR|1},
01079     {SyntaxErrorW,               JSGlobal_SyntaxError,               PROPF_CONSTR|1},
01080     {TypeErrorW,                 JSGlobal_TypeError,                 PROPF_CONSTR|1},
01081     {URIErrorW,                  JSGlobal_URIError,                  PROPF_CONSTR|1},
01082     {VBArrayW,                   JSGlobal_VBArray,                   PROPF_METHOD|1},
01083     {decodeURIW,                 JSGlobal_decodeURI,                 PROPF_METHOD|1},
01084     {decodeURIComponentW,        JSGlobal_decodeURIComponent,        PROPF_METHOD|1},
01085     {encodeURIW,                 JSGlobal_encodeURI,                 PROPF_METHOD|1},
01086     {encodeURIComponentW,        JSGlobal_encodeURIComponent,        PROPF_METHOD|1},
01087     {escapeW,                    JSGlobal_escape,                    PROPF_METHOD|1},
01088     {evalW,                      JSGlobal_eval,                      PROPF_METHOD|1},
01089     {isFiniteW,                  JSGlobal_isFinite,                  PROPF_METHOD|1},
01090     {isNaNW,                     JSGlobal_isNaN,                     PROPF_METHOD|1},
01091     {parseFloatW,                JSGlobal_parseFloat,                PROPF_METHOD|1},
01092     {parseIntW,                  JSGlobal_parseInt,                  PROPF_METHOD|2},
01093     {unescapeW,                  JSGlobal_unescape,                  PROPF_METHOD|1}
01094 };
01095 
01096 static const builtin_info_t JSGlobal_info = {
01097     JSCLASS_GLOBAL,
01098     {NULL, NULL, 0},
01099     sizeof(JSGlobal_props)/sizeof(*JSGlobal_props),
01100     JSGlobal_props,
01101     NULL,
01102     NULL
01103 };
01104 
01105 static HRESULT init_constructors(script_ctx_t *ctx, DispatchEx *object_prototype)
01106 {
01107     HRESULT hres;
01108 
01109     hres = init_function_constr(ctx, object_prototype);
01110     if(FAILED(hres))
01111         return hres;
01112 
01113     hres = create_object_constr(ctx, object_prototype, &ctx->object_constr);
01114     if(FAILED(hres))
01115         return hres;
01116 
01117     hres = create_activex_constr(ctx, &ctx->activex_constr);
01118     if(FAILED(hres))
01119         return hres;
01120 
01121     hres = create_array_constr(ctx, object_prototype, &ctx->array_constr);
01122     if(FAILED(hres))
01123         return hres;
01124 
01125     hres = create_bool_constr(ctx, object_prototype, &ctx->bool_constr);
01126     if(FAILED(hres))
01127         return hres;
01128 
01129     hres = create_date_constr(ctx, object_prototype, &ctx->date_constr);
01130     if(FAILED(hres))
01131         return hres;
01132 
01133     hres = init_error_constr(ctx, object_prototype);
01134     if(FAILED(hres))
01135         return hres;
01136 
01137     hres = create_number_constr(ctx, object_prototype, &ctx->number_constr);
01138     if(FAILED(hres))
01139         return hres;
01140 
01141     hres = create_regexp_constr(ctx, object_prototype, &ctx->regexp_constr);
01142     if(FAILED(hres))
01143         return hres;
01144 
01145     hres = create_string_constr(ctx, object_prototype, &ctx->string_constr);
01146     if(FAILED(hres))
01147         return hres;
01148 
01149     return S_OK;
01150 }
01151 
01152 HRESULT init_global(script_ctx_t *ctx)
01153 {
01154     DispatchEx *math, *object_prototype;
01155     VARIANT var;
01156     HRESULT hres;
01157 
01158     if(ctx->global)
01159         return S_OK;
01160 
01161     hres = create_object_prototype(ctx, &object_prototype);
01162     if(FAILED(hres))
01163         return hres;
01164 
01165     hres = init_constructors(ctx, object_prototype);
01166     jsdisp_release(object_prototype);
01167     if(FAILED(hres))
01168         return hres;
01169 
01170     hres = create_dispex(ctx, &JSGlobal_info, NULL, &ctx->global);
01171     if(FAILED(hres))
01172         return hres;
01173 
01174     hres = create_math(ctx, &math);
01175     if(FAILED(hres))
01176         return hres;
01177 
01178     V_VT(&var) = VT_EMPTY;
01179     hres = jsdisp_propput_name(ctx->global, undefinedW, &var, NULL/*FIXME*/, NULL/*FIXME*/);
01180     if(FAILED(hres))
01181         return hres;
01182 
01183     V_VT(&var) = VT_DISPATCH;
01184     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(math);
01185     hres = jsdisp_propput_name(ctx->global, MathW, &var, NULL/*FIXME*/, NULL/*FIXME*/);
01186     jsdisp_release(math);
01187 
01188     return hres;
01189 }

Generated on Sun May 27 2012 04:24:21 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.