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 {
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, "WebAssembly.Table expects its 'element' field to be the string 'anyfunc'"_s)));
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 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, "'maximum' property must be greater than or equal to the 'initial' property"_s)));
90 }
91 }
92
93 RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(initial, maximum);
94 if (!wasmTable) {
95 return JSValue::encode(throwException(exec, throwScope,
96 createRangeError(exec, "couldn't create Table"_s)));
97 }
98
99 RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyTable::create(exec, vm, exec->lexicalGlobalObject()->webAssemblyTableStructure(), wasmTable.releaseNonNull())));
100}
101
102static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyTable(ExecState* exec)
103{
104 VM& vm = exec->vm();
105 auto scope = DECLARE_THROW_SCOPE(vm);
106 return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(exec, scope, "WebAssembly.Table"));
107}
108
109WebAssemblyTableConstructor* WebAssemblyTableConstructor::create(VM& vm, Structure* structure, WebAssemblyTablePrototype* thisPrototype)
110{
111 auto* constructor = new (NotNull, allocateCell<WebAssemblyTableConstructor>(vm.heap)) WebAssemblyTableConstructor(vm, structure);
112 constructor->finishCreation(vm, thisPrototype);
113 return constructor;
114}
115
116Structure* WebAssemblyTableConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
117{
118 return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
119}
120
121void WebAssemblyTableConstructor::finishCreation(VM& vm, WebAssemblyTablePrototype* prototype)
122{
123 Base::finishCreation(vm, "Table"_s, NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
124 putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
125 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete);
126}
127
128WebAssemblyTableConstructor::WebAssemblyTableConstructor(VM& vm, Structure* structure)
129 : Base(vm, structure, callJSWebAssemblyTable, constructJSWebAssemblyTable)
130{
131}
132
133} // namespace JSC
134
135#endif // ENABLE(WEBASSEMBLY)
136
137