Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: src/wasm/wasm-js.cc

Issue 2695813005: [wasm] Split the compilation and instantiation API into sync and async methods. (Closed)
Patch Set: [wasm] Split the compilation and instantiation API into sync and async methods. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/value-serializer.cc ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/api-natives.h" 5 #include "src/api-natives.h"
6 #include "src/api.h" 6 #include "src/api.h"
7 #include "src/asmjs/asm-js.h" 7 #include "src/asmjs/asm-js.h"
8 #include "src/asmjs/asm-typer.h" 8 #include "src/asmjs/asm-typer.h"
9 #include "src/asmjs/asm-wasm-builder.h" 9 #include "src/asmjs/asm-wasm-builder.h"
10 #include "src/assert-scope.h" 10 #include "src/assert-scope.h"
(...skipping 13 matching lines...) Expand all
24 #include "src/wasm/wasm-objects.h" 24 #include "src/wasm/wasm-objects.h"
25 #include "src/wasm/wasm-result.h" 25 #include "src/wasm/wasm-result.h"
26 26
27 typedef uint8_t byte; 27 typedef uint8_t byte;
28 28
29 using v8::internal::wasm::ErrorThrower; 29 using v8::internal::wasm::ErrorThrower;
30 30
31 namespace v8 { 31 namespace v8 {
32 32
33 namespace { 33 namespace {
34 // TODO(wasm): move brand check to the respective types, and don't throw
35 // in it, rather, use a provided ErrorThrower, or let caller handle it.
36 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
37 if (!value->IsJSObject()) return false;
38 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
39 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
40 return has_brand.FromMaybe(false);
41 }
42
43 static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym,
44 ErrorThrower* thrower, const char* msg) {
45 return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false);
46 }
47
34 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { 48 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
35 return isolate->factory()->NewStringFromAsciiChecked(str); 49 return isolate->factory()->NewStringFromAsciiChecked(str);
36 } 50 }
37 Local<String> v8_str(Isolate* isolate, const char* str) { 51 Local<String> v8_str(Isolate* isolate, const char* str) {
38 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); 52 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
39 } 53 }
40 54
41 struct RawBuffer { 55 i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
42 const byte* start; 56 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
43 const byte* end; 57 v8::Isolate* isolate = args.GetIsolate();
44 size_t size() { return static_cast<size_t>(end - start); } 58 if (args.Length() < 1) {
45 }; 59 thrower->TypeError("Argument 0 must be a WebAssembly.Module");
60 return {};
61 }
46 62
47 RawBuffer GetRawBufferSource( 63 Local<Context> context = isolate->GetCurrentContext();
48 v8::Local<v8::Value> source, ErrorThrower* thrower) { 64 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
65 if (!BrandCheck(Utils::OpenHandle(*args[0]),
66 i::handle(i_context->wasm_module_sym()), thrower,
67 "Argument 0 must be a WebAssembly.Module")) {
68 return {};
69 }
70
71 Local<Object> module_obj = Local<Object>::Cast(args[0]);
72 return i::Handle<i::WasmModuleObject>::cast(
73 v8::Utils::OpenHandle(*module_obj));
74 }
75
76 i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
77 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
78 if (args.Length() < 1) {
79 thrower->TypeError("Argument 0 must be a buffer source");
80 return i::wasm::ModuleWireBytes(nullptr, nullptr);
81 }
82
49 const byte* start = nullptr; 83 const byte* start = nullptr;
50 const byte* end = nullptr; 84 const byte* end = nullptr;
51 85 v8::Local<v8::Value> source = args[0];
52 if (source->IsArrayBuffer()) { 86 if (source->IsArrayBuffer()) {
53 // A raw array buffer was passed. 87 // A raw array buffer was passed.
54 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); 88 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
55 ArrayBuffer::Contents contents = buffer->GetContents(); 89 ArrayBuffer::Contents contents = buffer->GetContents();
56 90
57 start = reinterpret_cast<const byte*>(contents.Data()); 91 start = reinterpret_cast<const byte*>(contents.Data());
58 end = start + contents.ByteLength(); 92 end = start + contents.ByteLength();
59 93
60 } else if (source->IsTypedArray()) { 94 } else if (source->IsTypedArray()) {
61 // A TypedArray was passed. 95 // A TypedArray was passed.
62 Local<TypedArray> array = Local<TypedArray>::Cast(source); 96 Local<TypedArray> array = Local<TypedArray>::Cast(source);
63 Local<ArrayBuffer> buffer = array->Buffer(); 97 Local<ArrayBuffer> buffer = array->Buffer();
64 98
65 ArrayBuffer::Contents contents = buffer->GetContents(); 99 ArrayBuffer::Contents contents = buffer->GetContents();
66 100
67 start = 101 start =
68 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); 102 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset();
69 end = start + array->ByteLength(); 103 end = start + array->ByteLength();
70 104
71 } else { 105 } else {
72 thrower->TypeError("Argument 0 must be a buffer source"); 106 thrower->TypeError("Argument 0 must be a buffer source");
73 } 107 }
74 if (start == nullptr || end == start) { 108 if (start == nullptr || end == start) {
75 thrower->CompileError("BufferSource argument is empty"); 109 thrower->CompileError("BufferSource argument is empty");
76 } 110 }
77 return {start, end}; 111 // TODO(titzer): use the handle as well?
112 return i::wasm::ModuleWireBytes(start, end);
78 } 113 }
79 114
80 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( 115 i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports(
81 v8::Isolate* isolate, const v8::Local<v8::Value> source, 116 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
82 ErrorThrower* thrower) { 117 if (args.Length() < 2) return {};
83 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 118 if (args[1]->IsUndefined()) return {};
84 i::MaybeHandle<i::JSObject> nothing;
85 119
86 RawBuffer buffer = GetRawBufferSource(source, thrower); 120 if (!args[1]->IsObject()) {
87 if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>(); 121 thrower->TypeError("Argument 1 must be an object");
88 122 return {};
89 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); 123 }
90 return i::wasm::CreateModuleObjectFromBytes( 124 Local<Object> obj = Local<Object>::Cast(args[1]);
91 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin, 125 return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
92 i::Handle<i::Script>::null(), i::Vector<const byte>::empty());
93 } 126 }
94 127
95 static bool ValidateModule(v8::Isolate* isolate, 128 // WebAssembly.compile(bytes) -> Promise
96 const v8::Local<v8::Value> source,
97 ErrorThrower* thrower) {
98 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
99 i::MaybeHandle<i::JSObject> nothing;
100
101 RawBuffer buffer = GetRawBufferSource(source, thrower);
102 if (buffer.start == nullptr) return false;
103
104 DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
105 return i::wasm::ValidateModuleBytes(i_isolate, buffer.start, buffer.end,
106 thrower,
107 i::wasm::ModuleOrigin::kWasmOrigin);
108 }
109
110 // TODO(wasm): move brand check to the respective types, and don't throw
111 // in it, rather, use a provided ErrorThrower, or let caller handle it.
112 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
113 if (!value->IsJSObject()) return false;
114 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
115 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
116 return !has_brand.IsNothing() && has_brand.ToChecked();
117 }
118
119 static bool BrandCheck(ErrorThrower* thrower, i::Handle<i::Object> value,
120 i::Handle<i::Symbol> sym, const char* msg) {
121 return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false);
122 }
123
124 void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { 129 void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
125 v8::Isolate* isolate = args.GetIsolate(); 130 v8::Isolate* isolate = args.GetIsolate();
131 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
126 HandleScope scope(isolate); 132 HandleScope scope(isolate);
127 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 133 ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
128 "WebAssembly.compile()");
129 134
130 Local<Context> context = isolate->GetCurrentContext(); 135 Local<Context> context = isolate->GetCurrentContext();
131 v8::Local<v8::Promise::Resolver> resolver; 136 v8::Local<v8::Promise::Resolver> resolver;
132 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 137 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
133 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 138 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
134 return_value.Set(resolver->GetPromise()); 139 return_value.Set(resolver->GetPromise());
135 140
136 if (args.Length() < 1) { 141 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
137 thrower.TypeError("Argument 0 must be a buffer source"); 142 if (thrower.error()) {
138 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 143 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
139 return; 144 return;
140 } 145 }
141 i::MaybeHandle<i::JSObject> module_obj = 146 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
142 CreateModuleObject(isolate, args[0], &thrower); 147 i::wasm::AsyncCompile(i_isolate, promise, bytes);
143
144 if (thrower.error()) {
145 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
146 } else {
147 resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked()));
148 }
149 } 148 }
150 149
150 // WebAssembly.validate(bytes) -> bool
151 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { 151 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
152 v8::Isolate* isolate = args.GetIsolate(); 152 v8::Isolate* isolate = args.GetIsolate();
153 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
153 HandleScope scope(isolate); 154 HandleScope scope(isolate);
154 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 155 ErrorThrower thrower(i_isolate, "WebAssembly.validate()");
155 "WebAssembly.validate()");
156 156
157 if (args.Length() < 1) { 157 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
158 thrower.TypeError("Argument 0 must be a buffer source");
159 return;
160 }
161 158
162 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 159 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
163 if (ValidateModule(isolate, args[0], &thrower)) { 160 if (!thrower.error() &&
161 i::wasm::SyncValidate(reinterpret_cast<i::Isolate*>(isolate), &thrower,
162 bytes)) {
164 return_value.Set(v8::True(isolate)); 163 return_value.Set(v8::True(isolate));
165 } else { 164 } else {
166 if (thrower.wasm_error()) thrower.Reify(); // Clear error. 165 if (thrower.wasm_error()) thrower.Reify(); // Clear error.
167 return_value.Set(v8::False(isolate)); 166 return_value.Set(v8::False(isolate));
168 } 167 }
169 } 168 }
170 169
170 // new WebAssembly.Module(bytes) -> WebAssembly.Module
171 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { 171 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
172 v8::Isolate* isolate = args.GetIsolate(); 172 v8::Isolate* isolate = args.GetIsolate();
173 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
173 HandleScope scope(isolate); 174 HandleScope scope(isolate);
174 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 175 ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
175 "WebAssembly.Module()");
176 176
177 if (args.Length() < 1) { 177 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
178 thrower.TypeError("Argument 0 must be a buffer source"); 178 if (thrower.error()) return;
179 return;
180 }
181 179
182 i::MaybeHandle<i::JSObject> module_obj = 180 i::MaybeHandle<i::Object> module_obj =
183 CreateModuleObject(isolate, args[0], &thrower); 181 i::wasm::SyncCompile(i_isolate, &thrower, bytes);
184 if (module_obj.is_null()) return; 182 if (module_obj.is_null()) return;
185 183
186 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 184 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
187 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); 185 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
188 } 186 }
189 187
190 MaybeLocal<Value> InstantiateModuleImpl( 188 // WebAssembly.Module.imports(module) -> Array<Import>
191 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj,
192 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
193 // It so happens that in both the WebAssembly.instantiate, as well as
194 // WebAssembly.Instance ctor, the positions of the ffi object and memory
195 // are the same. If that changes later, we refactor the consts into
196 // parameters.
197 static const int kFfiOffset = 1;
198
199 MaybeLocal<Value> nothing;
200 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null();
201 // This is a first - level validation of the argument. If present, we only
202 // check its type. {Instantiate} will further check that if the module
203 // has imports, the argument must be present, as well as piecemeal
204 // import satisfaction.
205 if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) {
206 if (!args[kFfiOffset]->IsObject()) {
207 thrower->TypeError("Argument %d must be an object", kFfiOffset);
208 return nothing;
209 }
210 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]);
211 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
212 }
213
214 i::MaybeHandle<i::JSObject> instance =
215 i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi);
216 if (instance.is_null()) {
217 if (!thrower->error())
218 thrower->RuntimeError("Could not instantiate module");
219 return nothing;
220 }
221 DCHECK(!i_isolate->has_pending_exception());
222 return Utils::ToLocal(instance.ToHandleChecked());
223 }
224
225 namespace {
226 i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
227 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
228 v8::Isolate* isolate = args.GetIsolate();
229 i::MaybeHandle<i::WasmModuleObject> nothing;
230 if (args.Length() < 1) {
231 thrower->TypeError("Argument 0 must be a WebAssembly.Module");
232 return nothing;
233 }
234
235 Local<Context> context = isolate->GetCurrentContext();
236 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
237 if (!BrandCheck(thrower, Utils::OpenHandle(*args[0]),
238 i::Handle<i::Symbol>(i_context->wasm_module_sym()),
239 "Argument 0 must be a WebAssembly.Module")) {
240 return nothing;
241 }
242
243 Local<Object> module_obj = Local<Object>::Cast(args[0]);
244 return i::Handle<i::WasmModuleObject>::cast(
245 v8::Utils::OpenHandle(*module_obj));
246 }
247 } // namespace
248
249 void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { 189 void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
250 HandleScope scope(args.GetIsolate()); 190 HandleScope scope(args.GetIsolate());
251 v8::Isolate* isolate = args.GetIsolate(); 191 v8::Isolate* isolate = args.GetIsolate();
252 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 192 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
253 ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()"); 193 ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()");
254 194
255 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 195 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
256 196 if (thrower.error()) return;
257 if (!maybe_module.is_null()) { 197 auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
258 auto imports = 198 args.GetReturnValue().Set(Utils::ToLocal(imports));
259 i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
260 args.GetReturnValue().Set(Utils::ToLocal(imports));
261 }
262 } 199 }
263 200
201 // WebAssembly.Module.exports(module) -> Array<Export>
264 void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) { 202 void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
265 HandleScope scope(args.GetIsolate()); 203 HandleScope scope(args.GetIsolate());
266 v8::Isolate* isolate = args.GetIsolate(); 204 v8::Isolate* isolate = args.GetIsolate();
267 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 205 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
268 ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()"); 206 ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()");
269 207
270 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 208 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
271 209 if (thrower.error()) return;
272 if (!maybe_module.is_null()) { 210 auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
273 auto exports = 211 args.GetReturnValue().Set(Utils::ToLocal(exports));
274 i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
275 args.GetReturnValue().Set(Utils::ToLocal(exports));
276 }
277 } 212 }
278 213
214 // WebAssembly.Module.customSections(module, name) -> Array<Section>
279 void WebAssemblyModuleCustomSections( 215 void WebAssemblyModuleCustomSections(
280 const v8::FunctionCallbackInfo<v8::Value>& args) { 216 const v8::FunctionCallbackInfo<v8::Value>& args) {
281 HandleScope scope(args.GetIsolate()); 217 HandleScope scope(args.GetIsolate());
282 v8::Isolate* isolate = args.GetIsolate(); 218 v8::Isolate* isolate = args.GetIsolate();
283 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 219 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
284 ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()"); 220 ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()");
285 221
286 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 222 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
223 if (thrower.error()) return;
287 224
288 if (args.Length() < 2) { 225 if (args.Length() < 2) {
289 thrower.TypeError("Argument 1 must be a string"); 226 thrower.TypeError("Argument 1 must be a string");
290 return; 227 return;
291 } 228 }
292 229
293 i::Handle<i::Object> name = Utils::OpenHandle(*args[1]); 230 i::Handle<i::Object> name = Utils::OpenHandle(*args[1]);
294 if (!name->IsString()) { 231 if (!name->IsString()) {
295 thrower.TypeError("Argument 1 must be a string"); 232 thrower.TypeError("Argument 1 must be a string");
296 return; 233 return;
297 } 234 }
298 235
299 if (!maybe_module.is_null()) { 236 auto custom_sections =
300 auto custom_sections = 237 i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
301 i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(), 238 i::Handle<i::String>::cast(name), &thrower);
302 i::Handle<i::String>::cast(name), &thrower); 239 if (thrower.error()) return;
303 if (!thrower.error()) { 240 args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
304 args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
305 }
306 }
307 } 241 }
308 242
243 // new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
309 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { 244 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
310 HandleScope scope(args.GetIsolate()); 245 HandleScope scope(args.GetIsolate());
311 v8::Isolate* isolate = args.GetIsolate(); 246 v8::Isolate* isolate = args.GetIsolate();
312 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 247 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
313 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); 248 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
314 249
315 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 250 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
251 if (thrower.error()) return;
316 252
317 if (!maybe_module.is_null()) { 253 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
318 MaybeLocal<Value> instance = InstantiateModuleImpl( 254 if (thrower.error()) return;
319 i_isolate, maybe_module.ToHandleChecked(), args, &thrower);
320 255
321 if (instance.IsEmpty()) { 256 i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate(
322 DCHECK(thrower.error()); 257 i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports,
323 return; 258 i::MaybeHandle<i::JSArrayBuffer>());
324 } 259 if (instance_object.is_null()) return;
325 args.GetReturnValue().Set(instance.ToLocalChecked()); 260 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked()));
326 }
327 } 261 }
328 262
263 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
264 // WebAssembly.instantiate(bytes, imports) ->
265 // {module: WebAssembly.Module, instance: WebAssembly.Instance}
329 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { 266 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
330 v8::Isolate* isolate = args.GetIsolate(); 267 v8::Isolate* isolate = args.GetIsolate();
331 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 268 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
332 ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()"); 269 ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()");
333 270
334 HandleScope scope(isolate); 271 HandleScope scope(isolate);
335 272
336 Local<Context> context = isolate->GetCurrentContext(); 273 Local<Context> context = isolate->GetCurrentContext();
337 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 274 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
338 275
(...skipping 10 matching lines...) Expand all
349 return; 286 return;
350 } 287 }
351 288
352 i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]); 289 i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]);
353 if (!first_arg->IsJSObject()) { 290 if (!first_arg->IsJSObject()) {
354 thrower.TypeError( 291 thrower.TypeError(
355 "Argument 0 must be a buffer source or a WebAssembly.Module object"); 292 "Argument 0 must be a buffer source or a WebAssembly.Module object");
356 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 293 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
357 return; 294 return;
358 } 295 }
359 bool want_pair = 296
360 !HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym())); 297 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
361 i::Handle<i::WasmModuleObject> module_obj; 298 if (thrower.error()) {
362 if (want_pair) { 299 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
363 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj = 300 return;
364 CreateModuleObject(isolate, args[0], &thrower); 301 }
365 if (!maybe_module_obj.ToHandle(&module_obj)) { 302 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
366 DCHECK(thrower.error()); 303
304 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) {
305 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
306 auto module_object = GetFirstArgumentAsModule(args, &thrower);
307 i::wasm::AsyncInstantiate(i_isolate, promise,
308 module_object.ToHandleChecked(), maybe_imports);
309 } else {
310 // WebAssembly.instantiate(bytes, imports) -> {module, instance}
311 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
312 if (thrower.error()) {
367 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 313 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
368 return; 314 return;
369 } 315 }
370 } else { 316 i::wasm::AsyncCompileAndInstantiate(i_isolate, promise, bytes,
371 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg); 317 maybe_imports);
372 }
373 DCHECK(!module_obj.is_null());
374 MaybeLocal<Value> instance =
375 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower);
376 if (instance.IsEmpty()) {
377 DCHECK(thrower.error());
378 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
379 } else {
380 DCHECK(!thrower.error());
381 Local<Value> retval;
382 if (want_pair) {
383 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>(
384 i_isolate->native_context()->object_function(), i_isolate);
385
386 i::Handle<i::JSObject> i_retval =
387 i_isolate->factory()->NewJSObject(object_function, i::TENURED);
388 i::Handle<i::String> module_property_name =
389 i_isolate->factory()->InternalizeUtf8String("module");
390 i::Handle<i::String> instance_property_name =
391 i_isolate->factory()->InternalizeUtf8String("instance");
392 i::JSObject::AddProperty(i_retval, module_property_name, module_obj,
393 i::NONE);
394 i::JSObject::AddProperty(i_retval, instance_property_name,
395 Utils::OpenHandle(*instance.ToLocalChecked()),
396 i::NONE);
397 retval = Utils::ToLocal(i_retval);
398 } else {
399 retval = instance.ToLocalChecked();
400 }
401 DCHECK(!retval.IsEmpty());
402 resolver->Resolve(context, retval);
403 } 318 }
404 } 319 }
405 320
406 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 321 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
407 Local<Context> context, Local<v8::Object> object, 322 Local<Context> context, Local<v8::Object> object,
408 Local<String> property, int* result, 323 Local<String> property, int* result,
409 int64_t lower_bound, uint64_t upper_bound) { 324 int64_t lower_bound, uint64_t upper_bound) {
410 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); 325 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property);
411 v8::Local<v8::Value> value; 326 v8::Local<v8::Value> value;
412 if (maybe.ToLocal(&value)) { 327 if (maybe.ToLocal(&value)) {
(...skipping 10 matching lines...) Expand all
423 " is above the upper bound %" PRIu64, 338 " is above the upper bound %" PRIu64,
424 number, upper_bound); 339 number, upper_bound);
425 return false; 340 return false;
426 } 341 }
427 *result = static_cast<int>(number); 342 *result = static_cast<int>(number);
428 return true; 343 return true;
429 } 344 }
430 return false; 345 return false;
431 } 346 }
432 347
348 // new WebAssembly.Table(args) -> WebAssembly.Table
433 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { 349 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
434 v8::Isolate* isolate = args.GetIsolate(); 350 v8::Isolate* isolate = args.GetIsolate();
351 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
435 HandleScope scope(isolate); 352 HandleScope scope(isolate);
436 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 353 ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
437 "WebAssembly.Module()");
438 if (args.Length() < 1 || !args[0]->IsObject()) { 354 if (args.Length() < 1 || !args[0]->IsObject()) {
439 thrower.TypeError("Argument 0 must be a table descriptor"); 355 thrower.TypeError("Argument 0 must be a table descriptor");
440 return; 356 return;
441 } 357 }
442 Local<Context> context = isolate->GetCurrentContext(); 358 Local<Context> context = isolate->GetCurrentContext();
443 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 359 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
444 // The descriptor's 'element'. 360 // The descriptor's 'element'.
445 { 361 {
446 v8::MaybeLocal<v8::Value> maybe = 362 v8::MaybeLocal<v8::Value> maybe =
447 descriptor->Get(context, v8_str(isolate, "element")); 363 descriptor->Get(context, v8_str(isolate, "element"));
(...skipping 21 matching lines...) Expand all
469 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key); 385 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key);
470 386
471 if (!has_maximum.IsNothing() && has_maximum.FromJust()) { 387 if (!has_maximum.IsNothing() && has_maximum.FromJust()) {
472 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, 388 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key,
473 &maximum, initial, 389 &maximum, initial,
474 i::wasm::kSpecMaxWasmTableSize)) { 390 i::wasm::kSpecMaxWasmTableSize)) {
475 return; 391 return;
476 } 392 }
477 } 393 }
478 394
479 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
480 i::Handle<i::FixedArray> fixed_array; 395 i::Handle<i::FixedArray> fixed_array;
481 i::Handle<i::JSObject> table_obj = 396 i::Handle<i::JSObject> table_obj =
482 i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array); 397 i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array);
483 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 398 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
484 return_value.Set(Utils::ToLocal(table_obj)); 399 return_value.Set(Utils::ToLocal(table_obj));
485 } 400 }
486 401
487 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { 402 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
488 v8::Isolate* isolate = args.GetIsolate(); 403 v8::Isolate* isolate = args.GetIsolate();
404 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
489 HandleScope scope(isolate); 405 HandleScope scope(isolate);
490 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 406 ErrorThrower thrower(i_isolate, "WebAssembly.Memory()");
491 "WebAssembly.Memory()");
492 if (args.Length() < 1 || !args[0]->IsObject()) { 407 if (args.Length() < 1 || !args[0]->IsObject()) {
493 thrower.TypeError("Argument 0 must be a memory descriptor"); 408 thrower.TypeError("Argument 0 must be a memory descriptor");
494 return; 409 return;
495 } 410 }
496 Local<Context> context = isolate->GetCurrentContext(); 411 Local<Context> context = isolate->GetCurrentContext();
497 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 412 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
498 // The descriptor's 'initial'. 413 // The descriptor's 'initial'.
499 int initial = 0; 414 int initial = 0;
500 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 415 if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
501 v8_str(isolate, "initial"), &initial, 0, 416 v8_str(isolate, "initial"), &initial, 0,
502 i::FLAG_wasm_max_mem_pages)) { 417 i::FLAG_wasm_max_mem_pages)) {
503 return; 418 return;
504 } 419 }
505 // The descriptor's 'maximum'. 420 // The descriptor's 'maximum'.
506 int maximum = -1; 421 int maximum = -1;
507 Local<String> maximum_key = v8_str(isolate, "maximum"); 422 Local<String> maximum_key = v8_str(isolate, "maximum");
508 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key); 423 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key);
509 424
510 if (!has_maximum.IsNothing() && has_maximum.FromJust()) { 425 if (!has_maximum.IsNothing() && has_maximum.FromJust()) {
511 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, 426 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key,
512 &maximum, initial, 427 &maximum, initial,
513 i::wasm::kSpecMaxWasmMemoryPages)) { 428 i::wasm::kSpecMaxWasmMemoryPages)) {
514 return; 429 return;
515 } 430 }
516 } 431 }
517 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
518 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * 432 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) *
519 static_cast<size_t>(initial); 433 static_cast<size_t>(initial);
520 i::Handle<i::JSArrayBuffer> buffer = 434 i::Handle<i::JSArrayBuffer> buffer =
521 i::wasm::NewArrayBuffer(i_isolate, size, i::FLAG_wasm_guard_pages); 435 i::wasm::NewArrayBuffer(i_isolate, size, i::FLAG_wasm_guard_pages);
522 if (buffer.is_null()) { 436 if (buffer.is_null()) {
523 thrower.RangeError("could not allocate memory"); 437 thrower.RangeError("could not allocate memory");
524 return; 438 return;
525 } 439 }
526 i::Handle<i::JSObject> memory_obj = 440 i::Handle<i::JSObject> memory_obj =
527 i::WasmMemoryObject::New(i_isolate, buffer, maximum); 441 i::WasmMemoryObject::New(i_isolate, buffer, maximum);
528 args.GetReturnValue().Set(Utils::ToLocal(memory_obj)); 442 args.GetReturnValue().Set(Utils::ToLocal(memory_obj));
529 } 443 }
530 444
531 void WebAssemblyTableGetLength( 445 void WebAssemblyTableGetLength(
532 const v8::FunctionCallbackInfo<v8::Value>& args) { 446 const v8::FunctionCallbackInfo<v8::Value>& args) {
533 v8::Isolate* isolate = args.GetIsolate(); 447 v8::Isolate* isolate = args.GetIsolate();
534 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 448 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
535 "WebAssembly.Table.length()"); 449 HandleScope scope(isolate);
450 ErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
536 Local<Context> context = isolate->GetCurrentContext(); 451 Local<Context> context = isolate->GetCurrentContext();
537 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 452 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
538 if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), 453 if (!BrandCheck(Utils::OpenHandle(*args.This()),
539 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 454 i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
540 "Receiver is not a WebAssembly.Table")) { 455 "Receiver is not a WebAssembly.Table")) {
541 return; 456 return;
542 } 457 }
543 auto receiver = 458 auto receiver =
544 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 459 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
545 args.GetReturnValue().Set( 460 args.GetReturnValue().Set(
546 v8::Number::New(isolate, receiver->current_length())); 461 v8::Number::New(isolate, receiver->current_length()));
547 } 462 }
548 463
464 // WebAssembly.Table.grow(num) -> num
549 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 465 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
550 v8::Isolate* isolate = args.GetIsolate(); 466 v8::Isolate* isolate = args.GetIsolate();
551 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 467 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
552 "WebAssembly.Table.grow()"); 468 HandleScope scope(isolate);
469 ErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
553 Local<Context> context = isolate->GetCurrentContext(); 470 Local<Context> context = isolate->GetCurrentContext();
554 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 471 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
555 if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), 472 if (!BrandCheck(Utils::OpenHandle(*args.This()),
556 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 473 i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
557 "Receiver is not a WebAssembly.Table")) { 474 "Receiver is not a WebAssembly.Table")) {
558 return; 475 return;
559 } 476 }
560 477
561 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
562 auto receiver = 478 auto receiver =
563 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 479 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
564 i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate); 480 i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate);
565 int old_size = old_array->length(); 481 int old_size = old_array->length();
566 int64_t new_size64 = 0; 482 int64_t new_size64 = 0;
567 if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) { 483 if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) {
568 return; 484 return;
569 } 485 }
570 new_size64 += old_size; 486 new_size64 += old_size;
571 487
(...skipping 20 matching lines...) Expand all
592 i::Object* null = i_isolate->heap()->null_value(); 508 i::Object* null = i_isolate->heap()->null_value();
593 for (int i = old_size; i < new_size; ++i) new_array->set(i, null); 509 for (int i = old_size; i < new_size; ++i) new_array->set(i, null);
594 receiver->set_functions(*new_array); 510 receiver->set_functions(*new_array);
595 } 511 }
596 512
597 // TODO(gdeepti): use weak links for instances 513 // TODO(gdeepti): use weak links for instances
598 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 514 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
599 return_value.Set(old_size); 515 return_value.Set(old_size);
600 } 516 }
601 517
518 // WebAssembly.Table.get(num) -> JSFunction
602 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { 519 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
603 v8::Isolate* isolate = args.GetIsolate(); 520 v8::Isolate* isolate = args.GetIsolate();
604 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 521 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
522 HandleScope scope(isolate);
605 ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()"); 523 ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
606 Local<Context> context = isolate->GetCurrentContext(); 524 Local<Context> context = isolate->GetCurrentContext();
607 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 525 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
608 if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), 526 if (!BrandCheck(Utils::OpenHandle(*args.This()),
609 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 527 i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
610 "Receiver is not a WebAssembly.Table")) { 528 "Receiver is not a WebAssembly.Table")) {
611 return; 529 return;
612 } 530 }
613 531
614 auto receiver = 532 auto receiver =
615 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); 533 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
616 i::Handle<i::FixedArray> array(receiver->functions(), i_isolate); 534 i::Handle<i::FixedArray> array(receiver->functions(), i_isolate);
617 int i = 0; 535 int i = 0;
618 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; 536 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
619 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 537 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
620 if (i < 0 || i >= array->length()) { 538 if (i < 0 || i >= array->length()) {
621 thrower.RangeError("index out of bounds"); 539 thrower.RangeError("index out of bounds");
622 return; 540 return;
623 } 541 }
624 542
625 i::Handle<i::Object> value(array->get(i), i_isolate); 543 i::Handle<i::Object> value(array->get(i), i_isolate);
626 return_value.Set(Utils::ToLocal(value)); 544 return_value.Set(Utils::ToLocal(value));
627 } 545 }
628 546
547 // WebAssembly.Table.set(num, JSFunction)
629 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { 548 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
630 v8::Isolate* isolate = args.GetIsolate(); 549 v8::Isolate* isolate = args.GetIsolate();
631 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 550 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
551 HandleScope scope(isolate);
632 ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()"); 552 ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
633 Local<Context> context = isolate->GetCurrentContext(); 553 Local<Context> context = isolate->GetCurrentContext();
634 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 554 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
635 if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), 555 if (!BrandCheck(Utils::OpenHandle(*args.This()),
636 i::Handle<i::Symbol>(i_context->wasm_table_sym()), 556 i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
637 "Receiver is not a WebAssembly.Table")) { 557 "Receiver is not a WebAssembly.Table")) {
638 return; 558 return;
639 } 559 }
640 if (args.Length() < 2) { 560 if (args.Length() < 2) {
641 thrower.TypeError("Argument 1 must be null or a function"); 561 thrower.TypeError("Argument 1 must be null or a function");
642 return; 562 return;
643 } 563 }
644 i::Handle<i::Object> value = Utils::OpenHandle(*args[1]); 564 i::Handle<i::Object> value = Utils::OpenHandle(*args[1]);
645 if (!value->IsNull(i_isolate) && 565 if (!value->IsNull(i_isolate) &&
646 (!value->IsJSFunction() || 566 (!value->IsJSFunction() ||
(...skipping 19 matching lines...) Expand all
666 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, 586 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
667 i::Handle<i::JSFunction>::null()); 587 i::Handle<i::JSFunction>::null());
668 } else { 588 } else {
669 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, 589 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
670 i::Handle<i::JSFunction>::cast(value)); 590 i::Handle<i::JSFunction>::cast(value));
671 } 591 }
672 592
673 i::Handle<i::FixedArray>::cast(array)->set(i, *value); 593 i::Handle<i::FixedArray>::cast(array)->set(i, *value);
674 } 594 }
675 595
596 // WebAssembly.Memory.grow(num) -> num
676 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { 597 void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
677 v8::Isolate* isolate = args.GetIsolate(); 598 v8::Isolate* isolate = args.GetIsolate();
678 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 599 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
600 HandleScope scope(isolate);
679 ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()"); 601 ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
680 Local<Context> context = isolate->GetCurrentContext(); 602 Local<Context> context = isolate->GetCurrentContext();
681 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 603 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
682 if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), 604 if (!BrandCheck(Utils::OpenHandle(*args.This()),
683 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 605 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
684 "Receiver is not a WebAssembly.Memory")) { 606 "Receiver is not a WebAssembly.Memory")) {
685 return; 607 return;
686 } 608 }
687 int64_t delta_size = 0; 609 int64_t delta_size = 0;
688 if (args.Length() < 1 || !args[0]->IntegerValue(context).To(&delta_size)) { 610 if (args.Length() < 1 || !args[0]->IntegerValue(context).To(&delta_size)) {
689 thrower.TypeError("Argument 0 required, must be numeric value of pages"); 611 thrower.TypeError("Argument 0 required, must be numeric value of pages");
690 return; 612 return;
691 } 613 }
692 i::Handle<i::WasmMemoryObject> receiver = 614 i::Handle<i::WasmMemoryObject> receiver =
693 i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This())); 615 i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
(...skipping 14 matching lines...) Expand all
708 int32_t ret = i::wasm::GrowWebAssemblyMemory( 630 int32_t ret = i::wasm::GrowWebAssemblyMemory(
709 i_isolate, receiver, static_cast<uint32_t>(delta_size)); 631 i_isolate, receiver, static_cast<uint32_t>(delta_size));
710 if (ret == -1) { 632 if (ret == -1) {
711 thrower.RangeError("Unable to grow instance memory."); 633 thrower.RangeError("Unable to grow instance memory.");
712 return; 634 return;
713 } 635 }
714 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 636 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
715 return_value.Set(ret); 637 return_value.Set(ret);
716 } 638 }
717 639
640 // WebAssembly.Memory.buffer -> ArrayBuffer
718 void WebAssemblyMemoryGetBuffer( 641 void WebAssemblyMemoryGetBuffer(
719 const v8::FunctionCallbackInfo<v8::Value>& args) { 642 const v8::FunctionCallbackInfo<v8::Value>& args) {
720 v8::Isolate* isolate = args.GetIsolate(); 643 v8::Isolate* isolate = args.GetIsolate();
721 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 644 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
645 HandleScope scope(isolate);
722 ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer"); 646 ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
723 Local<Context> context = isolate->GetCurrentContext(); 647 Local<Context> context = isolate->GetCurrentContext();
724 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 648 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
725 if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), 649 if (!BrandCheck(Utils::OpenHandle(*args.This()),
726 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), 650 i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
727 "Receiver is not a WebAssembly.Memory")) { 651 "Receiver is not a WebAssembly.Memory")) {
728 return; 652 return;
729 } 653 }
730 i::Handle<i::WasmMemoryObject> receiver = 654 i::Handle<i::WasmMemoryObject> receiver =
731 i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This())); 655 i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
732 i::Handle<i::Object> buffer(receiver->buffer(), i_isolate); 656 i::Handle<i::Object> buffer(receiver->buffer(), i_isolate);
733 DCHECK(buffer->IsJSArrayBuffer()); 657 DCHECK(buffer->IsJSArrayBuffer());
734 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 658 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
735 return_value.Set(Utils::ToLocal(buffer)); 659 return_value.Set(Utils::ToLocal(buffer));
736 } 660 }
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 859 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
936 return HasBrand(value, symbol); 860 return HasBrand(value, symbol);
937 } 861 }
938 862
939 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 863 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
940 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 864 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
941 return HasBrand(value, symbol); 865 return HasBrand(value, symbol);
942 } 866 }
943 } // namespace internal 867 } // namespace internal
944 } // namespace v8 868 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.cc ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698