cea97dc73946bd35318bc020604396ef1a299f5e
[WebKit-https.git] / Source / JavaScriptCore / wasm / js / WebAssemblyModulePrototype.cpp
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 "WebAssemblyModulePrototype.h"
28
29 #if ENABLE(WEBASSEMBLY)
30
31 #include "ArrayBuffer.h"
32 #include "FunctionPrototype.h"
33 #include "JSArrayBuffer.h"
34 #include "JSCInlines.h"
35 #include "JSWebAssemblyModule.h"
36 #include "ObjectConstructor.h"
37
38 namespace JSC {
39 static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoCustomSections(ExecState*);
40 static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoImports(ExecState*);
41 static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoExports(ExecState*);
42 }
43
44 #include "WebAssemblyModulePrototype.lut.h"
45
46 namespace JSC {
47
48 const ClassInfo WebAssemblyModulePrototype::s_info = { "WebAssembly.Module.prototype", &Base::s_info, &prototypeTableWebAssemblyModule, CREATE_METHOD_TABLE(WebAssemblyModulePrototype) };
49
50 /* Source for WebAssemblyModulePrototype.lut.h
51  @begin prototypeTableWebAssemblyModule
52  customSections webAssemblyModuleProtoCustomSections DontEnum|Function 1
53  imports        webAssemblyModuleProtoImports        DontEnum|Accessor 0
54  exports        webAssemblyModuleProtoExports        DontEnum|Accessor 0
55  @end
56  */
57
58 EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoCustomSections(ExecState* exec)
59 {
60     VM& vm = exec->vm();
61     auto* globalObject = exec->lexicalGlobalObject();
62     auto throwScope = DECLARE_THROW_SCOPE(vm);
63
64     JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->thisValue());
65     if (!module)
66         return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.customSections called with non WebAssembly.Module |this| value"))));
67
68     const String sectionNameString = exec->argument(0).getString(exec);
69     RETURN_IF_EXCEPTION(throwScope, { });
70
71     JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
72     RETURN_IF_EXCEPTION(throwScope, { });
73
74     const auto& customSections = module->moduleInformation().customSections;
75     for (const Wasm::CustomSection& section : customSections) {
76         if (section.name == sectionNameString) {
77             auto buffer = ArrayBuffer::tryCreate(section.payload.data(), section.payload.size());
78             if (!buffer)
79                 return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
80
81             Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, JSValue(), globalObject->arrayBufferStructure(ArrayBufferSharingMode::Default));
82             RETURN_IF_EXCEPTION(throwScope, { });
83
84             result->push(exec, JSArrayBuffer::create(vm, arrayBufferStructure, WTFMove(buffer)));
85             RETURN_IF_EXCEPTION(throwScope, { });
86         }
87     }
88
89     return JSValue::encode(result);
90 }
91
92 EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoImports(ExecState* exec)
93 {
94     VM& vm = exec->vm();
95     auto* globalObject = exec->lexicalGlobalObject();
96     auto throwScope = DECLARE_THROW_SCOPE(vm);
97
98     JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->thisValue());
99     if (!module)
100         return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.imports called with non WebAssembly.Module |this| value"))));
101
102     JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
103     RETURN_IF_EXCEPTION(throwScope, { });
104
105     const auto& imports = module->moduleInformation().imports;
106     if (imports.size()) {
107         Identifier module = Identifier::fromString(exec, "module");
108         Identifier name = Identifier::fromString(exec, "name");
109         Identifier kind = Identifier::fromString(exec, "kind");
110         for (const Wasm::Import& imp : imports) {
111             JSObject* obj = constructEmptyObject(exec);
112             RETURN_IF_EXCEPTION(throwScope, { });
113             obj->putDirect(vm, module, jsString(exec, imp.module));
114             obj->putDirect(vm, name, jsString(exec, imp.field));
115             obj->putDirect(vm, kind, jsString(exec, String(makeString(imp.kind))));
116             result->push(exec, obj);
117             RETURN_IF_EXCEPTION(throwScope, { });
118         }
119     }
120
121     return JSValue::encode(result);
122 }
123
124 EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoExports(ExecState* exec)
125 {
126     VM& vm = exec->vm();
127     auto* globalObject = exec->lexicalGlobalObject();
128     auto throwScope = DECLARE_THROW_SCOPE(vm);
129
130     JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->thisValue());
131     if (!module)
132         return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.exports called with non WebAssembly.Module |this| value"))));
133
134     JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
135     RETURN_IF_EXCEPTION(throwScope, { });
136
137     const auto& exports = module->moduleInformation().exports;
138     if (exports.size()) {
139         Identifier name = Identifier::fromString(exec, "name");
140         Identifier kind = Identifier::fromString(exec, "kind");
141         for (const Wasm::Export& exp : exports) {
142             JSObject* obj = constructEmptyObject(exec);
143             RETURN_IF_EXCEPTION(throwScope, { });
144             obj->putDirect(vm, name, jsString(exec, exp.field));
145             obj->putDirect(vm, kind, jsString(exec, String(makeString(exp.kind))));
146             result->push(exec, obj);
147             RETURN_IF_EXCEPTION(throwScope, { });
148         }
149     }
150
151     return JSValue::encode(result);
152 }
153
154 WebAssemblyModulePrototype* WebAssemblyModulePrototype::create(VM& vm, JSGlobalObject*, Structure* structure)
155 {
156     auto* object = new (NotNull, allocateCell<WebAssemblyModulePrototype>(vm.heap)) WebAssemblyModulePrototype(vm, structure);
157     object->finishCreation(vm);
158     return object;
159 }
160
161 Structure* WebAssemblyModulePrototype::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
162 {
163     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
164 }
165
166 void WebAssemblyModulePrototype::finishCreation(VM& vm)
167 {
168     Base::finishCreation(vm);
169 }
170
171 WebAssemblyModulePrototype::WebAssemblyModulePrototype(VM& vm, Structure* structure)
172     : Base(vm, structure)
173 {
174 }
175
176 } // namespace JSC
177
178 #endif // ENABLE(WEBASSEMBLY)