| 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.h" | 5 #include "src/api.h" |
| 6 #include "src/api-natives.h" | 6 #include "src/api-natives.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/factory.h" | 10 #include "src/factory.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 | 37 |
| 38 RawBuffer GetRawBufferArgument( | 38 RawBuffer GetRawBufferArgument( |
| 39 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { | 39 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 40 if (args.Length() < 1 || !args[0]->IsArrayBuffer()) { | 40 if (args.Length() < 1 || !args[0]->IsArrayBuffer()) { |
| 41 thrower.Error("Argument 0 must be an array buffer"); | 41 thrower.Error("Argument 0 must be an array buffer"); |
| 42 return {nullptr, nullptr}; | 42 return {nullptr, nullptr}; |
| 43 } | 43 } |
| 44 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(args[0]); | 44 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(args[0]); |
| 45 ArrayBuffer::Contents contents = | 45 ArrayBuffer::Contents contents = buffer->GetContents(); |
| 46 buffer->IsExternal() ? buffer->GetContents() : buffer->Externalize(); | |
| 47 | 46 |
| 48 // TODO(titzer): allow offsets into buffers, views, etc. | 47 // TODO(titzer): allow offsets into buffers, views, etc. |
| 49 | 48 |
| 50 const byte* start = reinterpret_cast<const byte*>(contents.Data()); | 49 const byte* start = reinterpret_cast<const byte*>(contents.Data()); |
| 51 const byte* end = start + contents.ByteLength(); | 50 const byte* end = start + contents.ByteLength(); |
| 52 | 51 |
| 53 if (start == nullptr) { | 52 if (start == nullptr) { |
| 54 thrower.Error("ArrayBuffer argument is empty"); | 53 thrower.Error("ArrayBuffer argument is empty"); |
| 55 } | 54 } |
| 56 return {start, end}; | 55 return {start, end}; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 75 | 74 |
| 76 if (result.val) delete result.val; | 75 if (result.val) delete result.val; |
| 77 } | 76 } |
| 78 | 77 |
| 79 | 78 |
| 80 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { | 79 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 81 HandleScope scope(args.GetIsolate()); | 80 HandleScope scope(args.GetIsolate()); |
| 82 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 81 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
| 83 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); | 82 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); |
| 84 | 83 |
| 85 // TODO(titzer): no need to externalize to get the bytes for verification. | |
| 86 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 84 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
| 87 if (thrower.error()) return; | 85 if (thrower.error()) return; |
| 88 | 86 |
| 89 internal::wasm::FunctionResult result; | 87 internal::wasm::FunctionResult result; |
| 90 { | 88 { |
| 91 // Verification of a single function shouldn't allocate. | 89 // Verification of a single function shouldn't allocate. |
| 92 i::DisallowHeapAllocation no_allocation; | 90 i::DisallowHeapAllocation no_allocation; |
| 93 i::Zone zone; | 91 i::Zone zone; |
| 94 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, | 92 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, |
| 95 buffer.start, buffer.end); | 93 buffer.start, buffer.end); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); | 236 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); |
| 239 | 237 |
| 240 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 238 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
| 241 if (buffer.start == nullptr) return; | 239 if (buffer.start == nullptr) return; |
| 242 | 240 |
| 243 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 241 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
| 244 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | 242 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |
| 245 Local<Object> obj = Local<Object>::Cast(args[2]); | 243 Local<Object> obj = Local<Object>::Cast(args[2]); |
| 246 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 244 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
| 247 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | 245 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |
| 248 i::Isolate* isolate = memory->GetIsolate(); | |
| 249 memory->set_is_external(true); | |
| 250 isolate->heap()->UnregisterArrayBuffer(*memory); | |
| 251 } | 246 } |
| 252 | 247 |
| 253 // Decode but avoid a redundant pass over function bodies for verification. | 248 // Decode but avoid a redundant pass over function bodies for verification. |
| 254 // Verification will happen during compilation. | 249 // Verification will happen during compilation. |
| 255 i::Zone zone; | 250 i::Zone zone; |
| 256 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( | 251 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( |
| 257 isolate, &zone, buffer.start, buffer.end, false, false); | 252 isolate, &zone, buffer.start, buffer.end, false, false); |
| 258 | 253 |
| 259 if (result.failed()) { | 254 if (result.failed()) { |
| 260 thrower.Failed("", result); | 255 thrower.Failed("", result); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 296 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
| 302 Handle<JSFunction> function = | 297 Handle<JSFunction> function = |
| 303 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 298 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
| 304 PropertyAttributes attributes = | 299 PropertyAttributes attributes = |
| 305 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 300 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 306 JSObject::AddProperty(object, name, function, attributes); | 301 JSObject::AddProperty(object, name, function, attributes); |
| 307 } | 302 } |
| 308 | 303 |
| 309 | 304 |
| 310 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 305 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
| 306 // Setup wasm function map. |
| 307 Handle<Map> wasm_function_map = isolate->factory()->NewMap( |
| 308 JS_FUNCTION_TYPE, JSFunction::kSize + kPointerSize); |
| 309 wasm_function_map->set_is_callable(); |
| 310 global->native_context()->set_wasm_function_map(*wasm_function_map); |
| 311 |
| 311 // Bind the WASM object. | 312 // Bind the WASM object. |
| 312 Factory* factory = isolate->factory(); | 313 Factory* factory = isolate->factory(); |
| 313 Handle<String> name = v8_str(isolate, "WASM"); | 314 Handle<String> name = v8_str(isolate, "WASM"); |
| 314 Handle<JSFunction> cons = factory->NewFunction(name); | 315 Handle<JSFunction> cons = factory->NewFunction(name); |
| 315 JSFunction::SetInstancePrototype( | 316 JSFunction::SetInstancePrototype( |
| 316 cons, Handle<Object>(global->native_context()->initial_object_prototype(), | 317 cons, Handle<Object>(global->native_context()->initial_object_prototype(), |
| 317 isolate)); | 318 isolate)); |
| 318 cons->shared()->set_instance_class_name(*name); | 319 cons->shared()->set_instance_class_name(*name); |
| 319 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); | 320 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); |
| 320 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | 321 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
| 321 JSObject::AddProperty(global, name, wasm_object, attributes); | 322 JSObject::AddProperty(global, name, wasm_object, attributes); |
| 322 | 323 |
| 323 // Install functions on the WASM object. | 324 // Install functions on the WASM object. |
| 324 InstallFunc(isolate, wasm_object, "instantiateModule", InstantiateModule); | 325 InstallFunc(isolate, wasm_object, "instantiateModule", InstantiateModule); |
| 325 InstallFunc(isolate, wasm_object, "verifyModule", VerifyModule); | 326 InstallFunc(isolate, wasm_object, "verifyModule", VerifyModule); |
| 326 InstallFunc(isolate, wasm_object, "verifyFunction", VerifyFunction); | 327 InstallFunc(isolate, wasm_object, "verifyFunction", VerifyFunction); |
| 327 InstallFunc(isolate, wasm_object, "compileRun", CompileRun); | 328 InstallFunc(isolate, wasm_object, "compileRun", CompileRun); |
| 328 InstallFunc(isolate, wasm_object, "asmCompileRun", AsmCompileRun); | 329 InstallFunc(isolate, wasm_object, "asmCompileRun", AsmCompileRun); |
| 329 InstallFunc(isolate, wasm_object, "instantiateModuleFromAsm", | 330 InstallFunc(isolate, wasm_object, "instantiateModuleFromAsm", |
| 330 InstantiateModuleFromAsm); | 331 InstantiateModuleFromAsm); |
| 331 } | 332 } |
| 332 } // namespace internal | 333 } // namespace internal |
| 333 } // namespace v8 | 334 } // namespace v8 |
| OLD | NEW |