1 /* 2 * Copyright 2008 Jacek Caban for CodeWeavers 3 * Copyright 2009 Piotr Caban 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include <assert.h> 21 22 #include "jscript.h" 23 24 #include "wine/debug.h" 25 26 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 27 28 typedef struct { 29 jsdisp_t dispex; 30 31 BOOL val; 32 } BoolInstance; 33 34 static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; 35 static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; 36 37 static inline BoolInstance *bool_from_jsdisp(jsdisp_t *jsdisp) 38 { 39 return CONTAINING_RECORD(jsdisp, BoolInstance, dispex); 40 } 41 42 static inline BoolInstance *bool_from_vdisp(vdisp_t *vdisp) 43 { 44 return bool_from_jsdisp(vdisp->u.jsdisp); 45 } 46 47 static inline BoolInstance *bool_this(vdisp_t *jsthis) 48 { 49 return is_vclass(jsthis, JSCLASS_BOOLEAN) ? bool_from_vdisp(jsthis) : NULL; 50 } 51 52 BOOL bool_obj_value(jsdisp_t *obj) 53 { 54 assert(is_class(obj, JSCLASS_BOOLEAN)); 55 return bool_from_jsdisp(obj)->val; 56 } 57 58 /* ECMA-262 3rd Edition 15.6.4.2 */ 59 static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) 60 { 61 BoolInstance *bool; 62 63 static const WCHAR trueW[] = {'t','r','u','e',0}; 64 static const WCHAR falseW[] = {'f','a','l','s','e',0}; 65 66 TRACE("\n"); 67 68 if(!(bool = bool_this(jsthis))) 69 return throw_type_error(ctx, JS_E_BOOLEAN_EXPECTED, NULL); 70 71 if(r) { 72 jsstr_t *val; 73 74 val = jsstr_alloc(bool->val ? trueW : falseW); 75 if(!val) 76 return E_OUTOFMEMORY; 77 78 *r = jsval_string(val); 79 } 80 81 return S_OK; 82 } 83 84 /* ECMA-262 3rd Edition 15.6.4.3 */ 85 static HRESULT Bool_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) 86 { 87 BoolInstance *bool; 88 89 TRACE("\n"); 90 91 if(!(bool = bool_this(jsthis))) 92 return throw_type_error(ctx, JS_E_BOOLEAN_EXPECTED, NULL); 93 94 if(r) 95 *r = jsval_bool(bool->val); 96 return S_OK; 97 } 98 99 static HRESULT Bool_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, 100 jsval_t *r) 101 { 102 TRACE("\n"); 103 104 switch(flags) { 105 case INVOKE_FUNC: 106 return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL); 107 default: 108 FIXME("unimplemented flags %x\n", flags); 109 return E_NOTIMPL; 110 } 111 112 return S_OK; 113 114 } 115 116 static const builtin_prop_t Bool_props[] = { 117 {toStringW, Bool_toString, PROPF_METHOD}, 118 {valueOfW, Bool_valueOf, PROPF_METHOD} 119 }; 120 121 static const builtin_info_t Bool_info = { 122 JSCLASS_BOOLEAN, 123 {NULL, Bool_value, 0}, 124 sizeof(Bool_props)/sizeof(*Bool_props), 125 Bool_props, 126 NULL, 127 NULL 128 }; 129 130 static const builtin_info_t BoolInst_info = { 131 JSCLASS_BOOLEAN, 132 {NULL, Bool_value, 0}, 133 0, NULL, 134 NULL, 135 NULL 136 }; 137 138 static HRESULT BoolConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, 139 jsval_t *r) 140 { 141 BOOL value = FALSE; 142 HRESULT hres; 143 144 if(argc) { 145 hres = to_boolean(argv[0], &value); 146 if(FAILED(hres)) 147 return hres; 148 } 149 150 switch(flags) { 151 case DISPATCH_CONSTRUCT: { 152 jsdisp_t *bool; 153 154 hres = create_bool(ctx, value, &bool); 155 if(FAILED(hres)) 156 return hres; 157 158 *r = jsval_obj(bool); 159 return S_OK; 160 } 161 162 case INVOKE_FUNC: 163 if(r) 164 *r = jsval_bool(value); 165 return S_OK; 166 167 default: 168 FIXME("unimplemented flags %x\n", flags); 169 return E_NOTIMPL; 170 } 171 172 return S_OK; 173 } 174 175 static HRESULT alloc_bool(script_ctx_t *ctx, jsdisp_t *object_prototype, BoolInstance **ret) 176 { 177 BoolInstance *bool; 178 HRESULT hres; 179 180 bool = heap_alloc_zero(sizeof(BoolInstance)); 181 if(!bool) 182 return E_OUTOFMEMORY; 183 184 if(object_prototype) 185 hres = init_dispex(&bool->dispex, ctx, &Bool_info, object_prototype); 186 else 187 hres = init_dispex_from_constr(&bool->dispex, ctx, &BoolInst_info, ctx->bool_constr); 188 189 if(FAILED(hres)) { 190 heap_free(bool); 191 return hres; 192 } 193 194 *ret = bool; 195 return S_OK; 196 } 197 198 HRESULT create_bool_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret) 199 { 200 BoolInstance *bool; 201 HRESULT hres; 202 203 static const WCHAR BooleanW[] = {'B','o','o','l','e','a','n',0}; 204 205 hres = alloc_bool(ctx, object_prototype, &bool); 206 if(FAILED(hres)) 207 return hres; 208 209 hres = create_builtin_constructor(ctx, BoolConstr_value, BooleanW, NULL, 210 PROPF_CONSTR|1, &bool->dispex, ret); 211 212 jsdisp_release(&bool->dispex); 213 return hres; 214 } 215 216 HRESULT create_bool(script_ctx_t *ctx, BOOL b, jsdisp_t **ret) 217 { 218 BoolInstance *bool; 219 HRESULT hres; 220 221 hres = alloc_bool(ctx, NULL, &bool); 222 if(FAILED(hres)) 223 return hres; 224 225 bool->val = b; 226 227 *ret = &bool->dispex; 228 return S_OK; 229 } 230