1/*
2 * Copyright (C) 2016-2017 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
39namespace JSC {
40
41const ClassInfo WebAssemblyTableConstructor::s_info = { "Function", &Base::s_info, &constructorTableWebAssemblyTable, nullptr, CREATE_METHOD_TABLE(WebAssemblyTableConstructor) };
42
43/* Source for WebAssemblyTableConstructor.lut.h
44 @begin constructorTableWebAssemblyTable
45 @end
46 */
47
48static 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, "WebAssembly.Table expects its first argument to be an object"_s)));
58 memoryDescriptor = jsCast<JSObject*>(argument);
59 }
60
61 Wasm::TableElementType type;
62 {
63 Identifier elementIdent = Identifier::fromString(&vm, "element");
64 JSValue elementValue = memoryDescriptor->get(exec, elementIdent);
65 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
66 String elementString = elementValue.toWTFString(exec);
67 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
68 if (elementString == "anyfunc")
69 type = Wasm::TableElementType::Funcref;
70 else if (elementString == "anyref")
71 type = Wasm::TableElementType::Anyref;
72 else
73 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Table expects its 'element' field to be the string 'anyfunc' or 'anyref'"_s)));
74 }
75
76 Identifier initialIdent = Identifier::fromString(&vm, "initial");
77 JSValue initialSizeValue = memoryDescriptor->get(exec, initialIdent);
78 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
79 uint32_t initial = toNonWrappingUint32(exec, initialSizeValue);
80 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
81
82 Optional<uint32_t> maximum;
83 Identifier maximumIdent = Identifier::fromString(&vm, "maximum");
84 bool hasProperty = memoryDescriptor->hasProperty(exec, maximumIdent);
85 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
86 if (hasProperty) {
87 JSValue maxSizeValue = memoryDescriptor->get(exec, maximumIdent);
88 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
89 maximum = toNonWrappingUint32(exec, maxSizeValue);
90 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
91
92 if (initial > *maximum) {
93 return JSValue::encode(throwException(exec, throwScope,
94 createRangeError(exec, "'maximum' property must be greater than or equal to the 'initial' property"_s)));
95 }
96 }
97
98 RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(initial, maximum, type);
99 if (!wasmTable) {
100 return JSValue::encode(throwException(exec, throwScope,
101 createRangeError(exec, "couldn't create Table"_s)));
102 }
103
104 RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyTable::create(exec, vm, exec->lexicalGlobalObject()->webAssemblyTableStructure(), wasmTable.releaseNonNull())));
105}
106
107static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyTable(ExecState* exec)
108{
109 VM& vm = exec->vm();
110 auto scope = DECLARE_THROW_SCOPE(vm);
111 return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(exec, scope, "WebAssembly.Table"));
112}
113
114WebAssemblyTableConstructor* WebAssemblyTableConstructor::create(VM& vm, Structure* structure, WebAssemblyTablePrototype* thisPrototype)
115{
116 auto* constructor = new (NotNull, allocateCell<WebAssemblyTableConstructor>(vm.heap)) WebAssemblyTableConstructor(vm, structure);
117 constructor->finishCreation(vm, thisPrototype);
118 return constructor;
119}
120
121Structure* WebAssemblyTableConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
122{
123 return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
124}
125
126void WebAssemblyTableConstructor::finishCreation(VM& vm, WebAssemblyTablePrototype* prototype)
127{
128 Base::finishCreation(vm, "Table"_s, NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
129 putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
130 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete);
131}
132
133WebAssemblyTableConstructor::WebAssemblyTableConstructor(VM& vm, Structure* structure)
134 : Base(vm, structure, callJSWebAssemblyTable, constructJSWebAssemblyTable)
135{
136}
137
138} // namespace JSC
139
140#endif // ENABLE(WEBASSEMBLY)
141
142