OLD | NEW |
---|---|
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/assert-scope.h" | 7 #include "src/assert-scope.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/execution.h" | 10 #include "src/execution.h" |
(...skipping 17 matching lines...) Expand all Loading... | |
28 | 28 |
29 namespace v8 { | 29 namespace v8 { |
30 | 30 |
31 namespace { | 31 namespace { |
32 struct RawBuffer { | 32 struct RawBuffer { |
33 const byte* start; | 33 const byte* start; |
34 const byte* end; | 34 const byte* end; |
35 size_t size() { return static_cast<size_t>(end - start); } | 35 size_t size() { return static_cast<size_t>(end - start); } |
36 }; | 36 }; |
37 | 37 |
38 RawBuffer GetRawBufferArgument( | 38 RawBuffer GetRawBufferSource( |
39 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { | 39 v8::Local<v8::Value> source, ErrorThrower* thrower) { |
40 if (args.Length() < 1) { | |
41 thrower.Error("Argument 0 must be an array buffer"); | |
42 return {nullptr, nullptr}; | |
43 } | |
44 | |
45 const byte* start = nullptr; | 40 const byte* start = nullptr; |
46 const byte* end = nullptr; | 41 const byte* end = nullptr; |
47 | 42 |
48 if (args[0]->IsArrayBuffer()) { | 43 if (source->IsArrayBuffer()) { |
49 // A raw array buffer was passed. | 44 // A raw array buffer was passed. |
50 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(args[0]); | 45 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); |
51 ArrayBuffer::Contents contents = buffer->GetContents(); | 46 ArrayBuffer::Contents contents = buffer->GetContents(); |
52 | 47 |
53 start = reinterpret_cast<const byte*>(contents.Data()); | 48 start = reinterpret_cast<const byte*>(contents.Data()); |
54 end = start + contents.ByteLength(); | 49 end = start + contents.ByteLength(); |
55 | 50 |
56 if (start == nullptr || end == start) { | 51 if (start == nullptr || end == start) { |
57 thrower.Error("ArrayBuffer argument is empty"); | 52 thrower->Error("ArrayBuffer argument is empty"); |
58 } | 53 } |
59 } else if (args[0]->IsTypedArray()) { | 54 } else if (source->IsTypedArray()) { |
60 // A TypedArray was passed. | 55 // A TypedArray was passed. |
61 Local<TypedArray> array = Local<TypedArray>::Cast(args[0]); | 56 Local<TypedArray> array = Local<TypedArray>::Cast(source); |
62 Local<ArrayBuffer> buffer = array->Buffer(); | 57 Local<ArrayBuffer> buffer = array->Buffer(); |
63 | 58 |
64 ArrayBuffer::Contents contents = buffer->GetContents(); | 59 ArrayBuffer::Contents contents = buffer->GetContents(); |
65 | 60 |
66 start = | 61 start = |
67 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); | 62 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); |
68 end = start + array->ByteLength(); | 63 end = start + array->ByteLength(); |
69 | 64 |
70 if (start == nullptr || end == start) { | 65 if (start == nullptr || end == start) { |
71 thrower.Error("ArrayBuffer argument is empty"); | 66 thrower->Error("ArrayBuffer argument is empty"); |
72 } | 67 } |
73 } else { | 68 } else { |
74 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); | 69 thrower->Error("Argument 0 must be an ArrayBuffer or Uint8Array"); |
75 } | 70 } |
76 | 71 |
77 return {start, end}; | 72 return {start, end}; |
78 } | 73 } |
79 | 74 |
80 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 75 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
81 HandleScope scope(args.GetIsolate()); | 76 HandleScope scope(args.GetIsolate()); |
82 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 77 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
83 ErrorThrower thrower(isolate, "WASM.verifyModule()"); | 78 ErrorThrower thrower(isolate, "Wasm.verifyModule()"); |
84 | 79 |
85 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 80 if (args.Length() < 1) { |
81 thrower.Error("Argument 0 must be a buffer source"); | |
82 return; | |
83 } | |
84 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | |
86 if (thrower.error()) return; | 85 if (thrower.error()) return; |
87 | 86 |
88 i::Zone zone(isolate->allocator()); | 87 i::Zone zone(isolate->allocator()); |
89 internal::wasm::ModuleResult result = | 88 internal::wasm::ModuleResult result = |
90 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, | 89 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, |
91 true, internal::wasm::kWasmOrigin); | 90 true, internal::wasm::kWasmOrigin); |
92 | 91 |
93 if (result.failed()) { | 92 if (result.failed()) { |
94 thrower.Failed("", result); | 93 thrower.Failed("", result); |
95 } | 94 } |
96 | 95 |
97 if (result.val) delete result.val; | 96 if (result.val) delete result.val; |
98 } | 97 } |
99 | 98 |
100 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { | 99 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { |
101 HandleScope scope(args.GetIsolate()); | 100 HandleScope scope(args.GetIsolate()); |
102 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 101 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
103 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); | 102 ErrorThrower thrower(isolate, "Wasm.verifyFunction()"); |
104 | 103 |
105 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 104 if (args.Length() < 1) { |
105 thrower.Error("Argument 0 must be a buffer source"); | |
106 return; | |
107 } | |
108 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | |
106 if (thrower.error()) return; | 109 if (thrower.error()) return; |
107 | 110 |
108 internal::wasm::FunctionResult result; | 111 internal::wasm::FunctionResult result; |
109 { | 112 { |
110 // Verification of a single function shouldn't allocate. | 113 // Verification of a single function shouldn't allocate. |
111 i::DisallowHeapAllocation no_allocation; | 114 i::DisallowHeapAllocation no_allocation; |
112 i::Zone zone(isolate->allocator()); | 115 i::Zone zone(isolate->allocator()); |
113 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, | 116 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, |
114 buffer.start, buffer.end); | 117 buffer.start, buffer.end); |
115 } | 118 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 | 156 |
154 v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), | 157 v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), |
155 info->literal(), &typer); | 158 info->literal(), &typer); |
156 | 159 |
157 return builder.Run(foreign_args); | 160 return builder.Run(foreign_args); |
158 } | 161 } |
159 | 162 |
160 i::MaybeHandle<i::JSObject> InstantiateModuleCommon( | 163 i::MaybeHandle<i::JSObject> InstantiateModuleCommon( |
161 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, | 164 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, |
162 const byte* end, ErrorThrower* thrower, | 165 const byte* end, ErrorThrower* thrower, |
163 internal::wasm::ModuleOrigin origin) { | 166 internal::wasm::ModuleOrigin origin = i::wasm::kWasmOrigin) { |
164 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 167 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
165 | 168 |
166 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | |
167 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | |
168 Local<Object> obj = Local<Object>::Cast(args[2]); | |
169 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | |
170 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | |
171 } | |
172 | |
173 // Decode but avoid a redundant pass over function bodies for verification. | 169 // Decode but avoid a redundant pass over function bodies for verification. |
174 // Verification will happen during compilation. | 170 // Verification will happen during compilation. |
175 i::Zone zone(isolate->allocator()); | 171 i::Zone zone(isolate->allocator()); |
176 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( | 172 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( |
177 isolate, &zone, start, end, false, origin); | 173 isolate, &zone, start, end, false, origin); |
178 | 174 |
179 i::MaybeHandle<i::JSObject> object; | 175 i::MaybeHandle<i::JSObject> object; |
180 if (result.failed() && origin == internal::wasm::kAsmJsOrigin) { | 176 if (result.failed() && origin == internal::wasm::kAsmJsOrigin) { |
181 thrower->Error("Asm.js converted module failed to decode"); | 177 thrower->Error("Asm.js converted module failed to decode"); |
182 } else if (result.failed()) { | 178 } else if (result.failed()) { |
183 thrower->Failed("", result); | 179 thrower->Failed("", result); |
184 } else { | 180 } else { |
185 // Success. Instantiate the module and return the object. | 181 // Success. Instantiate the module and return the object. |
186 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 182 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |
187 if (args.Length() > 1 && args[1]->IsObject()) { | 183 if (args.Length() > 1 && args[1]->IsObject()) { |
188 Local<Object> obj = Local<Object>::Cast(args[1]); | 184 Local<Object> obj = Local<Object>::Cast(args[1]); |
189 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 185 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
190 } | 186 } |
191 | 187 |
188 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | |
189 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | |
190 Local<Object> obj = Local<Object>::Cast(args[2]); | |
191 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | |
192 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | |
193 } | |
194 | |
192 object = result.val->Instantiate(isolate, ffi, memory); | 195 object = result.val->Instantiate(isolate, ffi, memory); |
193 | |
194 if (!object.is_null()) { | 196 if (!object.is_null()) { |
195 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | 197 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); |
196 } | 198 } |
197 } | 199 } |
198 | 200 |
199 if (result.val) delete result.val; | 201 if (result.val) delete result.val; |
200 return object; | 202 return object; |
201 } | 203 } |
202 | 204 |
203 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { | 205 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { |
204 HandleScope scope(args.GetIsolate()); | 206 HandleScope scope(args.GetIsolate()); |
205 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 207 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
206 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); | 208 ErrorThrower thrower(isolate, "Wasm.instantiateModuleFromAsm()"); |
207 | 209 |
208 if (!args[0]->IsString()) { | 210 if (!args[0]->IsString()) { |
209 thrower.Error("Asm module text should be a string"); | 211 thrower.Error("Asm module text should be a string"); |
210 return; | 212 return; |
211 } | 213 } |
212 | 214 |
213 i::Factory* factory = isolate->factory(); | 215 i::Factory* factory = isolate->factory(); |
214 i::Zone zone(isolate->allocator()); | 216 i::Zone zone(isolate->allocator()); |
215 Local<String> source = Local<String>::Cast(args[0]); | 217 Local<String> source = Local<String>::Cast(args[0]); |
216 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); | 218 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 | 270 |
269 if (retval.is_null()) { | 271 if (retval.is_null()) { |
270 thrower.Error( | 272 thrower.Error( |
271 "WASM.instantiateModuleFromAsm(): foreign init function failed"); | 273 "WASM.instantiateModuleFromAsm(): foreign init function failed"); |
272 } | 274 } |
273 } | 275 } |
274 | 276 |
275 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 277 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
276 HandleScope scope(args.GetIsolate()); | 278 HandleScope scope(args.GetIsolate()); |
277 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 279 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
278 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); | 280 ErrorThrower thrower(isolate, "Wasm.instantiateModule()"); |
279 | 281 |
280 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 282 if (args.Length() < 1) { |
283 thrower.Error("Argument 0 must be a buffer source"); | |
284 return; | |
285 } | |
286 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | |
281 if (buffer.start == nullptr) return; | 287 if (buffer.start == nullptr) return; |
282 | 288 |
283 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, | 289 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower); |
284 internal::wasm::kWasmOrigin); | 290 } |
291 | |
292 | |
293 static i::MaybeHandle<i::JSObject> CreateModuleObject( | |
294 v8::Isolate* isolate, const v8::Local<v8::Value> source, | |
295 ErrorThrower* thrower) { | |
296 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | |
297 | |
298 RawBuffer buffer = GetRawBufferSource(source, thrower); | |
299 if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>(); | |
300 | |
301 // TODO(rossberg): Once we can, do compilation here. | |
302 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); | |
303 Local<Context> context = isolate->GetCurrentContext(); | |
304 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | |
305 i::Handle<i::JSFunction> module_cons(i_context->wasm_module_constructor()); | |
306 i::Handle<i::JSObject> module_obj = | |
307 i_isolate->factory()->NewJSObject(module_cons); | |
308 i::Handle<i::Object> module_ref = Utils::OpenHandle(*source); | |
309 i::Handle<i::Symbol> module_sym(i_context->wasm_module_sym()); | |
310 i::Object::SetProperty(module_obj, module_sym, module_ref, i::STRICT).Check(); | |
311 | |
312 return module_obj; | |
313 } | |
314 | |
315 void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
316 v8::Isolate* isolate = args.GetIsolate(); | |
317 HandleScope scope(isolate); | |
318 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | |
319 "WebAssembly.compile()"); | |
320 | |
321 if (args.Length() < 1) { | |
322 thrower.Error("Argument 0 must be a buffer source"); | |
323 return; | |
324 } | |
325 i::MaybeHandle<i::JSObject> module_obj = | |
326 CreateModuleObject(isolate, args[0], &thrower); | |
327 if (module_obj.is_null()) return; | |
328 | |
329 Local<Context> context = isolate->GetCurrentContext(); | |
330 v8::Local<v8::Promise::Resolver> resolver; | |
331 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; | |
332 resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked())); | |
333 | |
334 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | |
335 return_value.Set(resolver->GetPromise()); | |
336 } | |
337 | |
338 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
339 v8::Isolate* isolate = args.GetIsolate(); | |
340 HandleScope scope(isolate); | |
341 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | |
342 "WebAssembly.Module()"); | |
343 | |
344 if (args.Length() < 1) { | |
345 thrower.Error("Argument 0 must be a buffer source"); | |
346 return; | |
347 } | |
348 i::MaybeHandle<i::JSObject> module_obj = | |
349 CreateModuleObject(isolate, args[0], &thrower); | |
350 if (module_obj.is_null()) return; | |
351 | |
352 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | |
353 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); | |
354 } | |
355 | |
356 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
357 HandleScope scope(args.GetIsolate()); | |
358 v8::Isolate* isolate = args.GetIsolate(); | |
359 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | |
360 "WebAssembly.Instance()"); | |
361 | |
362 if (args.Length() < 1) { | |
363 thrower.Error("Argument 0 must be a WebAssembly.Module"); | |
364 return; | |
365 } | |
366 Local<Context> context = isolate->GetCurrentContext(); | |
367 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | |
368 i::Handle<i::Symbol> module_sym(i_context->wasm_module_sym()); | |
369 i::MaybeHandle<i::Object> source = | |
370 i::Object::GetProperty(Utils::OpenHandle(*args[0]), module_sym); | |
371 if (source.is_null()) return; | |
372 | |
373 RawBuffer buffer = | |
374 GetRawBufferSource(Utils::ToLocal(source.ToHandleChecked()), &thrower); | |
375 if (buffer.start == nullptr) return; | |
376 | |
377 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower); | |
285 } | 378 } |
286 } // namespace | 379 } // namespace |
287 | 380 |
288 // TODO(titzer): we use the API to create the function template because the | 381 // TODO(titzer): we use the API to create the function template because the |
289 // internal guts are too ugly to replicate here. | 382 // internal guts are too ugly to replicate here. |
290 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, | 383 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, |
291 FunctionCallback func) { | 384 FunctionCallback func) { |
292 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); | 385 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); |
293 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); | 386 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); |
294 return v8::Utils::OpenHandle(*local); | 387 return v8::Utils::OpenHandle(*local); |
295 } | 388 } |
296 | 389 |
297 namespace internal { | 390 namespace internal { |
298 static Handle<String> v8_str(Isolate* isolate, const char* str) { | 391 static Handle<String> v8_str(Isolate* isolate, const char* str) { |
299 return isolate->factory()->NewStringFromAsciiChecked(str); | 392 return isolate->factory()->NewStringFromAsciiChecked(str); |
300 } | 393 } |
301 | 394 |
302 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, | 395 static Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object, |
303 const char* str, FunctionCallback func) { | 396 const char* str, FunctionCallback func) { |
304 Handle<String> name = v8_str(isolate, str); | 397 Handle<String> name = v8_str(isolate, str); |
305 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 398 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
306 Handle<JSFunction> function = | 399 Handle<JSFunction> function = |
307 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 400 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
308 PropertyAttributes attributes = | 401 PropertyAttributes attributes = |
309 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 402 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
310 JSObject::AddProperty(object, name, function, attributes); | 403 JSObject::AddProperty(object, name, function, attributes); |
404 return function; | |
311 } | 405 } |
312 | 406 |
313 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 407 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
408 Factory* factory = isolate->factory(); | |
409 | |
314 // Setup wasm function map. | 410 // Setup wasm function map. |
315 Handle<Context> context(global->native_context(), isolate); | 411 Handle<Context> context(global->native_context(), isolate); |
316 InstallWasmFunctionMap(isolate, context); | 412 InstallWasmFunctionMap(isolate, context); |
317 | 413 |
318 // Bind the WASM object. | 414 // Bind the experimental WASM object. |
319 Factory* factory = isolate->factory(); | 415 // TODO(rossberg, titzer): remove once it's no longer needed. |
320 Handle<String> name = v8_str(isolate, "Wasm"); | 416 { |
417 Handle<String> name = v8_str(isolate, "Wasm"); | |
418 Handle<JSFunction> cons = factory->NewFunction(name); | |
419 JSFunction::SetInstancePrototype( | |
420 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | |
421 cons->shared()->set_instance_class_name(*name); | |
422 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); | |
423 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | |
424 JSObject::AddProperty(global, name, wasm_object, attributes); | |
425 | |
426 // Install functions on the WASM object. | |
427 InstallFunc(isolate, wasm_object, "verifyModule", VerifyModule); | |
428 InstallFunc(isolate, wasm_object, "verifyFunction", VerifyFunction); | |
429 InstallFunc(isolate, wasm_object, "instantiateModule", InstantiateModule); | |
430 InstallFunc(isolate, wasm_object, "instantiateModuleFromAsm", | |
431 InstantiateModuleFromAsm); | |
432 | |
433 { | |
434 // Add the Wasm.experimentalVersion property. | |
435 Handle<String> name = v8_str(isolate, "experimentalVersion"); | |
436 PropertyAttributes attributes = | |
437 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | |
438 Handle<Smi> value = | |
439 Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); | |
440 JSObject::AddProperty(wasm_object, name, value, attributes); | |
441 } | |
442 } | |
443 | |
444 // Create private symbols. | |
445 Handle<Symbol> module_sym = isolate->factory()->NewPrivateSymbol(); | |
446 Handle<Symbol> instance_sym = isolate->factory()->NewPrivateSymbol(); | |
447 context->set_wasm_module_sym(*module_sym); | |
448 context->set_wasm_instance_sym(*instance_sym); | |
449 | |
450 // Bind the WebAssembly object. | |
451 Handle<String> name = v8_str(isolate, "WebAssembly"); | |
321 Handle<JSFunction> cons = factory->NewFunction(name); | 452 Handle<JSFunction> cons = factory->NewFunction(name); |
322 JSFunction::SetInstancePrototype( | 453 JSFunction::SetInstancePrototype( |
323 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | 454 cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
324 cons->shared()->set_instance_class_name(*name); | 455 cons->shared()->set_instance_class_name(*name); |
325 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); | 456 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); |
326 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | 457 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
327 JSObject::AddProperty(global, name, wasm_object, attributes); | 458 JSObject::AddProperty(global, name, wasm_object, attributes); |
328 | 459 |
329 // Install functions on the WASM object. | 460 // Install static methods on WebAssembly object. |
330 InstallFunc(isolate, wasm_object, "verifyModule", VerifyModule); | 461 InstallFunc(isolate, wasm_object, "compile", WebAssemblyCompile); |
331 InstallFunc(isolate, wasm_object, "verifyFunction", VerifyFunction); | 462 Handle<JSFunction> module_constructor = |
332 InstallFunc(isolate, wasm_object, "instantiateModule", InstantiateModule); | 463 InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); |
333 InstallFunc(isolate, wasm_object, "instantiateModuleFromAsm", | 464 Handle<JSFunction> instance_constructor = |
334 InstantiateModuleFromAsm); | 465 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); |
Mircea Trofin
2016/06/21 13:20:49
Don't we want to name this "Instantiate", rather t
rossberg
2016/06/21 13:35:16
No, it's a constructor, i.e., represents a class.
| |
335 | 466 context->set_wasm_module_constructor(*module_constructor); |
336 { | 467 context->set_wasm_instance_constructor(*instance_constructor); |
337 // Add the Wasm.experimentalVersion property. | |
338 Handle<String> name = v8_str(isolate, "experimentalVersion"); | |
339 PropertyAttributes attributes = | |
340 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | |
341 Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); | |
342 JSObject::AddProperty(wasm_object, name, value, attributes); | |
343 } | |
344 } | 468 } |
345 | 469 |
346 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { | 470 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { |
347 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | 471 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
348 // TODO(titzer): Move this to bootstrapper.cc?? | 472 // TODO(titzer): Move this to bootstrapper.cc?? |
349 // TODO(titzer): Also make one for strict mode functions? | 473 // TODO(titzer): Also make one for strict mode functions? |
350 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | 474 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
351 | 475 |
352 InstanceType instance_type = prev_map->instance_type(); | 476 InstanceType instance_type = prev_map->instance_type(); |
353 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); | 477 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
354 CHECK_EQ(0, internal_fields); | 478 CHECK_EQ(0, internal_fields); |
355 int pre_allocated = | 479 int pre_allocated = |
356 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); | 480 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); |
357 int instance_size; | 481 int instance_size; |
358 int in_object_properties; | 482 int in_object_properties; |
359 JSFunction::CalculateInstanceSizeHelper(instance_type, internal_fields + 1, | 483 JSFunction::CalculateInstanceSizeHelper(instance_type, internal_fields + 1, |
360 0, &instance_size, | 484 0, &instance_size, |
361 &in_object_properties); | 485 &in_object_properties); |
362 | 486 |
363 int unused_property_fields = in_object_properties - pre_allocated; | 487 int unused_property_fields = in_object_properties - pre_allocated; |
364 Handle<Map> map = Map::CopyInitialMap( | 488 Handle<Map> map = Map::CopyInitialMap( |
365 prev_map, instance_size, in_object_properties, unused_property_fields); | 489 prev_map, instance_size, in_object_properties, unused_property_fields); |
366 | 490 |
367 context->set_wasm_function_map(*map); | 491 context->set_wasm_function_map(*map); |
368 } | 492 } |
369 } | 493 } |
370 | 494 |
371 } // namespace internal | 495 } // namespace internal |
372 } // namespace v8 | 496 } // namespace v8 |
OLD | NEW |