• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "JSDataView.h"
28 
29 #include "DataView.h"
30 #include "ExceptionCode.h"
31 #include "JSArrayBufferViewHelper.h"
32 #include <wtf/MathExtras.h>
33 
34 using namespace JSC;
35 
36 namespace WebCore {
37 
38 enum DataViewAccessType {
39     AccessDataViewMemberAsInt8,
40     AccessDataViewMemberAsUint8,
41     AccessDataViewMemberAsFloat32,
42     AccessDataViewMemberAsFloat64
43 };
44 
toJS(ExecState * exec,JSDOMGlobalObject * globalObject,DataView * object)45 JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, DataView* object)
46 {
47     return wrap<JSDataView>(exec, globalObject, object);
48 }
49 
constructJSDataView(ExecState * exec)50 EncodedJSValue JSC_HOST_CALL JSDataViewConstructor::constructJSDataView(ExecState* exec)
51 {
52     if (exec->argument(0).isNull() || !exec->argument(0).isObject())
53         return throwVMTypeError(exec);
54 
55     RefPtr<DataView> view = constructArrayBufferViewWithArrayBufferArgument<DataView, char>(exec);
56     if (!view.get()) {
57         setDOMException(exec, INDEX_SIZE_ERR);
58         return JSValue::encode(jsUndefined());
59     }
60 
61     JSDataViewConstructor* jsConstructor = static_cast<JSDataViewConstructor*>(exec->callee());
62     return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), view.get())));
63 }
64 
getDataViewMember(ExecState * exec,DataView * imp,DataViewAccessType type)65 static JSValue getDataViewMember(ExecState* exec, DataView* imp, DataViewAccessType type)
66 {
67     if (exec->argumentCount() < 1)
68         return throwError(exec, createSyntaxError(exec, "Not enough arguments"));
69     ExceptionCode ec = 0;
70     unsigned byteOffset = exec->argument(0).toUInt32(exec);
71     if (exec->hadException())
72         return jsUndefined();
73 
74     bool littleEndian = false;
75     if (exec->argumentCount() > 1 && (type == AccessDataViewMemberAsFloat32 || type == AccessDataViewMemberAsFloat64)) {
76         littleEndian = exec->argument(1).toBoolean(exec);
77         if (exec->hadException())
78             return jsUndefined();
79     }
80 
81     JSC::JSValue result;
82     switch (type) {
83     case AccessDataViewMemberAsInt8:
84         result = jsNumber(imp->getInt8(byteOffset, ec));
85         break;
86     case AccessDataViewMemberAsUint8:
87         result = jsNumber(imp->getUint8(byteOffset, ec));
88         break;
89     case AccessDataViewMemberAsFloat32:
90     case AccessDataViewMemberAsFloat64: {
91         double value = (type == AccessDataViewMemberAsFloat32) ? imp->getFloat32(byteOffset, littleEndian, ec) : imp->getFloat64(byteOffset, littleEndian, ec);
92         result = isnan(value) ? JSValue(nonInlineNaN()) : jsNumber(value);
93         break;
94     } default:
95         ASSERT_NOT_REACHED();
96         break;
97     }
98     setDOMException(exec, ec);
99     return result;
100 }
101 
getInt8(ExecState * exec)102 JSValue JSDataView::getInt8(ExecState* exec)
103 {
104     return getDataViewMember(exec, static_cast<DataView*>(impl()), AccessDataViewMemberAsInt8);
105 }
106 
getUint8(ExecState * exec)107 JSValue JSDataView::getUint8(ExecState* exec)
108 {
109     return getDataViewMember(exec, static_cast<DataView*>(impl()), AccessDataViewMemberAsUint8);
110 }
111 
getFloat32(ExecState * exec)112 JSValue JSDataView::getFloat32(ExecState* exec)
113 {
114     return getDataViewMember(exec, static_cast<DataView*>(impl()), AccessDataViewMemberAsFloat32);
115 }
116 
getFloat64(ExecState * exec)117 JSValue JSDataView::getFloat64(ExecState* exec)
118 {
119     return getDataViewMember(exec, static_cast<DataView*>(impl()), AccessDataViewMemberAsFloat64);
120 }
121 
setDataViewMember(ExecState * exec,DataView * imp,DataViewAccessType type)122 static JSValue setDataViewMember(ExecState* exec, DataView* imp, DataViewAccessType type)
123 {
124     if (exec->argumentCount() < 2)
125         return throwError(exec, createSyntaxError(exec, "Not enough arguments"));
126     ExceptionCode ec = 0;
127     unsigned byteOffset = exec->argument(0).toUInt32(exec);
128     if (exec->hadException())
129         return jsUndefined();
130     int value = exec->argument(1).toInt32(exec);
131     if (exec->hadException())
132         return jsUndefined();
133 
134     switch (type) {
135     case AccessDataViewMemberAsInt8:
136         imp->setInt8(byteOffset, static_cast<int8_t>(value), ec);
137         break;
138     case AccessDataViewMemberAsUint8:
139         imp->setUint8(byteOffset, static_cast<uint8_t>(value), ec);
140         break;
141     default:
142         ASSERT_NOT_REACHED();
143         break;
144     }
145     setDOMException(exec, ec);
146     return jsUndefined();
147 }
148 
setInt8(ExecState * exec)149 JSValue JSDataView::setInt8(ExecState* exec)
150 {
151     return setDataViewMember(exec, static_cast<DataView*>(impl()), AccessDataViewMemberAsInt8);
152 }
153 
setUint8(ExecState * exec)154 JSValue JSDataView::setUint8(ExecState* exec)
155 {
156     return setDataViewMember(exec, static_cast<DataView*>(impl()), AccessDataViewMemberAsUint8);
157 }
158 
159 } // namespace WebCore
160