Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'wasm_import_module' option to the @[Link] annotation #11935

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion spec/compiler/semantic/lib_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ describe "Semantic: lib" do
lib LibFoo
end
),
"unknown link argument: 'boo' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config' and 'framework')"
"unknown link argument: 'boo' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config', 'framework', and 'wasm_import_module')"
end

it "errors if lib already specified with positional argument" do
Expand Down
11 changes: 11 additions & 0 deletions src/compiler/crystal/codegen/fun.cr
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,17 @@ class Crystal::CodeGenVisitor
end
end

if @program.has_flag?("wasm32")
if target_def.is_a?(External) && (wasm_import_module = target_def.wasm_import_module)
context.fun.add_target_dependent_attribute("wasm-import-name", target_def.real_name)
context.fun.add_target_dependent_attribute("wasm-import-module", wasm_import_module)
end

if is_exported_fun
context.fun.add_target_dependent_attribute("wasm-export-name", mangled_name)
end
end

context.fun
end
end
Expand Down
11 changes: 8 additions & 3 deletions src/compiler/crystal/codegen/link.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ module Crystal
getter pkg_config : String?
getter ldflags : String?
getter framework : String?
getter wasm_import_module : String?

def initialize(@lib = nil, @pkg_config = @lib, @ldflags = nil, @static = false, @framework = nil)
def initialize(@lib = nil, @pkg_config = @lib, @ldflags = nil, @static = false, @framework = nil, @wasm_import_module = nil)
end

def static?
Expand All @@ -25,6 +26,7 @@ module Crystal
lib_static = false
lib_pkg_config = nil
lib_framework = nil
lib_wasm_import_module = nil
count = 0

args.each do |arg|
Expand Down Expand Up @@ -71,12 +73,15 @@ module Crystal
when "pkg_config"
named_arg.raise "'pkg_config' link argument must be a String" unless value.is_a?(StringLiteral)
lib_pkg_config = value.value
when "wasm_import_module"
named_arg.raise "'wasm_import_module' link argument must be a String" unless value.is_a?(StringLiteral)
lib_wasm_import_module = value.value
else
named_arg.raise "unknown link argument: '#{named_arg.name}' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config' and 'framework')"
named_arg.raise "unknown link argument: '#{named_arg.name}' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config', 'framework', and 'wasm_import_module')"
end
end

new(lib_name, lib_pkg_config, lib_ldflags, lib_static, lib_framework)
new(lib_name, lib_pkg_config, lib_ldflags, lib_static, lib_framework, lib_wasm_import_module)
end
end

Expand Down
1 change: 1 addition & 0 deletions src/compiler/crystal/semantic/ast.cr
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,7 @@ module Crystal
property real_name : String
property! fun_def : FunDef
property call_convention : LLVM::CallConvention?
property wasm_import_module : String?

property? dead = false
property? used = false
Expand Down
12 changes: 12 additions & 0 deletions src/compiler/crystal/semantic/top_level_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,8 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor

type.private = true if node.visibility.private?

wasm_import_module = nil

process_annotations(annotations) do |annotation_type, ann|
case annotation_type
when @program.link_annotation
Expand All @@ -496,6 +498,12 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
@program.report_warning(ann, "using non-named arguments for Link annotations is deprecated")
end

if wasm_import_module && link_annotation.wasm_import_module
ann.raise "multiple wasm import modules specified for lib #{node.name}"
end

wasm_import_module = link_annotation.wasm_import_module

type.add_link_annotation(link_annotation)
when @program.call_convention_annotation
type.call_convention = parse_call_convention(ann, type.call_convention)
Expand Down Expand Up @@ -903,6 +911,10 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
call_convention = scope.call_convention
end

if scope.is_a?(LibType)
external.wasm_import_module = scope.wasm_import_module
end

# We fill the arguments and return type in TypeDeclarationVisitor
external.doc = node.doc
external.call_convention = call_convention
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/crystal/types.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2600,6 +2600,10 @@ module Crystal
def type_desc
"lib"
end

def wasm_import_module
(@link_annotations.try &.find &.wasm_import_module).try &.wasm_import_module
end
end

# A `type` (typedef) type inside a `lib` declaration.
Expand Down