js/src/jsbool.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /*
michael@0 8 * JS boolean implementation.
michael@0 9 */
michael@0 10
michael@0 11 #include "jsboolinlines.h"
michael@0 12
michael@0 13 #include "jsapi.h"
michael@0 14 #include "jsatom.h"
michael@0 15 #include "jscntxt.h"
michael@0 16 #include "jsobj.h"
michael@0 17 #include "jstypes.h"
michael@0 18
michael@0 19 #include "vm/GlobalObject.h"
michael@0 20 #include "vm/ProxyObject.h"
michael@0 21 #include "vm/StringBuffer.h"
michael@0 22
michael@0 23 #include "vm/BooleanObject-inl.h"
michael@0 24
michael@0 25 using namespace js;
michael@0 26 using namespace js::types;
michael@0 27
michael@0 28 const Class BooleanObject::class_ = {
michael@0 29 "Boolean",
michael@0 30 JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
michael@0 31 JS_PropertyStub, /* addProperty */
michael@0 32 JS_DeletePropertyStub, /* delProperty */
michael@0 33 JS_PropertyStub, /* getProperty */
michael@0 34 JS_StrictPropertyStub, /* setProperty */
michael@0 35 JS_EnumerateStub,
michael@0 36 JS_ResolveStub,
michael@0 37 JS_ConvertStub
michael@0 38 };
michael@0 39
michael@0 40 MOZ_ALWAYS_INLINE bool
michael@0 41 IsBoolean(HandleValue v)
michael@0 42 {
michael@0 43 return v.isBoolean() || (v.isObject() && v.toObject().is<BooleanObject>());
michael@0 44 }
michael@0 45
michael@0 46 #if JS_HAS_TOSOURCE
michael@0 47 MOZ_ALWAYS_INLINE bool
michael@0 48 bool_toSource_impl(JSContext *cx, CallArgs args)
michael@0 49 {
michael@0 50 HandleValue thisv = args.thisv();
michael@0 51 JS_ASSERT(IsBoolean(thisv));
michael@0 52
michael@0 53 bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();
michael@0 54
michael@0 55 StringBuffer sb(cx);
michael@0 56 if (!sb.append("(new Boolean(") || !BooleanToStringBuffer(b, sb) || !sb.append("))"))
michael@0 57 return false;
michael@0 58
michael@0 59 JSString *str = sb.finishString();
michael@0 60 if (!str)
michael@0 61 return false;
michael@0 62 args.rval().setString(str);
michael@0 63 return true;
michael@0 64 }
michael@0 65
michael@0 66 static bool
michael@0 67 bool_toSource(JSContext *cx, unsigned argc, Value *vp)
michael@0 68 {
michael@0 69 CallArgs args = CallArgsFromVp(argc, vp);
michael@0 70 return CallNonGenericMethod<IsBoolean, bool_toSource_impl>(cx, args);
michael@0 71 }
michael@0 72 #endif
michael@0 73
michael@0 74 MOZ_ALWAYS_INLINE bool
michael@0 75 bool_toString_impl(JSContext *cx, CallArgs args)
michael@0 76 {
michael@0 77 HandleValue thisv = args.thisv();
michael@0 78 JS_ASSERT(IsBoolean(thisv));
michael@0 79
michael@0 80 bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();
michael@0 81 args.rval().setString(js_BooleanToString(cx, b));
michael@0 82 return true;
michael@0 83 }
michael@0 84
michael@0 85 static bool
michael@0 86 bool_toString(JSContext *cx, unsigned argc, Value *vp)
michael@0 87 {
michael@0 88 CallArgs args = CallArgsFromVp(argc, vp);
michael@0 89 return CallNonGenericMethod<IsBoolean, bool_toString_impl>(cx, args);
michael@0 90 }
michael@0 91
michael@0 92 MOZ_ALWAYS_INLINE bool
michael@0 93 bool_valueOf_impl(JSContext *cx, CallArgs args)
michael@0 94 {
michael@0 95 HandleValue thisv = args.thisv();
michael@0 96 JS_ASSERT(IsBoolean(thisv));
michael@0 97
michael@0 98 bool b = thisv.isBoolean() ? thisv.toBoolean() : thisv.toObject().as<BooleanObject>().unbox();
michael@0 99 args.rval().setBoolean(b);
michael@0 100 return true;
michael@0 101 }
michael@0 102
michael@0 103 static bool
michael@0 104 bool_valueOf(JSContext *cx, unsigned argc, Value *vp)
michael@0 105 {
michael@0 106 CallArgs args = CallArgsFromVp(argc, vp);
michael@0 107 return CallNonGenericMethod<IsBoolean, bool_valueOf_impl>(cx, args);
michael@0 108 }
michael@0 109
michael@0 110 static const JSFunctionSpec boolean_methods[] = {
michael@0 111 #if JS_HAS_TOSOURCE
michael@0 112 JS_FN(js_toSource_str, bool_toSource, 0, 0),
michael@0 113 #endif
michael@0 114 JS_FN(js_toString_str, bool_toString, 0, 0),
michael@0 115 JS_FS_END
michael@0 116 };
michael@0 117
michael@0 118 static bool
michael@0 119 Boolean(JSContext *cx, unsigned argc, Value *vp)
michael@0 120 {
michael@0 121 CallArgs args = CallArgsFromVp(argc, vp);
michael@0 122
michael@0 123 bool b = args.length() != 0 ? JS::ToBoolean(args[0]) : false;
michael@0 124
michael@0 125 if (args.isConstructing()) {
michael@0 126 JSObject *obj = BooleanObject::create(cx, b);
michael@0 127 if (!obj)
michael@0 128 return false;
michael@0 129 args.rval().setObject(*obj);
michael@0 130 } else {
michael@0 131 args.rval().setBoolean(b);
michael@0 132 }
michael@0 133 return true;
michael@0 134 }
michael@0 135
michael@0 136 JSObject *
michael@0 137 js_InitBooleanClass(JSContext *cx, HandleObject obj)
michael@0 138 {
michael@0 139 JS_ASSERT(obj->isNative());
michael@0 140
michael@0 141 Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
michael@0 142
michael@0 143 RootedObject booleanProto (cx, global->createBlankPrototype(cx, &BooleanObject::class_));
michael@0 144 if (!booleanProto)
michael@0 145 return nullptr;
michael@0 146 booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
michael@0 147
michael@0 148 RootedFunction ctor(cx, global->createConstructor(cx, Boolean, cx->names().Boolean, 1));
michael@0 149 if (!ctor)
michael@0 150 return nullptr;
michael@0 151
michael@0 152 if (!LinkConstructorAndPrototype(cx, ctor, booleanProto))
michael@0 153 return nullptr;
michael@0 154
michael@0 155 if (!DefinePropertiesAndBrand(cx, booleanProto, nullptr, boolean_methods))
michael@0 156 return nullptr;
michael@0 157
michael@0 158 Handle<PropertyName*> valueOfName = cx->names().valueOf;
michael@0 159 RootedFunction
michael@0 160 valueOf(cx, NewFunction(cx, NullPtr(), bool_valueOf, 0, JSFunction::NATIVE_FUN,
michael@0 161 global, valueOfName));
michael@0 162 if (!valueOf)
michael@0 163 return nullptr;
michael@0 164
michael@0 165 RootedValue value(cx, ObjectValue(*valueOf));
michael@0 166 if (!JSObject::defineProperty(cx, booleanProto, valueOfName, value,
michael@0 167 JS_PropertyStub, JS_StrictPropertyStub, 0))
michael@0 168 {
michael@0 169 return nullptr;
michael@0 170 }
michael@0 171
michael@0 172 if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Boolean, ctor, booleanProto))
michael@0 173 return nullptr;
michael@0 174
michael@0 175 return booleanProto;
michael@0 176 }
michael@0 177
michael@0 178 JSString *
michael@0 179 js_BooleanToString(ExclusiveContext *cx, bool b)
michael@0 180 {
michael@0 181 return b ? cx->names().true_ : cx->names().false_;
michael@0 182 }
michael@0 183
michael@0 184 JS_PUBLIC_API(bool)
michael@0 185 js::ToBooleanSlow(HandleValue v)
michael@0 186 {
michael@0 187 if (v.isString())
michael@0 188 return v.toString()->length() != 0;
michael@0 189
michael@0 190 JS_ASSERT(v.isObject());
michael@0 191 return !EmulatesUndefined(&v.toObject());
michael@0 192 }
michael@0 193
michael@0 194 /*
michael@0 195 * This slow path is only ever taken for proxies wrapping Boolean objects
michael@0 196 * The only caller of the fast path, JSON's PreprocessValue, ensures that.
michael@0 197 */
michael@0 198 bool
michael@0 199 js::BooleanGetPrimitiveValueSlow(HandleObject wrappedBool)
michael@0 200 {
michael@0 201 JSObject *obj = wrappedBool->as<ProxyObject>().target();
michael@0 202 JS_ASSERT(obj);
michael@0 203 return obj->as<BooleanObject>().unbox();
michael@0 204 }

mercurial