WebAssembly: construct 32-bit encodedJSValue properly
[WebKit-https.git] / Source / JavaScriptCore / wasm / js / WebAssemblyTableConstructor.cpp
1 /*
2  * Copyright (C) 2016 Apple 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebAssemblyTableConstructor.h"
28
29 #if ENABLE(WEBASSEMBLY)
30
31 #include "FunctionPrototype.h"
32 #include "JSCInlines.h"
33 #include "JSWebAssemblyHelpers.h"
34 #include "JSWebAssemblyTable.h"
35 #include "WebAssemblyTablePrototype.h"
36
37 #include "WebAssemblyTableConstructor.lut.h"
38
39 namespace JSC {
40
41 const ClassInfo WebAssemblyTableConstructor::s_info = { "Function", &Base::s_info, &constructorTableWebAssemblyTable, CREATE_METHOD_TABLE(WebAssemblyTableConstructor) };
42
43 /* Source for WebAssemblyTableConstructor.lut.h
44  @begin constructorTableWebAssemblyTable
45  @end
46  */
47
48 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyTable(ExecState* exec)
49 {
50     VM& vm = exec->vm();
51     auto throwScope = DECLARE_THROW_SCOPE(vm);
52
53     JSObject* memoryDescriptor;
54     {
55         JSValue argument = exec->argument(0);
56         if (!argument.isObject())
57             return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Table expects its first argument to be an object"))));
58         memoryDescriptor = jsCast<JSObject*>(argument);
59     }
60
61     {
62         Identifier elementIdent = Identifier::fromString(&vm, "element");
63         JSValue elementValue = memoryDescriptor->get(exec, elementIdent);
64         RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
65         String elementString = elementValue.toWTFString(exec);
66         RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
67         if (elementString != "anyfunc")
68             return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Table expects its 'element' field to be the string 'anyfunc'"))));
69     }
70
71     Identifier initialIdent = Identifier::fromString(&vm, "initial");
72     JSValue initialSizeValue = memoryDescriptor->get(exec, initialIdent);
73     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
74     uint32_t initial = toNonWrappingUint32(exec, initialSizeValue);
75     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
76
77     std::optional<uint32_t> maximum;
78     Identifier maximumIdent = Identifier::fromString(&vm, "maximum");
79     bool hasProperty = memoryDescriptor->hasProperty(exec, maximumIdent);
80     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
81     if (hasProperty) {
82         JSValue maxSizeValue = memoryDescriptor->get(exec, maximumIdent);
83         RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
84         maximum = toNonWrappingUint32(exec, maxSizeValue);
85         RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
86
87         if (initial > *maximum) {
88             return JSValue::encode(throwException(exec, throwScope,
89                 createRangeError(exec, ASCIILiteral("'maximum' property must be greater than or equal to the 'initial' property"))));
90         }
91     }
92
93     throwScope.release();
94     return JSValue::encode(JSWebAssemblyTable::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyTableStructure(), initial, maximum));
95 }
96
97 static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyTable(ExecState* state)
98 {
99     VM& vm = state->vm();
100     auto scope = DECLARE_THROW_SCOPE(vm);
101     return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(state, scope, "WebAssembly.Table"));
102 }
103
104 WebAssemblyTableConstructor* WebAssemblyTableConstructor::create(VM& vm, Structure* structure, WebAssemblyTablePrototype* thisPrototype)
105 {
106     auto* constructor = new (NotNull, allocateCell<WebAssemblyTableConstructor>(vm.heap)) WebAssemblyTableConstructor(vm, structure);
107     constructor->finishCreation(vm, thisPrototype);
108     return constructor;
109 }
110
111 Structure* WebAssemblyTableConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
112 {
113     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
114 }
115
116 void WebAssemblyTableConstructor::finishCreation(VM& vm, WebAssemblyTablePrototype* prototype)
117 {
118     Base::finishCreation(vm, ASCIILiteral("Table"));
119     putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
120     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
121 }
122
123 WebAssemblyTableConstructor::WebAssemblyTableConstructor(VM& vm, Structure* structure)
124     : Base(vm, structure)
125 {
126 }
127
128 ConstructType WebAssemblyTableConstructor::getConstructData(JSCell*, ConstructData& constructData)
129 {
130     constructData.native.function = constructJSWebAssemblyTable;
131     return ConstructType::Host;
132 }
133
134 CallType WebAssemblyTableConstructor::getCallData(JSCell*, CallData& callData)
135 {
136     callData.native.function = callJSWebAssemblyTable;
137     return CallType::Host;
138 }
139
140 void WebAssemblyTableConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
141 {
142     auto* thisObject = jsCast<WebAssemblyTableConstructor*>(cell);
143     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
144     Base::visitChildren(thisObject, visitor);
145 }
146
147 } // namespace JSC
148
149 #endif // ENABLE(WEBASSEMBLY)
150